commit a489f71ae2b7694fb1a73fe4ece68189eb4078a6 Author: Bradlee Speice Date: Fri Sep 21 22:34:42 2018 -0400 Add an initial pass on an allocation tracing tool diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6936990 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..890b0b6 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "qadapt" +version = "0.1.0" +authors = ["Bradlee Speice "] +description = "The Quick And Dirty Allocation Profiling Tool" + +[dependencies] +lazy_static = "1.1" + +[dependencies.libc] +default-features = false +features = [] +version = "0.2" diff --git a/src/const_init.rs b/src/const_init.rs new file mode 100644 index 0000000..a699911 --- /dev/null +++ b/src/const_init.rs @@ -0,0 +1,5 @@ +/// Anything that can be initialized with a `const` value. +pub(crate) trait ConstInit { + /// The `const` default initializer value for `Self`. + const INIT: Self; +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..ca4a54f --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,44 @@ +extern crate libc; + +use libc::c_void; +use libc::free; +use libc::malloc; +use std::alloc::Layout; +use std::alloc::GlobalAlloc; +use std::sync::atomic::AtomicBool; +use std::sync::atomic::Ordering; + +mod const_init; +use const_init::ConstInit; + +pub struct QADAPT { + pub has_allocated: AtomicBool +} + +impl ConstInit for QADAPT { + + const INIT: QADAPT = QADAPT { + has_allocated: AtomicBool::new(false) + }; +} + +unsafe impl GlobalAlloc for QADAPT { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + let block = malloc(layout.size()) as *mut u8; + self.has_allocated.store(true, Ordering::SeqCst); + + block + } + + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { + free(ptr as *mut c_void) + } +} + +impl QADAPT { + pub const INIT: Self = ::INIT; + + pub fn clear_allocations(&self) { + self.has_allocated.store(false, Ordering::Release) + } +} diff --git a/tests/basic.rs b/tests/basic.rs new file mode 100644 index 0000000..be6ec46 --- /dev/null +++ b/tests/basic.rs @@ -0,0 +1,44 @@ +extern crate qadapt; + +use qadapt::QADAPT; +use std::alloc::alloc; +use std::alloc::Layout; +use std::sync::atomic::Ordering; + +#[global_allocator] +static A: QADAPT = QADAPT::INIT; + +#[test] +fn alloc_nonnull() { + unsafe { + assert!(!alloc(Layout::new::()).is_null()) + } +} + +struct Empty; + +struct NonEmpty { + _x: i32, + _y: i32 +} + +#[test] +fn allocation_flag() { + A.clear_allocations(); + assert!(!A.has_allocated.load(Ordering::SeqCst)); + + let _x = 24; + assert!(!A.has_allocated.load(Ordering::SeqCst)); + + let _x = Empty {}; + assert!(!A.has_allocated.load(Ordering::SeqCst)); + + let _x = NonEmpty { + _x: 42, + _y: 84 + }; + assert!(!A.has_allocated.load(Ordering::SeqCst)); + + let _x = Box::new(42); + assert!(A.has_allocated.load(Ordering::SeqCst)); +} \ No newline at end of file