<ply-base.h>namespace plyThreads
<ply-base.h>namespace plyPlywood provides portable threading primitives that wrap the platform's native threading API. These include threads, mutexes, condition variables, and atomic operations.
PID | get_current_process_id() |
TID | get_current_thread_id() |
void | sleep_millis(u32 millis) |
PID get_current_process_id()Returns the operating system's process ID for the current process.
TID get_current_thread_id()Returns the operating system's thread ID for the current thread.
void sleep_millis(u32 millis)Suspends the current thread for the specified number of milliseconds.
Thread
A Thread represents a separate thread of execution.
bool | is_valid() |
void | run<Callable>(Callable& callable) |
void | join() |
bool is_valid()Returns
trueif the thread object represents a running or joinable thread.void run<Callable>(Callable& callable)Starts a new thread that executes the given callable object. The callable can be a lambda, functor, or any object with
operator().void join()Blocks until the thread finishes execution. Must be called before the
Threadobject is destroyed.
Atomic
Atomic provides atomic operations on integer types with explicit memory ordering. The memory ordering is specified in the function name: acquire for load operations, release for store operations, and acq_rel for read-modify-write operations.
| Atomic(T value) |
| Atomic(const Atomic<T>& other) |
void | operator=(const Atomic<T>& other) |
T | load_nonatomic() const |
T | load_acquire() const |
void | store_nonatomic(T value) |
void | store_release(T value) |
T | compare_exchange_acq_rel(T expected, T desired) |
T | exchange_acq_rel(T desired) |
T | fetch_add_acq_rel(T operand) |
T | fetch_sub_acq_rel(T operand) |
T | fetch_and_acq_rel(T operand) |
T | fetch_or_acq_rel(T operand) |
Atomic(T value)Constructs an atomic with the given initial value.
Atomic(const Atomic<T>& other)Copy constructor. Performs an atomic load from
other.void operator=(const Atomic<T>& other)Copy assignment. Performs an atomic load and store.
T load_nonatomic() constReads the value without atomic guarantees. Only safe when no other thread is writing.
T load_acquire() constAtomically reads the value with acquire semantics.
void store_nonatomic(T value)Writes the value without atomic guarantees. Only safe when no other thread is reading.
void store_release(T value)Atomically writes the value with release semantics.
T compare_exchange_acq_rel(T expected, T desired)If the current value equals
expected, replaces it withdesired. Returns the previous value.T exchange_acq_rel(T desired)Atomically replaces the value and returns the previous value.
T fetch_add_acq_rel(T operand)Atomically adds
operandto the value and returns the previous value.T fetch_sub_acq_rel(T operand)Atomically subtracts
operandfrom the value and returns the previous value.T fetch_and_acq_rel(T operand)Atomically performs bitwise AND with
operandand returns the previous value.T fetch_or_acq_rel(T operand)Atomically performs bitwise OR with
operandand returns the previous value.
ThreadLocal
ThreadLocal provides per-thread storage. Each thread sees its own independent value.
| ThreadLocal() |
| ThreadLocal(const ThreadLocal& ) |
U | load() const |
void | store(T value) |
Scope | set_in_scope(T value) |
ThreadLocal()Constructs a thread-local variable. Each thread's value is initially zero/null.
ThreadLocal(const ThreadLocal& )Thread-local variables cannot be copied.
U load() constReturns the current thread's value.
void store(T value)Sets the current thread's value.
Scope set_in_scope(T value)Sets the value for the duration of a scope. The previous value is restored when the scope ends.
Mutex
A Mutex provides mutual exclusion to protect shared data. Use LockGuard for RAII-style locking.
void | lock() |
bool | try_lock() |
void | unlock() |
void lock()Acquires the mutex, blocking if another thread holds it.
bool try_lock()Attempts to acquire the mutex without blocking. Returns
trueif successful.void unlock()Releases the mutex.
LockGuard<MutexType> is a RAII wrapper that locks a mutex in its constructor and unlocks it in its destructor:
LockGuard<Mutex> guard{my_mutex}; // mutex is locked
// ... critical section ...
// mutex is unlocked when guard goes out of scope
ConditionVariable
A ConditionVariable allows threads to wait for a condition to become true. Always use with a mutex to protect the condition.
void | wait(LockGuard<Mutex>& lock_guard) |
void | timed_wait(LockGuard<Mutex>& lock_guard, u32 wait_millis) |
void | wake_all() |
void wait(LockGuard<Mutex>& lock_guard)Atomically releases the mutex and waits for a signal. Re-acquires the mutex before returning.
void timed_wait(LockGuard<Mutex>& lock_guard, u32 wait_millis)Like
wait, but returns afterwait_millismilliseconds even if not signaled.void wake_all()Wakes all threads waiting on this condition variable.
ReadWriteLock
A ReadWriteLock allows multiple readers or a single writer. This is efficient when reads are much more common than writes.
void | lock_exclusive() |
void | unlock_exclusive() |
void | lock_shared() |
void | unlock_shared() |
void lock_exclusive()Acquires exclusive (write) access. Blocks until all readers and writers have released the lock.
void unlock_exclusive()Releases exclusive access.
void lock_shared()Acquires shared (read) access. Multiple threads can hold shared access simultaneously.
void unlock_shared()Releases shared access.
Semaphore
A Semaphore is a signaling mechanism that maintains a count. Threads can wait for the count to be positive and decrement it, or signal to increment the count.
void | wait() |
void | signal(u32 count) |
void wait()Blocks until the count is positive, then decrements it.
void signal(u32 count)Increments the count by
count, potentially waking waiting threads.