Skip to content

Instantly share code, notes, and snippets.

@mikeyhew
Last active June 9, 2017 06:50
Show Gist options
  • Save mikeyhew/15a6cc51acc44c3a60bdf31dbb7ee129 to your computer and use it in GitHub Desktop.
Save mikeyhew/15a6cc51acc44c3a60bdf31dbb7ee129 to your computer and use it in GitHub Desktop.
An example of storing a Vec in a thread-local "scratchpad" static variable, to keep from repeatedly allocating and deallocating eat
use std::cell::UnsafeCell;
#[repr(C)]
struct Channel;
extern {
fn foo(inputs: *mut *mut Channel);
}
fn call_foo(inputs: &mut [&mut [Channel]]) {
thread_local! {
static SCRATCHPAD: UnsafeCell<Vec<*mut Channel>> = UnsafeCell::new(Vec::new());
}
SCRATCHPAD.with(|scratchpad| {
unsafe {
// safe because we only access this thread local from this function
// and there's no recursive calls inside of here AFAIK
let scratchpad = &mut *scratchpad.get();
// safe because no destructor will run on a raw pointer
scratchpad.set_len(0);
scratchpad.reserve(inputs.len());
scratchpad.extend(inputs.iter_mut().map(|slice: &mut &mut [Channel]| slice.as_mut_ptr()));
foo(scratchpad.as_mut_ptr());
}
});
}
fn main() {
println!("Hello, world!");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment