mirror of
				https://github.com/bspeice/qadapt
				synced 2025-10-31 09:30:37 -04:00 
			
		
		
		
	Add an initial pass on an allocation tracing tool
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| /target | ||||
| **/*.rs.bk | ||||
| Cargo.lock | ||||
							
								
								
									
										13
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| [package] | ||||
| name = "qadapt" | ||||
| version = "0.1.0" | ||||
| authors = ["Bradlee Speice <bradlee@speice.io>"] | ||||
| description = "The Quick And Dirty Allocation Profiling Tool" | ||||
|  | ||||
| [dependencies] | ||||
| lazy_static = "1.1" | ||||
|  | ||||
| [dependencies.libc] | ||||
| default-features = false | ||||
| features = [] | ||||
| version = "0.2" | ||||
							
								
								
									
										5
									
								
								src/const_init.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/const_init.rs
									
									
									
									
									
										Normal file
									
								
							| @ -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; | ||||
| } | ||||
							
								
								
									
										44
									
								
								src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/lib.rs
									
									
									
									
									
										Normal file
									
								
							| @ -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 = <Self as ConstInit>::INIT; | ||||
|  | ||||
|     pub fn clear_allocations(&self) { | ||||
|         self.has_allocated.store(false, Ordering::Release) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										44
									
								
								tests/basic.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								tests/basic.rs
									
									
									
									
									
										Normal file
									
								
							| @ -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::<u32>()).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)); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user