From 4d7f9b2696943e82636cb888c0f4ed647953c8b7 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 22:00:30 -0500 Subject: [PATCH 01/15] Prepare for edition 2018 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index cab42cb..b401e72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ maintenance = { status = "actively-developed" } [dependencies] libc = "0.2" log = "0.4" -spin = "0.4" +spin = { git = "https://github.com/bspeice/spin-rs.git" } thread-id = "3.3" qadapt-macro = { version = "0.7.1", path = "./qadapt-macro" } From 5232c556ff71031320dd38bbadddcd76dd557f4b Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 22:11:03 -0500 Subject: [PATCH 02/15] Actually upgrade the edition --- Cargo.toml | 3 ++- qadapt-macro/Cargo.toml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b401e72..3f81b2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ categories = [ "memory-management" ] repository = "https://github.com/bspeice/qadapt.git" +edition = "2018" [badges] maintenance = { status = "actively-developed" } @@ -26,4 +27,4 @@ thread-id = "3.3" qadapt-macro = { version = "0.7.1", path = "./qadapt-macro" } [dev-dependencies] -env_logger = "0.6" \ No newline at end of file +env_logger = "0.6" diff --git a/qadapt-macro/Cargo.toml b/qadapt-macro/Cargo.toml index 94f6842..580947f 100644 --- a/qadapt-macro/Cargo.toml +++ b/qadapt-macro/Cargo.toml @@ -13,6 +13,7 @@ categories = [ "memory-management" ] repository = "https://github.com/bspeice/qadapt.git" +edition = "2018" [badges] maintenance = { status = "actively-developed" } From de2b6700ae01c82ca9902565d245358665b55260 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 22:12:21 -0500 Subject: [PATCH 03/15] First of edition fixing --- examples/release_mode.rs | 2 +- examples/setup_warning.rs | 4 ++-- src/lib.rs | 8 ++++---- tests/allocations.rs | 2 +- tests/macros.rs | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/release_mode.rs b/examples/release_mode.rs index a184e07..d48228a 100644 --- a/examples/release_mode.rs +++ b/examples/release_mode.rs @@ -1,4 +1,4 @@ -extern crate qadapt; + use qadapt::allocate_panic; use qadapt::QADAPT; diff --git a/examples/setup_warning.rs b/examples/setup_warning.rs index fdc8e61..f7e85ba 100644 --- a/examples/setup_warning.rs +++ b/examples/setup_warning.rs @@ -1,5 +1,5 @@ -extern crate env_logger; -extern crate qadapt; +use env_logger; + use qadapt::allocate_panic; diff --git a/src/lib.rs b/src/lib.rs index b11062e..a835e6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,14 +11,14 @@ //! Please also take a look at [qadapt-macro](https://github.com/bspeice/qadapt/tree/master/qadapt-macro) //! for some helper macros to make working with QADAPT a bit easier. #![deny(missing_docs)] -extern crate libc; + #[macro_use] extern crate log; -extern crate qadapt_macro; -extern crate spin; + + // thread_id is necessary because `std::thread::current()` panics if we have not yet // allocated a `thread_local!{}` it depends on. -extern crate thread_id; +use thread_id; // Re-export the proc macros to use by other code pub use qadapt_macro::*; diff --git a/tests/allocations.rs b/tests/allocations.rs index 474be54..3e6fb67 100644 --- a/tests/allocations.rs +++ b/tests/allocations.rs @@ -1,4 +1,4 @@ -extern crate qadapt; + use qadapt::enter_protected; use qadapt::exit_protected; diff --git a/tests/macros.rs b/tests/macros.rs index 455a204..8adaaaf 100644 --- a/tests/macros.rs +++ b/tests/macros.rs @@ -1,4 +1,4 @@ -extern crate qadapt; + use std::io; use qadapt::allocate_panic; From f4f33dabb72f8cc6ee6e3b8ad330103578103788 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 22:12:45 -0500 Subject: [PATCH 04/15] More edition fixing --- qadapt-macro/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qadapt-macro/src/lib.rs b/qadapt-macro/src/lib.rs index 70c78a1..1d53632 100644 --- a/qadapt-macro/src/lib.rs +++ b/qadapt-macro/src/lib.rs @@ -111,7 +111,7 @@ fn escape_return(ts: TokenStream) -> TokenStream { let mut tt_iter = ts.into_iter(); while let Some(tt) = tt_iter.next() { - let mut tokens = match tt { + let tokens = match tt { TokenTree::Group(ref g) if g.delimiter() == Delimiter::Brace && !in_closure => { vec![group!(Delimiter::Brace, escape_return(g.stream()))] } From a1ee8934b40e54de28a78a5d779f1748c088b408 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 22:14:43 -0500 Subject: [PATCH 05/15] Fix up the clippy warnings --- examples/release_mode.rs | 2 -- examples/setup_warning.rs | 1 - src/lib.rs | 9 +++------ tests/allocations.rs | 2 -- tests/macros.rs | 1 - 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/examples/release_mode.rs b/examples/release_mode.rs index d48228a..b2a8156 100644 --- a/examples/release_mode.rs +++ b/examples/release_mode.rs @@ -1,5 +1,3 @@ - - use qadapt::allocate_panic; use qadapt::QADAPT; diff --git a/examples/setup_warning.rs b/examples/setup_warning.rs index f7e85ba..28bcb0a 100644 --- a/examples/setup_warning.rs +++ b/examples/setup_warning.rs @@ -1,6 +1,5 @@ use env_logger; - use qadapt::allocate_panic; // Note that we're missing the `#[global_allocator]` attribute diff --git a/src/lib.rs b/src/lib.rs index a835e6e..fb69128 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,10 +12,7 @@ //! for some helper macros to make working with QADAPT a bit easier. #![deny(missing_docs)] -#[macro_use] -extern crate log; - - +use log::warn; // thread_id is necessary because `std::thread::current()` panics if we have not yet // allocated a `thread_local!{}` it depends on. use thread_id; @@ -47,7 +44,7 @@ pub fn enter_protected() { return; } - if *IS_ACTIVE.read() == false { + if !*IS_ACTIVE.read() { *IS_ACTIVE.write() = true; warn!("QADAPT not initialized when using allocation guards; please verify `#[global_allocator]` is set!"); } @@ -123,7 +120,7 @@ fn alloc_immediate() -> bool { unsafe impl GlobalAlloc for QADAPT { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - if *IS_ACTIVE.read() == false { + if !*IS_ACTIVE.read() { *IS_ACTIVE.write() = true; } diff --git a/tests/allocations.rs b/tests/allocations.rs index 3e6fb67..d279c6a 100644 --- a/tests/allocations.rs +++ b/tests/allocations.rs @@ -1,5 +1,3 @@ - - use qadapt::enter_protected; use qadapt::exit_protected; use qadapt::protection_level; diff --git a/tests/macros.rs b/tests/macros.rs index 8adaaaf..57f0ed6 100644 --- a/tests/macros.rs +++ b/tests/macros.rs @@ -1,4 +1,3 @@ - use std::io; use qadapt::allocate_panic; From 65673e1af2b34bec6eebb492372b8a8178c10f82 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:02:44 -0500 Subject: [PATCH 06/15] Renaming and a new macro --- README.md | 56 ++++++++++++++++--- examples/release_mode.rs | 4 +- examples/setup_warning.rs | 20 ------- qadapt-macro/src/lib.rs | 2 +- src/lib.rs | 90 +++++++++++++++++++++++------- tests/assert_macro.rs | 26 +++++++++ tests/{macros.rs => proc_macro.rs} | 22 ++++---- tests/unused_panic.rs | 7 +++ 8 files changed, 164 insertions(+), 63 deletions(-) delete mode 100644 examples/setup_warning.rs create mode 100644 tests/assert_macro.rs rename tests/{macros.rs => proc_macro.rs} (93%) create mode 100644 tests/unused_panic.rs diff --git a/README.md b/README.md index 625faf2..30d8f73 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,53 @@ --- -# The Quick And Dirty Allocation Profiling Tool +# QADAPT - `debug_assert!` for your memory -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 -happen during their execution (and execution of any functions they call) and throw a -thread panic if this occurs. QADAPT-related code is *stripped out during release builds*, -so no worries about random allocations crashing in production. +This allocator is a helper for writing high-performance code that is memory-sensitive; +a thread panic will be triggered if a function annotated with `#[no_alloc]`, +or code inside an `assert_no_alloc!` macro interacts with the allocator in any way. +Wanton allocations and unforeseen drops no more - this library lets you focus on +writing code without worrying if Rust properly managed to inline the variable into the stack. -Currently this crate is Nightly-only, but will work once `const fn` is in Stable. +Now, an allocator blowing up in production is a scary thought; that's why QADAPT +is designed to strip its own code out whenever you're running with a release build. +Just like the [`debug_assert!` macro](https://doc.rust-lang.org/std/macro.debug_assert.html) +in Rust's standard library, it's safe to use without worrying about a unforeseen +circumstance causing your application to crash. -Please also take a look at [qadapt-macro](https://github.com/bspeice/qadapt/tree/master/qadapt-macro) -for some helper macros to make working with QADAPT a bit easier. +# Usage + +Actually making use of QADAPT is straight-forward. To set up the allocator, +place the following snippet in either your program binaries (main.rs) or tests: + +```rust,ignore +use qadapt::QADAPT; + +#[global_allocator] +static Q: QADAPT = QADAPT; +``` + +After that, there are two ways of telling QADAPT that it should trigger a panic: + +1. Annotate functions with the `#[no_alloc]` proc macro: +```rust,no_run +use qadapt::no_alloc; + +#[no_alloc] +fn do_math() -> u8 { +2 + 2 +} +``` + +2. Evaluate expressions with the `assert_no_alloc!` macro +```rust,no_run +use qadapt::assert_no_alloc; + +fn do_work() { +// This code is allowed to trigger an allocation +let b = Box::new(8); + +// This code would panic if an allocation occurred inside it +let x = assert_no_alloc!(*b + 2); +assert_eq!(x, 10); +} diff --git a/examples/release_mode.rs b/examples/release_mode.rs index b2a8156..027f6ac 100644 --- a/examples/release_mode.rs +++ b/examples/release_mode.rs @@ -1,10 +1,10 @@ -use qadapt::allocate_panic; +use qadapt::no_alloc; use qadapt::QADAPT; #[global_allocator] static Q: QADAPT = QADAPT; -#[allocate_panic] +#[no_alloc] fn does_allocate() -> Box { Box::new(0) } diff --git a/examples/setup_warning.rs b/examples/setup_warning.rs deleted file mode 100644 index 28bcb0a..0000000 --- a/examples/setup_warning.rs +++ /dev/null @@ -1,20 +0,0 @@ -use env_logger; - -use qadapt::allocate_panic; - -// Note that we're missing the `#[global_allocator]` attribute - -#[allocate_panic] -fn does_allocate() -> Box { - Box::new(0) -} - -fn main() { - // This code will warn that QADAPT isn't being used, but won't trigger a panic. - // Run with `RUST_LOG=warn cargo run --example setup_warning` - env_logger::init(); - does_allocate(); - - // The warning will only trigger once though - does_allocate(); -} diff --git a/qadapt-macro/src/lib.rs b/qadapt-macro/src/lib.rs index 1d53632..4f14c75 100644 --- a/qadapt-macro/src/lib.rs +++ b/qadapt-macro/src/lib.rs @@ -155,7 +155,7 @@ fn escape_return(ts: TokenStream) -> TokenStream { /// separate thread, or defers allocations via closure/Future, those results /// will not trigger an error. #[proc_macro_attribute] -pub fn allocate_panic(_attr: TokenStream, item: TokenStream) -> TokenStream { +pub fn no_alloc(_attr: TokenStream, item: TokenStream) -> TokenStream { let mut protected_fn: Vec = Vec::new(); let mut item_iter = item.into_iter(); diff --git a/src/lib.rs b/src/lib.rs index fb69128..82e6377 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,15 +1,53 @@ -//! # The Quick And Dirty Allocation Profiling Tool +//! # QADAPT - `debug_assert!` for your memory //! -//! 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 -//! happen during their execution (and execution of any functions they call) and throw a -//! thread panic if this occurs. QADAPT-related code is *stripped out during release builds*, -//! so no worries about random allocations crashing in production. -//! -//! Currently this crate is Nightly-only, but will work once `const fn` is in Stable. -//! -//! Please also take a look at [qadapt-macro](https://github.com/bspeice/qadapt/tree/master/qadapt-macro) -//! for some helper macros to make working with QADAPT a bit easier. +//! This allocator is a helper for writing high-performance code that is memory-sensitive; +//! a thread panic will be triggered if a function annotated with `#[no_alloc]`, +//! or code inside an `assert_no_alloc!` macro interacts with the allocator in any way. +//! Wanton allocations and unforeseen drops no more - this library lets you focus on +//! writing code without worrying if Rust properly managed to inline the variable into the stack. +//! +//! Now, an allocator blowing up in production is a scary thought; that's why QADAPT +//! is designed to strip its own code out whenever you're running with a release build. +//! Just like the [`debug_assert!` macro](https://doc.rust-lang.org/std/macro.debug_assert.html) +//! in Rust's standard library, it's safe to use without worrying about a unforeseen +//! circumstance causing your application to crash. +//! +//! # Usage +//! +//! Actually making use of QADAPT is straight-forward. To set up the allocator, +//! place the following snippet in either your program binaries (main.rs) or tests: +//! +//! ```rust,ignore +//! use qadapt::QADAPT; +//! +//! #[global_allocator] +//! static Q: QADAPT = QADAPT; +//! ``` +//! +//! After that, there are two ways of telling QADAPT that it should trigger a panic: +//! +//! 1. Annotate functions with the `#[no_alloc]` proc macro: +//! ```rust,no_run +//! use qadapt::no_alloc; +//! +//! #[no_alloc] +//! fn do_math() -> u8 { +//! 2 + 2 +//! } +//! ``` +//! +//! 2. Evaluate expressions with the `assert_no_alloc!` macro +//! ```rust,no_run +//! use qadapt::assert_no_alloc; +//! +//! fn do_work() { +//! // This code is allowed to trigger an allocation +//! let b = Box::new(8); +//! +//! // This code would panic if an allocation occurred inside it +//! let x = assert_no_alloc!(*b + 2); +//! assert_eq!(x, 10); +//! } #![deny(missing_docs)] use log::warn; @@ -45,8 +83,7 @@ pub fn enter_protected() { } if !*IS_ACTIVE.read() { - *IS_ACTIVE.write() = true; - warn!("QADAPT not initialized when using allocation guards; please verify `#[global_allocator]` is set!"); + panic!("QADAPT not initialized when using allocation guards; please verify `#[global_allocator]` is set!"); } PROTECTION_LEVEL @@ -80,17 +117,30 @@ pub fn exit_protected() { } } +/// Get the result of an expression, guaranteeing that no allocations occur +/// during its evaluation. +/// +/// **Warning**: Unexpected behavior may occur when using the `return` keyword. +/// Because the macro cleanup logic will not be run, QADAPT may trigger a panic +/// in code that was not specifically intended to be allocation-free. +#[macro_export] +macro_rules! assert_no_alloc { + ($e:expr) => {{ + ::qadapt::enter_protected(); + let e = { $e }; + ::qadapt::exit_protected(); + e + }}; +} + static IS_ACTIVE: RwLock = RwLock::new(false); static INTERNAL_ALLOCATION: RwLock = RwLock::new(usize::max_value()); /// Get the current "protection level" in QADAPT: calls to enter_protected() - exit_protected() pub fn protection_level() -> usize { - #[cfg(debug_assertions)] - { + if cfg!(debug_assertions) { PROTECTION_LEVEL.try_with(|v| *v.read()).unwrap_or(0) - } - #[cfg(not(debug_assertions))] - { + } else { 0 } } @@ -131,7 +181,7 @@ unsafe impl GlobalAlloc for QADAPT { } // Because accessing PROTECTION_LEVEL has the potential to trigger an allocation, - // we need to spin until we can claim the INTERNAL_ALLOCATION lock for our thread. + // we need to acquire the INTERNAL_ALLOCATION lock for our thread. claim_internal_alloc(); let protection_level: Result = PROTECTION_LEVEL.try_with(|v| *v.read()).or(Ok(0)); @@ -167,7 +217,7 @@ unsafe impl GlobalAlloc for QADAPT { free(ptr as *mut c_void); match protection_level { Ok(v) if v > 0 => { - // Tripped a bad dealloc, but make sure further memory access during unwind + // Tripped a bad drop, but make sure further memory access during unwind // doesn't have issues PROTECTION_LEVEL.with(|v| *v.write() = 0); panic!( diff --git a/tests/assert_macro.rs b/tests/assert_macro.rs new file mode 100644 index 0000000..78b7e9f --- /dev/null +++ b/tests/assert_macro.rs @@ -0,0 +1,26 @@ +use qadapt::assert_no_alloc; +use qadapt::QADAPT; + +#[global_allocator] +static Q: QADAPT = QADAPT; + +#[test] +fn math() { + let x = assert_no_alloc!(2 + 2); + assert_eq!(x, 4); +} + +fn early_return() -> usize { + assert_no_alloc!(return 8) +} + +fn into_box() -> Box { + Box::new(early_return()) +} + +#[test] +#[should_panic] +fn early_return_boxing() { + into_box(); +} + diff --git a/tests/macros.rs b/tests/proc_macro.rs similarity index 93% rename from tests/macros.rs rename to tests/proc_macro.rs index 57f0ed6..7e3fddd 100644 --- a/tests/macros.rs +++ b/tests/proc_macro.rs @@ -1,12 +1,12 @@ use std::io; -use qadapt::allocate_panic; +use qadapt::no_alloc; use qadapt::QADAPT; #[global_allocator] static Q: QADAPT = QADAPT; -#[allocate_panic] +#[no_alloc] fn no_allocate() { let _v: Vec<()> = Vec::with_capacity(0); } @@ -16,7 +16,7 @@ fn macro_no_allocate() { no_allocate(); } -#[allocate_panic] +#[no_alloc] fn allocates() { assert_eq!(::qadapt::protection_level(), 1); // Without boxing, release profile can actually optimize out the allocation @@ -30,7 +30,7 @@ fn macro_allocates() { allocates(); } -#[allocate_panic] +#[no_alloc] fn no_allocate_ret() -> bool { return true; } @@ -40,7 +40,7 @@ fn macro_return() { assert!(no_allocate_ret()); } -#[allocate_panic] +#[no_alloc] fn no_allocate_implicit_ret() -> bool { true } @@ -50,7 +50,7 @@ fn macro_implicit_return() { assert!(no_allocate_implicit_ret()); } -#[allocate_panic] +#[no_alloc] fn no_allocate_arg(b: bool) -> bool { b } @@ -61,7 +61,7 @@ fn macro_allocate_arg() { no_allocate_arg(false); } -#[allocate_panic] +#[no_alloc] fn no_allocate_args(_b: bool, _u: usize, i: i64) -> i64 { i } @@ -72,7 +72,7 @@ fn macro_allocate_args() { no_allocate_args(false, 4, -90); } -#[allocate_panic] +#[no_alloc] fn return_result(r: Result) -> Result, ()> { Ok(r) } @@ -82,7 +82,7 @@ fn macro_return_result() { return_result(Ok(16)).unwrap().unwrap(); } -#[allocate_panic] +#[no_alloc] fn branching_return(a: bool, b: bool, c: bool) -> u8 { if a { if b { @@ -131,7 +131,7 @@ fn run_closure(x: impl Fn(bool, bool) -> bool) -> bool { x(true, false) } -#[allocate_panic] +#[no_alloc] fn example_closure() { let c = run_closure(|a: bool, b| return a && b); assert!(!c); @@ -145,7 +145,7 @@ fn macro_closure() { } #[test] -#[allocate_panic] +#[no_alloc] fn macro_release_safe() { #[cfg(debug_assertions)] { diff --git a/tests/unused_panic.rs b/tests/unused_panic.rs new file mode 100644 index 0000000..e378e0a --- /dev/null +++ b/tests/unused_panic.rs @@ -0,0 +1,7 @@ +use qadapt::enter_protected; + +#[test] +#[should_panic] +fn guard_without_initialization() { + enter_protected(); +} \ No newline at end of file From b565c29cfc41742bb9bd232e37f8f8dacd28ed33 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:05:14 -0500 Subject: [PATCH 07/15] Minor wording tweak --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 82e6377..79d5cd5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -117,7 +117,7 @@ pub fn exit_protected() { } } -/// Get the result of an expression, guaranteeing that no allocations occur +/// Get the result of an expression, guaranteeing that no memory accesses occur /// during its evaluation. /// /// **Warning**: Unexpected behavior may occur when using the `return` keyword. From b23f7c45f708ed168196b31439e38cf35573985a Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:11:48 -0500 Subject: [PATCH 08/15] Handle release mode compiler seeing through us --- tests/assert_macro.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/assert_macro.rs b/tests/assert_macro.rs index 78b7e9f..a2935d1 100644 --- a/tests/assert_macro.rs +++ b/tests/assert_macro.rs @@ -21,6 +21,11 @@ fn into_box() -> Box { #[test] #[should_panic] fn early_return_boxing() { - into_box(); + if cfg!(debug_assertions) { + // The release-mode compiler is able to optimize through the Box + into_box(); + } else { + panic!("Intentional") + } } From 6df30473daacc6ff7152ce3e8ca19d81f3852bcd Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:14:56 -0500 Subject: [PATCH 09/15] Rustfmt fix --- tests/unused_panic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unused_panic.rs b/tests/unused_panic.rs index e378e0a..d9ef4a3 100644 --- a/tests/unused_panic.rs +++ b/tests/unused_panic.rs @@ -4,4 +4,4 @@ use qadapt::enter_protected; #[should_panic] fn guard_without_initialization() { enter_protected(); -} \ No newline at end of file +} From 1832cfb3896d51e491914e14673589be596a1d4d Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:16:35 -0500 Subject: [PATCH 10/15] Add testing in stable/beta branches --- .travis.yml | 11 ++++++++--- appveyor.yml | 4 ++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a97bb7d..6a01503 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,11 +23,16 @@ matrix: # Uniquely identifies the build that uploads to crates.io - env: CRATESIO=TRUE rust: nightly - - rust: nightly - # To build against specific Rust versions, include an item like the following: - # - rust: 1.30.0 + - rust: 1.31.0 - rust: nightly os: osx + - rust: stable + os: osx + - rust: beta + os: osx + - rust: nightly + - rust: stable + - rust: beta before_install: - set -e diff --git a/appveyor.yml b/appveyor.yml index 6400c44..22b79fe 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,6 +11,10 @@ environment: # RUST_VERSION: nightly - TARGET: x86_64-pc-windows-msvc RUST_VERSION: nightly + - TARGET: x86_64-pc-windows-msvc + RUST_VERSION: stable + - TARGET: x86_64-pc-windows-msvc + RUST_VERSION: beta install: - ps: >- From 508aa05cb99529b455a5e64ba95b95ff0b3f8789 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:19:37 -0500 Subject: [PATCH 11/15] Actually run rustfmt --- src/lib.rs | 22 +++++++++++----------- tests/assert_macro.rs | 1 - 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 79d5cd5..85acd04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,41 +5,41 @@ //! or code inside an `assert_no_alloc!` macro interacts with the allocator in any way. //! Wanton allocations and unforeseen drops no more - this library lets you focus on //! writing code without worrying if Rust properly managed to inline the variable into the stack. -//! +//! //! Now, an allocator blowing up in production is a scary thought; that's why QADAPT //! is designed to strip its own code out whenever you're running with a release build. //! Just like the [`debug_assert!` macro](https://doc.rust-lang.org/std/macro.debug_assert.html) //! in Rust's standard library, it's safe to use without worrying about a unforeseen //! circumstance causing your application to crash. -//! +//! //! # Usage -//! +//! //! Actually making use of QADAPT is straight-forward. To set up the allocator, //! place the following snippet in either your program binaries (main.rs) or tests: -//! +//! //! ```rust,ignore //! use qadapt::QADAPT; -//! +//! //! #[global_allocator] //! static Q: QADAPT = QADAPT; //! ``` -//! +//! //! After that, there are two ways of telling QADAPT that it should trigger a panic: -//! +//! //! 1. Annotate functions with the `#[no_alloc]` proc macro: //! ```rust,no_run //! use qadapt::no_alloc; -//! +//! //! #[no_alloc] //! fn do_math() -> u8 { //! 2 + 2 //! } //! ``` -//! +//! //! 2. Evaluate expressions with the `assert_no_alloc!` macro //! ```rust,no_run //! use qadapt::assert_no_alloc; -//! +//! //! fn do_work() { //! // This code is allowed to trigger an allocation //! let b = Box::new(8); @@ -119,7 +119,7 @@ pub fn exit_protected() { /// Get the result of an expression, guaranteeing that no memory accesses occur /// during its evaluation. -/// +/// /// **Warning**: Unexpected behavior may occur when using the `return` keyword. /// Because the macro cleanup logic will not be run, QADAPT may trigger a panic /// in code that was not specifically intended to be allocation-free. diff --git a/tests/assert_macro.rs b/tests/assert_macro.rs index a2935d1..03f98ec 100644 --- a/tests/assert_macro.rs +++ b/tests/assert_macro.rs @@ -28,4 +28,3 @@ fn early_return_boxing() { panic!("Intentional") } } - From 42754635ba2b339bb2c67084d0e42147d4fc84f4 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:22:30 -0500 Subject: [PATCH 12/15] Pass tests in release mode --- tests/unused_panic.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/unused_panic.rs b/tests/unused_panic.rs index d9ef4a3..e185a82 100644 --- a/tests/unused_panic.rs +++ b/tests/unused_panic.rs @@ -3,5 +3,9 @@ use qadapt::enter_protected; #[test] #[should_panic] fn guard_without_initialization() { - enter_protected(); + if cfg!(debug_assertions) { + enter_protected(); + } else { + panic!("Intentional") + } } From d19e596712ba003a109b91635ec8110989b0876d Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:23:39 -0500 Subject: [PATCH 13/15] Remove log crate --- Cargo.toml | 1 - src/lib.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3f81b2a..7b02f17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,6 @@ maintenance = { status = "actively-developed" } [dependencies] libc = "0.2" -log = "0.4" spin = { git = "https://github.com/bspeice/spin-rs.git" } thread-id = "3.3" diff --git a/src/lib.rs b/src/lib.rs index 85acd04..b2bf213 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,7 +50,6 @@ //! } #![deny(missing_docs)] -use log::warn; // thread_id is necessary because `std::thread::current()` panics if we have not yet // allocated a `thread_local!{}` it depends on. use thread_id; From dbf24afc6744dde640c38754af43e5890f5801b0 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:31:49 -0500 Subject: [PATCH 14/15] Remove env_logger as a dev dependency --- Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7b02f17..143e764 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,3 @@ spin = { git = "https://github.com/bspeice/spin-rs.git" } thread-id = "3.3" qadapt-macro = { version = "0.7.1", path = "./qadapt-macro" } - -[dev-dependencies] -env_logger = "0.6" From 65808b4e498050a22648523def32e070a4074678 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 6 Dec 2018 23:36:28 -0500 Subject: [PATCH 15/15] Minor docs update --- Makefile | 2 +- README.md | 17 ++++++++--------- src/lib.rs | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 16d0d47..8fc2aa7 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ readme: README.md README.md: src/lib.rs @sed -i '/---/q' README.md - @cat src/lib.rs | grep '//!' | sed 's/^\/\/\! *//g' >> README.md + @cat src/lib.rs | grep '//!' | sed -E 's/^\/\/\! ?//g' >> README.md .PHONY: doc doc: readme contributors diff --git a/README.md b/README.md index 30d8f73..52790f5 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,8 @@ [![travisci](https://travis-ci.org/bspeice/qadapt.svg?branch=master)](https://travis-ci.org/bspeice/qadapt) [![appveyor](https://ci.appveyor.com/api/projects/status/km1p081tkjcptn1w/branch/master?svg=true)](https://ci.appveyor.com/project/bspeice/qadapt/branch/master) - --- -# QADAPT - `debug_assert!` for your memory +## `debug_assert!` for your memory usage This allocator is a helper for writing high-performance code that is memory-sensitive; a thread panic will be triggered if a function annotated with `#[no_alloc]`, @@ -42,7 +41,7 @@ use qadapt::no_alloc; #[no_alloc] fn do_math() -> u8 { -2 + 2 + 2 + 2 } ``` @@ -51,10 +50,10 @@ fn do_math() -> u8 { use qadapt::assert_no_alloc; fn do_work() { -// This code is allowed to trigger an allocation -let b = Box::new(8); - -// This code would panic if an allocation occurred inside it -let x = assert_no_alloc!(*b + 2); -assert_eq!(x, 10); + // This code is allowed to trigger an allocation + let b = Box::new(8); + + // This code would panic if an allocation occurred inside it + let x = assert_no_alloc!(*b + 2); + assert_eq!(x, 10); } diff --git a/src/lib.rs b/src/lib.rs index b2bf213..94a6b36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//! # QADAPT - `debug_assert!` for your memory +//! ## `debug_assert!` for your memory usage //! //! This allocator is a helper for writing high-performance code that is memory-sensitive; //! a thread panic will be triggered if a function annotated with `#[no_alloc]`,