Skip to content

Commit

Permalink
Better contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
nickpdemarco committed Nov 29, 2023
1 parent ac8e692 commit 4f5362e
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 5 deletions.
14 changes: 12 additions & 2 deletions rustport/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ use std::{ffi::c_void, sync::Mutex};
use stlab::{Priority, PriorityTaskSystem};
mod stlab;

/// A static instance of the task system which is invoked through the `execute` functions below.
static TASK_SYSTEM: Lazy<Mutex<PriorityTaskSystem>> =
Lazy::new(|| Mutex::new(PriorityTaskSystem::new()));

// "Threadsafe" is not a guarantee, it is a requirement. These pointers are assumed to be able to
// be sent to another thread, and therefore must not rely on thread-local state.

/// A function pointer paired with a context, akin to a C++ lambda and its captures.
///
/// "Threadsafe" is not a guarantee, it is a requirement. These pointers are assumed to be able to
/// be sent to another thread, and therefore must not rely on thread-local state.
struct ThreadsafeCFnWrapper {
context: *mut c_void,
fn_ptr: extern "C" fn(*mut c_void),
Expand All @@ -19,21 +23,27 @@ impl ThreadsafeCFnWrapper {
Self { context, fn_ptr }
}

// Note: there is no way in stable rust to make a struct invocable with () syntax.
pub(crate) fn call(&self) {
(self.fn_ptr)(self.context)
}
}

/// `ThreadsafeCFnWrapper` may not rely on thread-local state.
unsafe impl Send for ThreadsafeCFnWrapper {}

/// Enqueues a the execution of `f(context)` on the PriorityTaskSystem.
///
/// Precondition: Neither `context` nor `fn_ptr` may rely on thread-local state.
#[no_mangle]
pub extern "C" fn execute(context: *mut c_void, fn_ptr: extern "C" fn(*mut c_void)) -> i32 {
execute_priority(context, fn_ptr, Priority::Default);
0
}

/// Enqueues a the execution of `f(context)` on the PriorityTaskSystem at the given `priority`.
///
/// Precondition: Neither `context` nor `fn_ptr` may rely on thread-local state.
#[no_mangle]
pub extern "C" fn execute_priority(
context: *mut c_void,
Expand Down
1 change: 0 additions & 1 deletion rustport/src/stlab/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ impl PriorityTaskSystem {

/// Push `f` to the first queue in `queues` whose mutex is not under contention.
/// If no such queue is found after a single pass, blockingly push `f` to one queue.
// REVIEW: I'm not sure `execute` is a good name. I think we want `push`, or `push_with_priority`.
pub fn execute<F>(&self, f: F, p: Priority)
where
F: FnOnce() -> () + Send + 'static,
Expand Down
3 changes: 1 addition & 2 deletions rustport/src/stlab/waiter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ impl Waiter {
}

/// Sets waiting to `false`. If waiting was `true`, wake one waiter and return `true`. Otherwise, return `false`.
/// If `try_lock` fails, return `false`. (REVIEW: why?)
/// (REVIEW: is it redundant to express that `waiting` and `done` are accesed under a mutex?)
/// If `try_lock` fails, return `false`.
pub fn wake(&self) -> bool {
if let Ok(ref mut this) = self.protected.try_lock() {
if !this.waiting {
Expand Down

0 comments on commit 4f5362e

Please sign in to comment.