1
use std::alloc::GlobalAlloc;
2
use std::alloc::Layout;
3
use std::alloc::System;
4
use std::sync::atomic::AtomicUsize;
5
use std::sync::atomic::Ordering::Relaxed;
6

            
7
/// An allocator that can be used globally to count metrics
8
/// on the allocations performed.
9
pub struct AllocCounter;
10

            
11
static NUMBER_OF_ALLOCATIONS: AtomicUsize = AtomicUsize::new(0);
12

            
13
impl AllocCounter {
14
    /// Returns the total number of allocations since program start.
15
    #[allow(dead_code)]
16
    pub fn number_of_allocations(&self) -> usize {
17
        NUMBER_OF_ALLOCATIONS.load(Relaxed)
18
    }
19
}
20

            
21
unsafe impl GlobalAlloc for AllocCounter {
22
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
23
        let ret = System.alloc(layout);
24
        if !ret.is_null() {
25
            NUMBER_OF_ALLOCATIONS.fetch_add(1, Relaxed);
26
        }
27
        ret
28
    }
29

            
30
    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
31
        System.dealloc(ptr, layout);
32
    }
33
}