1use std::mem;
2
3pub const EMPTY: *mut () = 0x1 as *mut ();
8
9#[inline]
17pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
18 assert!(size & align == 0, "invalid allocate arguments; size={}; align={}", size, align);
19
20 match align {
21 1 => do_allocate::<u8>(size),
22 2 => do_allocate::<u16>(size >> 1),
23 4 => do_allocate::<u32>(size >> 2),
24 8 => do_allocate::<u64>(size >> 3),
25 _ => panic!("unsupported alignment {}", align),
26 }
27}
28
29unsafe fn do_allocate<T>(capacity: usize) -> *mut u8 {
30 let vec = Vec::<T>::with_capacity(capacity);
31 let ptr = vec.as_ptr();
32
33 mem::forget(vec);
34
35 ptr as *mut u8
36}
37
38#[inline]
46pub unsafe fn deallocate(ptr: *mut u8, old_size: usize, align: usize) {
47 match align {
48 1 => do_deallocate::<u8>(ptr, old_size),
49 2 => do_deallocate::<u16>(ptr, old_size >> 1),
50 4 => do_deallocate::<u32>(ptr, old_size >> 2),
51 8 => do_deallocate::<u64>(ptr, old_size >> 3),
52 _ => panic!("unsupported alignment {}", align),
53 }
54}
55
56unsafe fn do_deallocate<T>(ptr: *mut u8, capacity: usize) {
57 let _ = Vec::from_raw_parts(ptr as *mut T, 0, capacity);
58}
59
60#[cfg(test)]
61mod test {
62 use std::mem;
63
64 #[test]
65 fn test_align() {
66 assert_eq!(1, mem::align_of::<u8>());
67 assert_eq!(2, mem::align_of::<u16>());
68 assert_eq!(4, mem::align_of::<u32>());
69 assert_eq!(8, mem::align_of::<u64>());
70 }
71
72 #[test]
73 fn test_allocate_deallocate() {
74 unsafe {
75 ::deallocate(::allocate(2048, 4), 2048, 4);
76 }
77 }
78
79 #[test]
80 fn test_empty_constant() {
81 let mut v = Vec::<()>::with_capacity(0);
82 assert_eq!(::EMPTY, v.as_mut_ptr());
83 }
84}