Add claude docs
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# Threading System
|
||||
|
||||
Source: `src/dusk/thread/`
|
||||
|
||||
## Platform support
|
||||
|
||||
Threading currently requires **pthreads** (`DUSK_THREAD_PTHREAD`). The
|
||||
implementation lives in the core thread files and is guarded by that
|
||||
compile-time flag -- there are no separate per-platform thread
|
||||
directories.
|
||||
|
||||
Thread-local storage uses the `THREAD_LOCAL` macro, which maps to
|
||||
`__thread` when pthreads is available. This is used by the error system
|
||||
to give each thread its own `ERROR_STATE`.
|
||||
|
||||
## Thread lifecycle
|
||||
|
||||
Threads follow a strict state machine:
|
||||
|
||||
```
|
||||
STOPPED -> STARTING -> RUNNING -> STOP_REQUESTED -> STOPPED
|
||||
```
|
||||
|
||||
- `threadStart()` -- blocking: starts the thread and waits until it
|
||||
reaches RUNNING.
|
||||
- `threadStop()` -- blocking: requests stop and waits until STOPPED.
|
||||
- `threadStartRequest()` -- non-blocking equivalent of `threadStart`.
|
||||
- `threadStopRequest()` -- non-blocking equivalent of `threadStop`.
|
||||
|
||||
The thread callback polls `threadShouldStop()` to know when to exit.
|
||||
Never kill a thread forcefully -- always let it stop cooperatively.
|
||||
|
||||
## Thread API
|
||||
|
||||
```c
|
||||
void threadInit(thread_t *thread, errorret_t (*callback)(thread_t *t));
|
||||
// Initialise; callback is the thread entry point.
|
||||
|
||||
errorret_t threadStart(thread_t *thread);
|
||||
// Start and block until RUNNING.
|
||||
|
||||
errorret_t threadStop(thread_t *thread);
|
||||
// Request stop, block until STOPPED.
|
||||
|
||||
void threadStartRequest(thread_t *thread);
|
||||
void threadStopRequest(thread_t *thread);
|
||||
// Non-blocking variants.
|
||||
|
||||
bool_t threadShouldStop(const thread_t *thread);
|
||||
// Call from inside the thread callback to know when to exit.
|
||||
```
|
||||
|
||||
## Mutex API (`threadmutex.h`)
|
||||
|
||||
Each `threadmutex_t` wraps a pthread mutex and a condition variable.
|
||||
|
||||
```c
|
||||
void threadMutexInit(threadmutex_t *mutex);
|
||||
void threadMutexDispose(threadmutex_t *mutex);
|
||||
|
||||
void threadMutexLock(threadmutex_t *mutex);
|
||||
void threadMutexUnlock(threadmutex_t *mutex);
|
||||
bool_t threadMutexTryLock(threadmutex_t *mutex);
|
||||
// Returns true if the lock was acquired; false if already held.
|
||||
|
||||
void threadMutexWaitLock(threadmutex_t *mutex);
|
||||
// Block until signalled (like pthread_cond_wait).
|
||||
// Must be called while holding the lock.
|
||||
|
||||
void threadMutexSignal(threadmutex_t *mutex);
|
||||
// Wake one waiter.
|
||||
```
|
||||
|
||||
## Usage example
|
||||
|
||||
```c
|
||||
static errorret_t workerCallback(thread_t *t) {
|
||||
while(!threadShouldStop(t)) {
|
||||
// do work
|
||||
}
|
||||
errorOk();
|
||||
}
|
||||
|
||||
thread_t worker;
|
||||
threadInit(&worker, workerCallback);
|
||||
errorChain(threadStart(&worker));
|
||||
// ... later ...
|
||||
errorChain(threadStop(&worker));
|
||||
```
|
||||
|
||||
## Thread safety rules
|
||||
|
||||
- The error system (`ERROR_STATE`) is thread-local -- each thread has
|
||||
its own error state. Do not pass `errorret_t` across thread
|
||||
boundaries without copying the message and lines strings first.
|
||||
- Asset loading: the background thread calls `loadAsync`; the main
|
||||
thread calls `loadSync`. Never call GPU or SDL functions from the
|
||||
loader background thread.
|
||||
- Use `assertIsMainThread()` / `assertNotMainThread()` to guard
|
||||
functions that have thread affinity requirements.
|
||||
Reference in New Issue
Block a user