• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::alloc::{GlobalAlloc, Layout, System};
2 use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
3 
4 static ALLOCATED: AtomicUsize = AtomicUsize::new(0);
5 
6 struct MyAllocator;
7 
8 unsafe impl GlobalAlloc for MyAllocator {
alloc(&self, layout: Layout) -> *mut u89     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
10         let ret = System.alloc(layout);
11         if !ret.is_null() {
12             ALLOCATED.fetch_add(layout.size(), SeqCst);
13         }
14         ret
15     }
16 
dealloc(&self, ptr: *mut u8, layout: Layout)17     unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
18         System.dealloc(ptr, layout);
19         ALLOCATED.fetch_sub(layout.size(), SeqCst);
20     }
21 }
22 
23 #[global_allocator]
24 static GLOBAL: MyAllocator = MyAllocator;
25 
main()26 fn main() {
27     println!("allocated bytes before main: {}", ALLOCATED.load(SeqCst));
28 }
29 
30 #[cfg(test)]
31 mod tests {
32     use super::*;
33 
34     #[test]
test_global_alloc_was_used()35     fn test_global_alloc_was_used() {
36         // Allocated bytes before main
37         let bytes_start = ALLOCATED.load(SeqCst);
38 
39         let _x = Box::new(5); // 4 bytes
40         let _y = Box::new(true); // 1 byte
41 
42         let bytes_end = ALLOCATED.load(SeqCst);
43 
44         assert_eq!(bytes_end - bytes_start, 5);
45     }
46 }
47