libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
Data Structures | Macros | Typedefs | Functions | Variables
thread.h File Reference
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "assert.h"
#include "helpers.h"
#include "list.h"
#include "time.h"
#include "safe_alloc.h"
Include dependency graph for thread.h:

Go to the source code of this file.

Data Structures

struct  lacf_thread_info_t
 
struct  mutex_t
 
struct  rwmutex_t
 
struct  rwlock_waiter_t
 

Macros

#define thread_create(thrp, start_proc, arg)
 
#define atomic32_t   volatile int32_t
 
#define atomic_inc_32(x)   __sync_add_and_fetch((x), 1)
 
#define atomic_dec_32(x)   __sync_add_and_fetch((x), -1)
 
#define atomic_add_32(x, y)   __sync_add_and_fetch((x), (y))
 
#define atomic_set_32(x, y)   __atomic_store_n((x), (y), __ATOMIC_RELAXED)
 
#define atomic64_t   volatile int64_t
 
#define atomic_inc_64(x)   __sync_add_and_fetch((x), 1)
 
#define atomic_dec_64(x)   __sync_add_and_fetch((x), -1)
 
#define atomic_add_64(x, y)   __sync_add_and_fetch((x), (y))
 
#define atomic_set_64(x, y)   __atomic_store_n((x), (y), __ATOMIC_RELAXED)
 
#define curthread_id   GetCurrentThreadId()
 
#define curthread   GetCurrentThread()
 
#define VERIFY_MUTEX_HELD(mtx)   (void)1
 
#define VERIFY_MUTEX_NOT_HELD(mtx)   (void)1
 
#define THREAD_PRIO_IDLE   THREAD_PRIORITY_IDLE
 
#define THREAD_PRIO_VERY_LOW   THREAD_PRIORITY_LOWEST
 
#define THREAD_PRIO_LOW   THREAD_PRIORITY_BELOW_NORMAL
 
#define THREAD_PRIO_NORM   THREAD_PRIORITY_NORMAL
 
#define THREAD_PRIO_HIGH   THREAD_PRIORITY_ABOVE_NORMAL
 
#define THREAD_PRIO_VERY_HIGH   THREAD_PRIORITY_HIGHEST
 
#define THREAD_PRIO_RT   THREAD_PRIORITY_TIME_CRITICAL
 
#define ASSERT_MUTEX_HELD(mtx)
 
#define ASSERT_MUTEX_NOT_HELD(mtx)
 

Typedefs

typedef HANDLE thread_t
 
typedef DWORD thread_id_t
 
typedef CONDITION_VARIABLE condvar_t
 

Functions

static bool_t thread_equal (thread_id_t tid1, thread_id_t tid2)
 
static void mutex_init (mutex_t *mtx)
 
static void mutex_destroy (mutex_t *mtx)
 
static void mutex_enter (mutex_t *mtx)
 
static void mutex_exit (mutex_t *mtx)
 
static void _lacf_thread_list_init (void)
 
static void _lacf_thread_list_fini (void)
 
static void _lacf_thread_list_add (lacf_thread_info_t *ti)
 
static void _lacf_thread_list_remove (lacf_thread_info_t *ti)
 
static void lacf_threads_fini (void)
 
DWORD lacf_thread_start_routine (void *arg)
 
static bool_t lacf_thread_create (thread_t *thrp, void(*proc)(void *), void *arg, const char *filename, int linenum)
 
static void thread_join (thread_t *thrp)
 
static void thread_set_name (const char *name)
 
static void cv_wait (condvar_t *cv, mutex_t *mtx)
 
static int cv_timedwait (condvar_t *cv, mutex_t *mtx, uint64_t limit)
 
static void cv_init (condvar_t *cv)
 
static void cv_destroy (condvar_t *cv)
 
static void cv_signal (condvar_t *cv)
 
static void cv_broadcast (condvar_t *cv)
 
static void thread_set_prio (thread_t thr, int prio)
 
void lacf_mask_sigpipe (void)
 
static void rwmutex_init (rwmutex_t *rw)
 
static void rwmutex_destroy (rwmutex_t *rw)
 
static bool_t rwmutex_held_write (rwmutex_t *rw)
 
static bool_t rwmutex_can_enter_impl (const rwmutex_t *rw, const rwlock_waiter_t *wt_self)
 
static void rwmutex_enter (rwmutex_t *rw, bool_t write)
 
static void rwmutex_exit (rwmutex_t *rw)
 
static void rwmutex_upgrade (rwmutex_t *rw)
 

Variables

bool_t lacf_thread_list_inited
 
mutex_t lacf_thread_list_lock
 
list_t lacf_thread_list
 

Detailed Description

Basic portable multi-threading API. We have 3 kinds of objects and associated manipulation functions here:

  1. thread_t - A generic thread identification structure.
  2. mutex_t - A generic mutual exclusion lock.
  3. condvar_t - A generic condition variable.

The actual implementation is large contained in this header and mostly works as a set of pre-processor switching on top of the OS-specific threading API (pthreads on Unix/Linux, winthreads on Win32).

Thread Handling

Example of how to create a thread:

thread_t my_thread;
if (!thread_create(&my_thread, thread_main_func, thread_arg))
fprintf(stderr, "thread create failed!\n");
HANDLE thread_t
Definition thread.h:393
#define thread_create(thrp, start_proc, arg)
Definition thread.h:189

Example of how to wait for a thread to exit:

thread_t my_thread;
thread_join(my_thread);
// ... thread disposed of, no need for further cleanup ...
## Locking
static void thread_join(thread_t *thrp)
Definition thread.h:836

Example of how to use a mutex_t:

mutex_t my_lock; // the lock object itself
mutex_init(&my_lock); // create the lock
mutex_enter(&my_lock); // grab the lock
// ... do some critical, exclusiony-type stuff ...
mutex_exit(&my_lock); // release the lock
mutex_destroy(&my_lock); // free the lock
## Condition Variables
static void mutex_destroy(mutex_t *mtx)
Definition thread.h:499
static void mutex_enter(mutex_t *mtx)
Definition thread.h:530
static void mutex_exit(mutex_t *mtx)
Definition thread.h:556
static void mutex_init(mutex_t *mtx)
Definition thread.h:488

Example of how to use a condvar_t:

mutex_t my_lock;
condvar_t my_cv;
mutex_init(&my_lock); // create a lock to control the CV
cv_init(&my_cv); // create the condition variable
// thread that's going to signal the condition:
mutex_enter(&my_lock); // grab the lock
// ... set up some resource that others might be waiting on ...
cv_broadcast(&my_lock); // wake up all waiters
mutex_exit(&my_lock); // release the lock
// thread that's going to wait on the condition:
mutex_enter(&my_lock); // grab the lock
while (!condition_met())
cv_wait(&my_cv, &my_lock); // wait for the CV
// to be signalled
// ... condition fulfilled, use the resource ...
mutex_exit(&my_lock); // release the lock
CONDITION_VARIABLE condvar_t
Definition thread.h:465
static void cv_init(condvar_t *cv)
Definition thread.h:926
static void cv_wait(condvar_t *cv, mutex_t *mtx)
Definition thread.h:868
static void cv_broadcast(condvar_t *cv)
Definition thread.h:960

You can also performed a "timed" wait on a CV using cv_timedwait(). The function will exit when either the condition has been signalled, or the timer has expired. The return value of the function indicates whether the condition was signalled before the timer expired (returns zero), or if the wait timed out (returns ETIMEDOUT) or another error occurred (returns -1).

mutex_enter(&my_lock); // grab the lock
// Wait for the CV to be signalled. Time argument is an
// absolute time as returned by the 'microclock' function +
// whatever extra time delay you want to apply.
uint64_t deadline = microclock() + timeout_usecs;
while (!condition_met()) {
if (cv_timedwait(&my_cv, &my_lock, deadline) ==
ETIMEDOUT) {
// timed out waiting for CV to signal
break;
}
}
mutex_exit(&my_lock); // release the lock
static int cv_timedwait(condvar_t *cv, mutex_t *mtx, uint64_t limit)
Definition thread.h:898

Atomics

The atomic32_t and atomic64_t types describe signed 32- and 64-bit integers respectively, which are suitable for being passed to the relevant atomic_* functions. Example of how use an atomic function:

atomic32_t my_value; // declare an atomic 32-bit signed int
atomic_set_32(&my_value, 1234); // set an integer atomically
atomic_inc_32(&my_value); // increment integer atomically
atomic_dec_32(&my_value); // decrement integer atomically
atomic_add_32(&my_value, -352); // add a value to the atomic integer
#define atomic_dec_32(x)
Definition thread.h:316
#define atomic32_t
Definition thread.h:314
#define atomic_add_32(x, y)
Definition thread.h:317
#define atomic_inc_32(x)
Definition thread.h:315
#define atomic_set_32(x, y)
Definition thread.h:318

Definition in file thread.h.

Macro Definition Documentation

◆ ASSERT_MUTEX_HELD

#define ASSERT_MUTEX_HELD (   mtx)

If compiling with the DEBUG macro set, expands to VERIFY_MUTEX_HELD(). Otherwise expands to nothing.

See also
VERIFY_MUTEX_HELD()
ASSERT_MUTEX_NOT_HELD()

Definition at line 1228 of file thread.h.

◆ ASSERT_MUTEX_NOT_HELD

#define ASSERT_MUTEX_NOT_HELD (   mtx)

If compiling with the DEBUG macro set, expands to VERIFY_MUTEX_NOT_HELD(). Otherwise expands to nothing.

See also
VERIFY_MUTEX_NOT_HELD()
ASSERT_MUTEX_HELD()

Definition at line 1229 of file thread.h.

◆ atomic32_t

#define atomic32_t   volatile int32_t

Atomic signed 32-bit integer. You must use this type with the atomic_*_32() family of functions, such as atomic_inc_32(), atomic_dec_32(), atomic_set_32() and atomic_add_32().

Definition at line 314 of file thread.h.

◆ atomic64_t

#define atomic64_t   volatile int64_t

Atomic signed 64-bit integer. You must use this type with the atomic_*_64() family of functions, such as atomic_inc_64(), atomic_dec_64(), atomic_set_64() and atomic_add_64().

Definition at line 319 of file thread.h.

◆ atomic_add_32

#define atomic_add_32 (   x,
 
)    __sync_add_and_fetch((x), (y))

Adds an arbitrary value to an atomic 32-bit.

Parameters
xPointer to the atomic32_t to be added to.
y32-bit signed integer value to be added to x. Can be negative to perform subtraction instead.

Definition at line 317 of file thread.h.

◆ atomic_add_64

#define atomic_add_64 (   x,
 
)    __sync_add_and_fetch((x), (y))

Adds an arbitrary value to an atomic 64-bit.

Parameters
xPointer to the atomic64_t to be added to.
y64-bit signed integer value to be added to x. Can be negative to perform subtraction instead.

Definition at line 322 of file thread.h.

◆ atomic_dec_32

#define atomic_dec_32 (   x)    __sync_add_and_fetch((x), -1)

Decrements an atomic 32-bit integer by 1.

Parameters
xPointer to the atomic32_t to be decremented.

Definition at line 316 of file thread.h.

◆ atomic_dec_64

#define atomic_dec_64 (   x)    __sync_add_and_fetch((x), -1)

Decrements an atomic 64-bit integer by 1.

Parameters
xPointer to the atomic64_t to be decremented.

Definition at line 321 of file thread.h.

◆ atomic_inc_32

#define atomic_inc_32 (   x)    __sync_add_and_fetch((x), 1)

Increments an atomic 32-bit integer by 1.

Parameters
xPointer to the atomic32_t to be incremented.

Definition at line 315 of file thread.h.

◆ atomic_inc_64

#define atomic_inc_64 (   x)    __sync_add_and_fetch((x), 1)

Increments an atomic 64-bit integer by 1.

Parameters
xPointer to the atomic64_t to be incremented.

Definition at line 320 of file thread.h.

◆ atomic_set_32

#define atomic_set_32 (   x,
 
)    __atomic_store_n((x), (y), __ATOMIC_RELAXED)

Sets an atomic 32-bit integer to a new value.

Parameters
xPointer to the atomic32_t to be set.
yNew 32-bit signed integer value to be set in x.

Definition at line 318 of file thread.h.

◆ atomic_set_64

#define atomic_set_64 (   x,
 
)    __atomic_store_n((x), (y), __ATOMIC_RELAXED)

Sets an atomic 64-bit integer to a new value.

Parameters
xPointer to the atomic64_t to be set.
yNew 64-bit signed integer value to be set in x.

Definition at line 323 of file thread.h.

◆ curthread

#define curthread   GetCurrentThread()
Returns
The calling thread's thread_t handle.
See also
thread_t
curthread_id

Definition at line 468 of file thread.h.

◆ curthread_id

#define curthread_id   GetCurrentThreadId()
Returns
The calling thread's thread_id_t.
See also
thread_id_t
curthread

Definition at line 467 of file thread.h.

◆ thread_create

#define thread_create (   thrp,
  start_proc,
  arg 
)
Value:
lacf_thread_create((thrp), (start_proc), (arg), \
log_basename(__FILE__), __LINE__)
#define log_basename(f)
Definition log.h:89
static bool_t lacf_thread_create(thread_t *thrp, void(*proc)(void *), void *arg, const char *filename, int linenum)
Definition thread.h:803

Creates a new thread.

Parameters
thrpReturn pointer to a thread_t, which will be filled with the thread handle if the thread was started successfully.
procStart function, which will be called by the new thread. When this function returns, the thread terminates.
argOptional pointer, which will be passed to the start function in its first argument.
Returns
B_TRUE if starting the thread was successful, B_FALSE otherwise. You MUST check the return value and not just assume that starting the thread is always succesful.

Definition at line 189 of file thread.h.

◆ THREAD_PRIO_HIGH

#define THREAD_PRIO_HIGH   THREAD_PRIORITY_ABOVE_NORMAL

Higher than normal thread scheduling priority.

See also
thread_set_prio()

Definition at line 991 of file thread.h.

◆ THREAD_PRIO_IDLE

#define THREAD_PRIO_IDLE   THREAD_PRIORITY_IDLE

Minimum thread scheduling priority - only use for threads which can can accept very long periods of not getting CPU time if the CPU is busy.

See also
thread_set_prio()

Definition at line 970 of file thread.h.

◆ THREAD_PRIO_LOW

#define THREAD_PRIO_LOW   THREAD_PRIORITY_BELOW_NORMAL

Reduced thread scheduling priority, below normal priority.

See also
thread_set_prio()

Definition at line 980 of file thread.h.

◆ THREAD_PRIO_NORM

#define THREAD_PRIO_NORM   THREAD_PRIORITY_NORMAL

Normal thread scheduling priority. This is the default for newly created threads.

See also
thread_set_prio()

Definition at line 986 of file thread.h.

◆ THREAD_PRIO_RT

#define THREAD_PRIO_RT   THREAD_PRIORITY_TIME_CRITICAL

Highest possible thread scheduling priority. Be very careful when using this, as if your thread does a lot of work at this priority, it can starve other threads of CPU time. Use sparingly and only for threads with a known bounded execution time between yields.

See also
thread_set_prio()

Definition at line 1004 of file thread.h.

◆ THREAD_PRIO_VERY_HIGH

#define THREAD_PRIO_VERY_HIGH   THREAD_PRIORITY_HIGHEST

Very high thread scheduling priority.

See also
thread_set_prio()

Definition at line 996 of file thread.h.

◆ THREAD_PRIO_VERY_LOW

#define THREAD_PRIO_VERY_LOW   THREAD_PRIORITY_LOWEST

Very low thread scheduling priority.

See also
thread_set_prio()

Definition at line 975 of file thread.h.

◆ VERIFY_MUTEX_HELD

#define VERIFY_MUTEX_HELD (   mtx)    (void)1

Verifies that a mutex_t is held by the calling thread. If it isn't, this trips an assertion failure (as if a VERIFY() check had failed).

See also
VERIFY_MUTEX_NOT_HELD()
ASSERT_MUTEX_HELD()

Definition at line 562 of file thread.h.

◆ VERIFY_MUTEX_NOT_HELD

#define VERIFY_MUTEX_NOT_HELD (   mtx)    (void)1

The opposite of VERIFY_MUTEX_HELD(). Due to varying platform support for checking mutex ownership, this cannot be done using a simple stacking such as VERIFY(!MUTEX_HELD(mtx)), as the inner macro wouldn't know what the desired output was and would thus be error-prone when used.

See also
VERIFY_MUTEX_HELD()
ASSERT_MUTEX_NOT_HELD()

Definition at line 563 of file thread.h.

Typedef Documentation

◆ condvar_t

typedef CONDITION_VARIABLE condvar_t

A condition variable is an object which can be waited on by any number of threads, and signalled by another thread, to notify the waiting threads that a certain condition has been met and/or that the waiting threads' attention is required. A condition variable is always used in conjuction with a mutex. The waiting thread(s) first acquire a mutex to protect a critical section of code. They then wait on a condition variable, which also atomatically relinquishes the mutex, allowing another thread to come acquire the lock and signal the condition. Once signalled, the waiting thread wakes up and atomically acquires the lock (once the signalling thread has relinquished it).

Use cv_init() to initialize a condition variable. Once initialized, the object must be destroyed using cv_destroy(). Waiting on the condition variable can be accomplished using either cv_wait() or cv_timedwait(). Signalling the condition is performed using either cv_signal() or cv_broadcast().

Example of how to use a condvar_t:

mutex_t my_lock;
condvar_t my_cv;
mutex_init(&my_lock); // create a lock to control the CV
cv_init(&my_cv); // create the condition variable
// thread that's going to signal the condition:
mutex_enter(&my_lock); // grab the lock
// ... set up some resource that others might be waiting on ...
cv_broadcast(&my_lock); // wake up all waiters
mutex_exit(&my_lock); // release the lock
// thread that's going to wait on the condition:
mutex_enter(&my_lock); // grab the lock
while (!condition_met())
cv_wait(&my_cv, &my_lock); // wait for the CV
// to be signalled
// ... condition fulfilled, use the resource ...
mutex_exit(&my_lock); // release the lock
See also
cv_init()
cv_destroy()
cv_wait()
cv_timedwait()
cv_signal()
cv_broadcast()

Definition at line 465 of file thread.h.

◆ thread_id_t

typedef DWORD thread_id_t

Thread ID object. This gets returned by macros such as curthread_id. Certain operations require the thread ID, instead of the handle, so this type encapsulates that detail on platforms where there is a distinction between thread handles and IDs (Windows).

See also
curthread_id

Definition at line 401 of file thread.h.

◆ thread_t

typedef HANDLE thread_t

Thread handle object. This gets initialized with a thread handle by a call to thread_create() and is consumed by a variety of other thread-related operations (such as thread_destroy()).

See also
thread_create()

Definition at line 393 of file thread.h.

Function Documentation

◆ _lacf_thread_list_add()

static void _lacf_thread_list_add ( lacf_thread_info_t ti)
static
Note
Internal. Do not call directly.

Definition at line 611 of file thread.h.

◆ _lacf_thread_list_fini()

static void _lacf_thread_list_fini ( void  )
static
Note
Internal. Do not call directly.

Definition at line 592 of file thread.h.

◆ _lacf_thread_list_init()

static void _lacf_thread_list_init ( void  )
static
Note
Internal. Do not call directly.

Definition at line 578 of file thread.h.

◆ _lacf_thread_list_remove()

static void _lacf_thread_list_remove ( lacf_thread_info_t ti)
static
Note
Internal. Do not call directly.

Definition at line 624 of file thread.h.

◆ cv_broadcast()

static void cv_broadcast ( condvar_t cv)
static

Signals a condition variable to ALL threads waiting on that condition variable (either using cv_wait() or cv_timedwait()). The threads will wake up (in an unpredictable order), and re-acquire the mutex associated with their cv_wait() or cv_timedwait() call.

Definition at line 960 of file thread.h.

◆ cv_destroy()

static void cv_destroy ( condvar_t cv)
static

Destroys a condition variable which has been previously initialized using cv_init().

Definition at line 936 of file thread.h.

◆ cv_init()

static void cv_init ( condvar_t cv)
static

Initializes a condition variable. Once initialized, a condition variable MUST be destroyed using cv_destroy().

See also
cv_destroy()
cv_wait()
cv_timedwait()

Definition at line 926 of file thread.h.

◆ cv_signal()

static void cv_signal ( condvar_t cv)
static

Signals a condition variable to a single waiting thread. If there are multiple threads currently blocked waiting on the condition variable (either using cv_wait() or cv_timedwait()), only ONE of the threads is signalled (which one is unpredictable).

Definition at line 948 of file thread.h.

◆ cv_timedwait()

static int cv_timedwait ( condvar_t cv,
mutex_t mtx,
uint64_t  limit 
)
static

Blocks the calling thread until the condition variable is signalled, or until a timeout limit is reached.

Parameters
cvThe condition variable to wait on.
mtxA mutex_t which MUST be currently held by the calling thread. The calling thread atomically relinquishes this mutex and starts monitoring the condition variable. Once the condition is signalled, the thread atomically wakes up and acquires the mutex again, so that when cv_wait() returns, the lock is acquired again by only the calling thread.
limitA deadline in microseconds, by which time the thread will wake up, regardless if the condition has been signalled or not. The limit must be calculated from the time value as returned by the microclock() function.
Returns
If the condition has been signalled before the timeout expired, this function returns zero. Please note that re-acquiring the mutex might extend beyond this time, so don't depend on the return value indicating a hard condition of the timeout limit not having been exceeded.
If the timeout has been reached without the condition becoming signalled, this function returns ETIMEDOUT. If an error occurred, this function returns -1. In both cases, the mutex is re-acquired before returning.

Definition at line 898 of file thread.h.

◆ cv_wait()

static void cv_wait ( condvar_t cv,
mutex_t mtx 
)
static

Blocks the calling thread until the condition variable is signalled.

Parameters
cvThe condition variable to wait on.
mtxA mutex_t which MUST be currently held by the calling thread. The calling thread atomically relinquishes this mutex and starts monitoring the condition variable. Once the condition is signalled, the thread atomically wakes up and acquires the mutex again, so that when cv_wait() returns, the lock is acquired again by only the calling thread.

Definition at line 868 of file thread.h.

◆ lacf_mask_sigpipe()

void lacf_mask_sigpipe ( void  )

Configures the calling thread to block SIGPIPE signals on macOS and Linux. Does nothing on Windows.

Definition at line 35 of file worker.c.

◆ lacf_thread_create()

static bool_t lacf_thread_create ( thread_t thrp,
void(*)(void *)  proc,
void *  arg,
const char *  filename,
int  linenum 
)
static

Implementation of thread_create(). Do not call directly, use the thread_create() macro.

See also
thread_create()

Definition at line 803 of file thread.h.

◆ lacf_thread_start_routine()

DWORD lacf_thread_start_routine ( void *  arg)
Note
Internal. Do not call directly.

Definition at line 40 of file thread.c.

◆ lacf_threads_fini()

static void lacf_threads_fini ( void  )
static

Checks to see if all threads that were created using thread_create() have been properly disposed of. If not, this trips an assertion failure and lists all threads (including filenames and line numbers where they have been spawned) that weren't properly stopped. You should call this just as your plugin is exiting, to check for leaked threads.

Definition at line 642 of file thread.h.

◆ mutex_destroy()

static void mutex_destroy ( mutex_t mtx)
static

Destroys mutex_t object previously initialized by a call to mutex_init().

See also
mutex_init()

Definition at line 499 of file thread.h.

◆ mutex_enter()

static void mutex_enter ( mutex_t mtx)
static

Acquires a mutex, which has previously been initialized using mutex_init(). If the mutex cannot be acquired exclusively by the calling thread, the thread blocks until it can be acquired. Once acquired, the mutex MUST be relinquished by a call to mutex_exit().

Note
mutex_enter() and mutex_exit() support recursive locking, so once a thread acquires a mutex, it can re-acquire it in nested subroutines without risk of deadlock:
...
// subroutine acquires the lock again - this is safe to do
...
mutex_exit(mtx);
...
mutex_exit(mtx);
All calls to mutex_enter() must be balanced by matching calls to mutex_exit() before the mutex is finally completely relinquished.
See also
mutex_exit()

Definition at line 530 of file thread.h.

◆ mutex_exit()

static void mutex_exit ( mutex_t mtx)
static

Relinquishes a mutex previously acquired by a call to mutex_enter().

Note
mutex_enter() and mutex_exit() support recursive locking, so once a thread acquires a mutex, it can re-acquire it in nested subroutines without risk of deadlock:
...
// subroutine acquires the lock again - this is safe to do
...
mutex_exit(mtx);
...
mutex_exit(mtx);
All calls to mutex_enter() must be balanced by matching calls to mutex_exit() before the mutex is finally completely relinquished.
See also
mutex_enter()

Definition at line 556 of file thread.h.

◆ mutex_init()

static void mutex_init ( mutex_t mtx)
static

Initializes a new mutex_t object. The mutex MUST be destroyed using mutex_destroy() to avoid leaking memory.

See also
mutex_destroy()

Definition at line 488 of file thread.h.

◆ rwmutex_can_enter_impl()

static bool_t rwmutex_can_enter_impl ( const rwmutex_t rw,
const rwlock_waiter_t wt_self 
)
static
Note
Internal. Do not call directly.

Definition at line 1100 of file thread.h.

◆ rwmutex_destroy()

static void rwmutex_destroy ( rwmutex_t rw)
static

Destroys an rwmutex_t that was previously initialized rwmutex_init().

See also
rwmutex_init()

Definition at line 1075 of file thread.h.

◆ rwmutex_enter()

static void rwmutex_enter ( rwmutex_t rw,
bool_t  write 
)
static

Acquires an rwmutex_t in either read or write mode. The lock can be simultaneously held in read mode by any number of threads. However, in write mode, the lock can only be held by a single thread. If the lock cannot be acquired immediately, the calling thread is blocked until successful.

Note
rwmutex_t does NOT support recursion. An attempt to acquire the lock multiple times from the same thread can cause an assertion failure or even deadlock.

Locking Order

rwmutex_t implements deterministic locking order. If the lock is currently held by one or more readers and another thread attempts to acquire the lock in write (exclusive) mode, the calling thread is blocked until all existing read locks are relinquished. Furthermore, any newly arriving locking attempts will queue up "behind" any preceding attempts and block. The queue of pending locks is then cleared in order of arrival. Writers can only enter one by one, while a "batched up" group of readers can enter simultaneously. This prevents lock starvation of writers in the presence of a large number of readers and vice versa.

Parameters
rwThe mutex to acquire.
writeSets whether the lock should be acquired in write (write=B_TRUE) or read (write=B_FALSE) mode.

Definition at line 1143 of file thread.h.

◆ rwmutex_exit()

static void rwmutex_exit ( rwmutex_t rw)
static

Relinquishes a previously acquired read- or write lock of an rwmutex_t.

Definition at line 1200 of file thread.h.

◆ rwmutex_held_write()

static bool_t rwmutex_held_write ( rwmutex_t rw)
static
Returns
B_TRUE if the rwmutex_t is currently held by the calling thread in write mode, B_FALSE otherwise.
Note
This doesn't determine whether the calling thread is currently holding the rwmutex_t in read mode. Read mode acquisitions of the rwmutex_t do not retain any ownership information.

Definition at line 1091 of file thread.h.

◆ rwmutex_init()

static void rwmutex_init ( rwmutex_t rw)
static

Initializes a new rwmutex_t. The mutex must be destroyed using rwmutex_destroy().

See also
rwmutex_destroy()

Definition at line 1061 of file thread.h.

◆ rwmutex_upgrade()

static void rwmutex_upgrade ( rwmutex_t rw)
static

"Upgrades" a currently held read lock into a write lock.

Definition at line 1218 of file thread.h.

◆ thread_equal()

static bool_t thread_equal ( thread_id_t  tid1,
thread_id_t  tid2 
)
static

Definition at line 477 of file thread.h.

◆ thread_join()

static void thread_join ( thread_t thrp)
static

Waits for a thread to exit. After this function returns, the passed thread has exited and its resources can be safely disposed of.

Parameters
thrpA pointer to a thread_t identifying the thread for which to wait.
Note
This function doesn't cause the target thread to exit, it only blocks the calling thread until the target thread has exited. You should notify the target thread using other means to exit before calling thread_join().

Definition at line 836 of file thread.h.

◆ thread_set_name()

static void thread_set_name ( const char *  name)
static

Sets the name of the calling thread. This is useful for debugging purposes, since the thread name is easily visible in a debugger or process analysis tool.

Note
This function is only supported on macOS and Linux. Furthermore, on Linux, names longer than 16 bytes (including the terminating NUL character) will be truncated to 16 bytes. On Windows, calling this function does nothing.

Definition at line 852 of file thread.h.

◆ thread_set_prio()

static void thread_set_prio ( thread_t  thr,
int  prio 
)
static

Sets the scheduling priority of a thread. The exact implementation is platform dependant:

  • On Linux, this calls pthread_setschedparam() with a policy of SCHED_OTHER.
  • On macOS, due to a bug in the thread schedling behavior under Rosetta x86 emulation, thread scheduling is disabled.
  • On Windows, this calls SetThreadPriority().
Parameters
prioMust be one of the THREAD_PRIO_* constants.

Definition at line 1017 of file thread.h.

Variable Documentation

◆ lacf_thread_list

list_t lacf_thread_list
extern

Definition at line 23 of file thread.c.

◆ lacf_thread_list_inited

bool_t lacf_thread_list_inited
extern

Definition at line 21 of file thread.c.

◆ lacf_thread_list_lock

mutex_t lacf_thread_list_lock
extern

Definition at line 22 of file thread.c.