Building on the above components, this struct contains the algorithm essential to the original C++ implementation. Namely (quoting the inline documentation):
/// A portable work-stealing task scheduler with three priorities.
///
/// This scheduler spins up a number of threads corresponding to the amount of parallelism available
/// on the target platform, namely, std::thread::available_parallelism() - 1. Each thread is
/// assigned a threadsafe priority queue. To reduce contention on push and pop operations, a thread
/// will first attempt to acquire the lock for its own queue without blocking.
/// If that fails, it will attempt the same non-blocking push/pop for each other priority queue in
/// the scheduler. Finally, if each of those attempts also fail, the thread will attempt a blocking
/// push/pop on its own priority queue.
///
/// The `add_thread` API is intended to mitigate the possibility of deadlock by spinning up a new
/// worker thread that non-blockingly polls all of the system's priority queues, and then sleeps
/// until `wake()` is called.
This PR reimplements
stlab::priority_task_system
in Rust.Usage
The rust port is chosen with a cmake argument, as in:
The build will require an installation of
cargo
; otherwise, it should work out of the box.To test this implementation, build with cmake as above, and then run
ctest
from the build directory.Implementation
For greater readability and easier-to-prove safety, the C++ implementation has been broken into four components:
DropJoinThreadPool
Like
scoped_threadpool
, but the scope is tied to an object's lifetime, rather than a function call.CoarsePriorityQueue
A priority queue with three priorities.
NotificationQueue
A threadsafe
CoarsePriorityQueue
.Waiter
A faithful copy of
stlab::detail::waiter
. It may be prudent to rewrite this in terms of the Rust-nativethread::park
PriorityTaskSystem
Building on the above components, this struct contains the algorithm essential to the original C++ implementation. Namely (quoting the inline documentation):