1 //! Test using `Bytes` with an allocator that hands out "odd" pointers for
2 //! vectors (pointers where the LSB is set).
3
4 #![cfg(not(miri))] // Miri does not support custom allocators (also, Miri is "odd" by default with 50% chance)
5
6 use std::alloc::{GlobalAlloc, Layout, System};
7 use std::ptr;
8
9 use bytes::Bytes;
10
11 #[global_allocator]
12 static ODD: Odd = Odd;
13
14 struct Odd;
15
16 unsafe impl GlobalAlloc for Odd {
alloc(&self, layout: Layout) -> *mut u817 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
18 if layout.align() == 1 && layout.size() > 0 {
19 // Allocate slightly bigger so that we can offset the pointer by 1
20 let size = layout.size() + 1;
21 let new_layout = match Layout::from_size_align(size, 1) {
22 Ok(layout) => layout,
23 Err(_err) => return ptr::null_mut(),
24 };
25 let ptr = System.alloc(new_layout);
26 if !ptr.is_null() {
27 let ptr = ptr.offset(1);
28 ptr
29 } else {
30 ptr
31 }
32 } else {
33 System.alloc(layout)
34 }
35 }
36
dealloc(&self, ptr: *mut u8, layout: Layout)37 unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
38 if layout.align() == 1 && layout.size() > 0 {
39 let size = layout.size() + 1;
40 let new_layout = match Layout::from_size_align(size, 1) {
41 Ok(layout) => layout,
42 Err(_err) => std::process::abort(),
43 };
44 System.dealloc(ptr.offset(-1), new_layout);
45 } else {
46 System.dealloc(ptr, layout);
47 }
48 }
49 }
50
51 #[test]
sanity_check_odd_allocator()52 fn sanity_check_odd_allocator() {
53 let vec = vec![33u8; 1024];
54 let p = vec.as_ptr() as usize;
55 assert!(p & 0x1 == 0x1, "{:#b}", p);
56 }
57
58 #[test]
test_bytes_from_vec_drop()59 fn test_bytes_from_vec_drop() {
60 let vec = vec![33u8; 1024];
61 let _b = Bytes::from(vec);
62 }
63
64 #[test]
test_bytes_clone_drop()65 fn test_bytes_clone_drop() {
66 let vec = vec![33u8; 1024];
67 let b1 = Bytes::from(vec);
68 let _b2 = b1.clone();
69 }
70