mirror of
https://github.com/bspeice/qadapt
synced 2024-11-24 06:48:09 -05:00
Fix conditional compilation guards
This commit is contained in:
parent
79f57ba2f9
commit
5d7be8e18e
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
*.swp
|
*.swp
|
||||||
|
.idea/
|
19
examples/release_mode.rs
Normal file
19
examples/release_mode.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
extern crate qadapt;
|
||||||
|
|
||||||
|
use qadapt::allocate_panic;
|
||||||
|
use qadapt::QADAPT;
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
static Q: QADAPT = QADAPT;
|
||||||
|
|
||||||
|
#[allocate_panic]
|
||||||
|
fn does_allocate() -> Box<u8> {
|
||||||
|
Box::new(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// If you were to run `cargo run --example release_mode`, this program blows up.
|
||||||
|
// If, however, you ran `cargo run --release --example release_mode`,
|
||||||
|
// nothing interesting will happen.
|
||||||
|
does_allocate();
|
||||||
|
}
|
@ -58,35 +58,6 @@ macro_rules! token_stream {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
fn release_guard(fn_name: &str) -> TokenStream {
|
|
||||||
// #[cfg(any(debug, test))]
|
|
||||||
// { ::qadapt::`fn_name`() }
|
|
||||||
token_stream!(
|
|
||||||
punct!('#', Spacing::Alone),
|
|
||||||
group!(Delimiter::Bracket, token_stream!(
|
|
||||||
ident!("cfg"),
|
|
||||||
group!(Delimiter::Parenthesis, token_stream!(
|
|
||||||
ident!("any"),
|
|
||||||
group!(Delimiter::Parenthesis, token_stream!(
|
|
||||||
ident!("debug"),
|
|
||||||
punct!(',', Spacing::Alone),
|
|
||||||
ident!("test")
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
group!(Delimiter::Brace, token_stream!(
|
|
||||||
punct!(':', Spacing::Joint),
|
|
||||||
punct!(':', Spacing::Alone),
|
|
||||||
ident!("qadapt"),
|
|
||||||
punct!(':', Spacing::Joint),
|
|
||||||
punct!(':', Spacing::Alone),
|
|
||||||
ident!(fn_name),
|
|
||||||
group!(Delimiter::Parenthesis)
|
|
||||||
))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generate the body of a function that is protected from making allocations.
|
/// Generate the body of a function that is protected from making allocations.
|
||||||
/// The code is conditionally compiled so that all QADAPT-related bits
|
/// The code is conditionally compiled so that all QADAPT-related bits
|
||||||
/// will be removed for release/bench builds, making the proc_macro safe
|
/// will be removed for release/bench builds, making the proc_macro safe
|
||||||
@ -94,7 +65,15 @@ fn release_guard(fn_name: &str) -> TokenStream {
|
|||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn protected_body(fn_body: Group) -> TokenTree {
|
fn protected_body(fn_body: Group) -> TokenTree {
|
||||||
group!(Delimiter::Brace, token_stream!(
|
group!(Delimiter::Brace, token_stream!(
|
||||||
group!(Delimiter::Brace, release_guard("enter_protected")),
|
group!(Delimiter::Brace, token_stream!(
|
||||||
|
punct!(':', Spacing::Joint),
|
||||||
|
punct!(':', Spacing::Alone),
|
||||||
|
ident!("qadapt"),
|
||||||
|
punct!(':', Spacing::Joint),
|
||||||
|
punct!(':', Spacing::Alone),
|
||||||
|
ident!("enter_protected"),
|
||||||
|
group!(Delimiter::Parenthesis)
|
||||||
|
)),
|
||||||
ident!("let"),
|
ident!("let"),
|
||||||
ident!("__ret__"),
|
ident!("__ret__"),
|
||||||
punct!('=', Spacing::Alone),
|
punct!('=', Spacing::Alone),
|
||||||
@ -110,7 +89,15 @@ fn protected_body(fn_body: Group) -> TokenTree {
|
|||||||
))
|
))
|
||||||
)),
|
)),
|
||||||
group!(Delimiter::Brace, token_stream!(
|
group!(Delimiter::Brace, token_stream!(
|
||||||
group!(Delimiter::Brace, release_guard("exit_protected")),
|
group!(Delimiter::Brace, token_stream!(
|
||||||
|
punct!(':', Spacing::Joint),
|
||||||
|
punct!(':', Spacing::Alone),
|
||||||
|
ident!("qadapt"),
|
||||||
|
punct!(':', Spacing::Joint),
|
||||||
|
punct!(':', Spacing::Alone),
|
||||||
|
ident!("exit_protected"),
|
||||||
|
group!(Delimiter::Parenthesis)
|
||||||
|
)),
|
||||||
ident!("__ret__")
|
ident!("__ret__")
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
@ -129,7 +116,18 @@ fn escape_return(ts: TokenStream) -> TokenStream {
|
|||||||
vec![group!(Delimiter::Brace, escape_return(g.stream()))]
|
vec![group!(Delimiter::Brace, escape_return(g.stream()))]
|
||||||
}
|
}
|
||||||
TokenTree::Ident(ref i) if i.to_string() == "return" && !in_closure => vec![
|
TokenTree::Ident(ref i) if i.to_string() == "return" && !in_closure => vec![
|
||||||
group!(Delimiter::Brace, release_guard("exit_protected")),
|
group!(
|
||||||
|
Delimiter::Brace,
|
||||||
|
token_stream!(
|
||||||
|
punct!(':', Spacing::Joint),
|
||||||
|
punct!(':', Spacing::Alone),
|
||||||
|
ident!("qadapt"),
|
||||||
|
punct!(':', Spacing::Joint),
|
||||||
|
punct!(':', Spacing::Alone),
|
||||||
|
ident!("exit_protected"),
|
||||||
|
group!(Delimiter::Parenthesis)
|
||||||
|
)
|
||||||
|
),
|
||||||
tt.clone(),
|
tt.clone(),
|
||||||
],
|
],
|
||||||
TokenTree::Punct(ref p) if p.as_char() == '|' => {
|
TokenTree::Punct(ref p) if p.as_char() == '|' => {
|
||||||
|
13
src/lib.rs
13
src/lib.rs
@ -39,6 +39,8 @@ pub struct QADAPT;
|
|||||||
/// Let QADAPT know that we are now entering a protected region and that
|
/// Let QADAPT know that we are now entering a protected region and that
|
||||||
/// panics should be triggered if allocations/drops happen while we are running.
|
/// panics should be triggered if allocations/drops happen while we are running.
|
||||||
pub fn enter_protected() {
|
pub fn enter_protected() {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
if thread::panicking() {
|
if thread::panicking() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -49,10 +51,13 @@ pub fn enter_protected() {
|
|||||||
})
|
})
|
||||||
.unwrap_or_else(|_e| ());
|
.unwrap_or_else(|_e| ());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Let QADAPT know that we are exiting a protected region. Will panic
|
/// Let QADAPT know that we are exiting a protected region. Will panic
|
||||||
/// if we attempt to [`exit_protected`] more times than we [`enter_protected`].
|
/// if we attempt to [`exit_protected`] more times than we [`enter_protected`].
|
||||||
pub fn exit_protected() {
|
pub fn exit_protected() {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
if thread::panicking() {
|
if thread::panicking() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -69,13 +74,21 @@ pub fn exit_protected() {
|
|||||||
})
|
})
|
||||||
.unwrap_or_else(|_e| ());
|
.unwrap_or_else(|_e| ());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static INTERNAL_ALLOCATION: RwLock<usize> = RwLock::new(usize::max_value());
|
static INTERNAL_ALLOCATION: RwLock<usize> = RwLock::new(usize::max_value());
|
||||||
|
|
||||||
/// Get the current "protection level" in QADAPT: calls to enter_protected() - exit_protected()
|
/// Get the current "protection level" in QADAPT: calls to enter_protected() - exit_protected()
|
||||||
pub fn protection_level() -> usize {
|
pub fn protection_level() -> usize {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
PROTECTION_LEVEL.try_with(|v| *v.read()).unwrap_or(0)
|
PROTECTION_LEVEL.try_with(|v| *v.read()).unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
{
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn claim_internal_alloc() {
|
fn claim_internal_alloc() {
|
||||||
loop {
|
loop {
|
||||||
|
@ -17,7 +17,7 @@ fn test_copy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[cfg_attr(debug_assertions, should_panic)]
|
||||||
fn test_allocate() {
|
fn test_allocate() {
|
||||||
enter_protected();
|
enter_protected();
|
||||||
let _x = Box::new(12);
|
let _x = Box::new(12);
|
||||||
@ -90,7 +90,7 @@ fn vec_with_one() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[cfg_attr(debug_assertions, should_panic)]
|
||||||
fn exit_too_often() {
|
fn exit_too_often() {
|
||||||
enter_protected();
|
enter_protected();
|
||||||
exit_protected();
|
exit_protected();
|
||||||
@ -98,7 +98,7 @@ fn exit_too_often() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[cfg_attr(debug_assertions, should_panic)]
|
||||||
fn intentional_drop() {
|
fn intentional_drop() {
|
||||||
let v: Vec<()> = Vec::new();
|
let v: Vec<()> = Vec::new();
|
||||||
let v = Box::new(v);
|
let v = Box::new(v);
|
||||||
|
@ -9,11 +9,6 @@ static Q: QADAPT = QADAPT;
|
|||||||
|
|
||||||
#[allocate_panic]
|
#[allocate_panic]
|
||||||
fn no_allocate() {
|
fn no_allocate() {
|
||||||
#[cfg(not(release))]
|
|
||||||
{
|
|
||||||
let _v = 0;
|
|
||||||
}
|
|
||||||
assert_eq!(::qadapt::protection_level(), 1);
|
|
||||||
let _v: Vec<()> = Vec::with_capacity(0);
|
let _v: Vec<()> = Vec::with_capacity(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,3 +144,16 @@ fn example_closure() {
|
|||||||
fn macro_closure() {
|
fn macro_closure() {
|
||||||
example_closure()
|
example_closure()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allocate_panic]
|
||||||
|
fn macro_release_safe() {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
assert_eq!(1, ::qadapt::protection_level());
|
||||||
|
}
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
{
|
||||||
|
assert_eq!(0, ::qadapt::protection_level());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user