allocator_tracer/
tracer.rs

1use std::{alloc::{GlobalAlloc, Layout}, sync::LazyLock, time::Instant};
2
3use crate::{ALLOCATOR_EVENTS, AllocationEvent};
4
5static FIRST_INSTANT: LazyLock<Instant> = LazyLock::new(Instant::now);
6
7pub struct Tracer<T>(pub T);
8
9
10
11unsafe impl<T: GlobalAlloc> GlobalAlloc for Tracer<T> {
12    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
13        let mut events = ALLOCATOR_EVENTS.lock();
14        let ptr = unsafe { self.0.alloc(layout) };
15        events.push(AllocationEvent::Alloc { size: layout.size(), align: layout.align(), time: FIRST_INSTANT.elapsed(), ptr: ptr as usize });
16        ptr
17    }
18
19    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
20        let mut events = ALLOCATOR_EVENTS.lock();
21        events.push(AllocationEvent::Dealloc { size: layout.size(), align: layout.align(), time: FIRST_INSTANT.elapsed(), ptr: ptr as usize }); 
22        unsafe { self.0.dealloc(ptr, layout) };
23    }
24
25    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
26        let mut events = ALLOCATOR_EVENTS.lock();
27        let new_ptr = unsafe { self.0.realloc(ptr, layout, new_size) };
28        events.push(AllocationEvent::Realloc { size: layout.size(), align: layout.align(), time: FIRST_INSTANT.elapsed(), ptr: ptr as usize, new_size, new_ptr: new_ptr as usize });
29        new_ptr
30    }
31}