1
0
mirror of https://github.com/bspeice/qadapt synced 2024-11-21 21:38:10 -05:00

Get version 0.4 ready

This commit is contained in:
Bradlee Speice 2018-11-15 20:16:49 -05:00
parent 398b1395a0
commit 8b4ebe8c88
7 changed files with 53 additions and 26 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "qadapt" name = "qadapt"
version = "0.3.0" version = "0.4.0"
authors = ["Bradlee Speice <bradlee@speice.io>"] authors = ["Bradlee Speice <bradlee@speice.io>"]
description = "The Quick And Dirty Allocation Profiling Tool" description = "The Quick And Dirty Allocation Profiling Tool"
license = "Apache-2.0" license = "Apache-2.0"
@ -14,9 +14,12 @@ categories = [
] ]
repository = "https://github.com/bspeice/qadapt.git" repository = "https://github.com/bspeice/qadapt.git"
[badges]
maintenance = { status = "actively-maintained" }
[dependencies] [dependencies]
libc = "0.2" libc = "0.2"
spin = "0.4" spin = "0.4"
thread-id = "3.3" thread-id = "3.3"
qadapt-macro = { version = "0.3.0", path = "./qadapt-macro" } qadapt-macro = { version = "0.4.0", path = "./qadapt-macro" }

View File

@ -1,6 +1,9 @@
The Quick And Dirty Allocation Profiling Tool The Quick And Dirty Allocation Profiling Tool
============================================= =============================================
[![crates.io](https://img.shields.io/crates/v/qadapt.svg)](https://crates.io/crates/qadapt)
[![docs.rs](https://docs.rs/qadapt/badge.svg)](https://docs.rs/qadapt/)
This allocator is a helper for writing high-performance code that is allocation/drop free; This allocator is a helper for writing high-performance code that is allocation/drop free;
for functions annotated with `#[allocate_panic]`, QADAPT will detect when allocations/drops for functions annotated with `#[allocate_panic]`, QADAPT will detect when allocations/drops
happen during their execution (and execution of any functions they call) and throw a happen during their execution (and execution of any functions they call) and throw a

View File

@ -1,6 +1,6 @@
[package] [package]
name = "qadapt-macro" name = "qadapt-macro"
version = "0.3.0" version = "0.4.0"
authors = ["Bradlee Speice <bradlee@speice.io>"] authors = ["Bradlee Speice <bradlee@speice.io>"]
description = "The Quick And Dirty Allocation Profiling Tool - Support Macros" description = "The Quick And Dirty Allocation Profiling Tool - Support Macros"
license = "Apache-2.0" license = "Apache-2.0"
@ -14,5 +14,8 @@ categories = [
] ]
repository = "https://github.com/bspeice/qadapt.git" repository = "https://github.com/bspeice/qadapt.git"
[badges]
maintenance = { static = "actively-maintained" }
[lib] [lib]
proc-macro = true proc-macro = true

View File

@ -1,5 +1,8 @@
# QADAPT - Helper macros # QADAPT - Helper macros
[![crates.io](https://img.shields.io/crates/v/qadapt-macro.svg)](https://crates.io/crates/qadapt-macro)
[![docs.rs](https://docs.rs/dtparse/qadapt-macro.svg)](https://docs.rs/qadapt-macro/)
Helper macros to use with the QADAPT allocator system Helper macros to use with the QADAPT allocator system
This crate is intended for managing the QADAPT allocator, This crate is intended for managing the QADAPT allocator,

View File

@ -106,6 +106,18 @@ fn protected_body(fn_body: Group) -> TokenTree {
)) ))
} }
fn contains_return(ts: TokenStream) -> bool {
for tt in ts.into_iter() {
match tt {
TokenTree::Group(ref g) => if contains_return(g.stream()) { return true },
TokenTree::Ident(ref i) if i.to_string() == "return" => return true,
_ => (),
}
}
false
}
/// Set up the QADAPT allocator to trigger a panic if any allocations happen during /// Set up the QADAPT allocator to trigger a panic if any allocations happen during
/// calls to this function. /// calls to this function.
/// ///
@ -114,6 +126,16 @@ fn protected_body(fn_body: Group) -> TokenTree {
/// separate thread, QADAPT will not trigger a panic. /// separate thread, QADAPT will not trigger a panic.
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn allocate_panic(_attr: TokenStream, item: TokenStream) -> TokenStream { pub fn allocate_panic(_attr: TokenStream, item: TokenStream) -> TokenStream {
if contains_return(item.clone()) {
let mut iter = item.clone().into_iter();
iter.next();
let fn_name = iter.next().unwrap();
eprintln!("QADAPT does not currently support `return` \
statements in functions. Function named `{}` \
DOES NOT have allocation guards in place.", fn_name);
return item;
}
let mut protected_fn: Vec<TokenTree> = Vec::new(); let mut protected_fn: Vec<TokenTree> = Vec::new();
let mut item_iter = item.into_iter(); let mut item_iter = item.into_iter();

View File

@ -131,7 +131,7 @@ unsafe impl GlobalAlloc for QADAPT {
} }
} }
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
if alloc_immediate() { if alloc_immediate() {
return free(ptr as *mut c_void); return free(ptr as *mut c_void);
} }
@ -148,13 +148,11 @@ unsafe impl GlobalAlloc for QADAPT {
// Tripped a bad dealloc, but make sure further memory access during unwind // Tripped a bad dealloc, but make sure further memory access during unwind
// doesn't have issues // doesn't have issues
PROTECTION_LEVEL.with(|v| *v.write() = 0); PROTECTION_LEVEL.with(|v| *v.write() = 0);
/*
panic!( panic!(
"Unexpected deallocation for size {}, protection level: {}", "Unexpected deallocation for size {}, protection level: {}",
layout.size(), layout.size(),
v v
) )
*/
} }
_ => (), _ => (),
} }

View File

@ -1,4 +1,3 @@
#![feature(asm)]
extern crate qadapt; extern crate qadapt;
use qadapt::enter_protected; use qadapt::enter_protected;
@ -9,16 +8,11 @@ use qadapt::QADAPT;
#[global_allocator] #[global_allocator]
static Q: QADAPT = QADAPT; static Q: QADAPT = QADAPT;
pub fn black_box<T>(dummy: T) -> T {
// Taken from test lib, need to mark the arg as non-introspectable
unsafe { asm!("" : : "r"(&dummy)) }
dummy
}
#[test] #[test]
fn test_copy() { fn test_copy() {
enter_protected(); enter_protected();
black_box(0u8); let v = 0u8;
let v2 = v;
exit_protected(); exit_protected();
} }
@ -41,16 +35,8 @@ fn unit_result(b: bool) -> Result<(), ()> {
#[test] #[test]
fn test_unit_result() { fn test_unit_result() {
enter_protected(); enter_protected();
#[allow(unused)] unit_result(true).unwrap();
{ unit_result(false).unwrap_err();
black_box(unit_result(true));
}
black_box(unit_result(true)).unwrap();
#[allow(unused)]
{
black_box(unit_result(false));
}
black_box(unit_result(false)).unwrap_err();
exit_protected(); exit_protected();
} }
@ -80,14 +66,14 @@ fn test_vec_push_capacity() {
#[test] #[test]
fn test_vec_with_zero() { fn test_vec_with_zero() {
enter_protected(); enter_protected();
let _v: Vec<u8> = black_box(Vec::with_capacity(0)); let _v: Vec<u8> = Vec::with_capacity(0);
exit_protected(); exit_protected();
} }
#[test] #[test]
fn test_vec_new() { fn test_vec_new() {
enter_protected(); enter_protected();
let _v: Vec<u8> = black_box(Vec::new()); let _v: Vec<u8> = Vec::new();
exit_protected(); exit_protected();
} }
@ -110,3 +96,12 @@ fn exit_too_often() {
exit_protected(); exit_protected();
exit_protected(); exit_protected();
} }
#[test]
#[should_panic]
fn intentional_drop() {
let v: Vec<()> = Vec::new();
let v = Box::new(v);
enter_protected();
drop(v);
}