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