[ English | 简体中文 ]
Thread API
openvela provides POSIX-compatible thread (pthread) interfaces, supporting thread creation, synchronization, and attribute management.
Header file: #include <pthread.h>
openvela Implementation Notes
openvela's pthread implementation is based on the NuttX RTOS kernel and differs from the standard Linux implementation in the following ways:
pthread_tispid_t: In openvela, the thread ID underlying type ispid_t(process ID), and can be passed directly to system calls such askill().- No process isolation: openvela does not support Linux-style processes; all threads run in the same address space. The
PTHREAD_PROCESS_SHAREDattribute can be set but behaves the same asPTHREAD_PROCESS_PRIVATE. - Fixed contention scope: Only
PTHREAD_SCOPE_SYSTEMis supported;PTHREAD_SCOPE_PROCESSreturnsENOTSUP. - Limited
fork()support: Thepthread_atfork()interface exists, butfork()may be unavailable in an RTOS environment; it is mainly for POSIX compatibility. - Conditional compilation dependencies: Some features require specific configuration options:
CONFIG_SMP: CPU affinity interfaces (pthread_setaffinity_np, etc.)CONFIG_PRIORITY_INHERITANCE: Priority inheritance protocol (PTHREAD_PRIO_INHERIT)CONFIG_PRIORITY_PROTECT: Priority ceiling protection (PTHREAD_PRIO_PROTECT,prioceiling-related interfaces)CONFIG_RR_INTERVAL > 0:SCHED_RRscheduling policyCONFIG_SCHED_SPORADIC:SCHED_SPORADICscheduling policy
Thread Creation and Management
pthread_create
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
pthread_startroutine_t start_routine, pthread_addr_t arg);
Type notes:
pthread_startroutine_tis equivalent tovoid *(*)(void *), andpthread_addr_tis equivalent tovoid *; both are NuttX type aliases.
Creates a new thread and makes it runnable. The new thread begins execution from the start_routine function, which receives arg as its sole argument. The thread attribute object attr specifies various thread attributes such as stack size, scheduling policy, and priority.
If attr is NULL, the thread is created with default attributes. By default, threads are joinable with a default stack size and scheduling policy.
Parameters:
threadPointer to apthread_tin which the new thread's ID is stored on success.attrPointer to a thread attribute object. IfNULL, default attributes are used (stack sizePTHREAD_STACK_DEFAULT, scheduling policySCHED_OTHER, joinable).start_routineThread entry function with signaturevoid *(*)(void *). The new thread starts from this function.argArgument passed to the entry function. To pass multiple arguments, pass a pointer to a struct.
Returns:
Returns 0 on success, or an error code on failure:
EAGAINInsufficient system resources to create a new thread, or the system thread count limit has been reached.EINVALSettings inattrare invalid.EPERMNo permission to set the specified scheduling policy or parameters.
Notes:
- The new thread shares the same address space, file descriptors, and signal handling as the calling thread.
- If the thread is created with
PTHREAD_CREATE_DETACHED, resources are released automatically upon termination, without needingpthread_join(). - The thread becomes schedulable immediately after creation; creation order does not guarantee execution order.
- The thread's return value can be obtained via
pthread_join(), or returned explicitly viapthread_exit(). - Ensure arguments passed to the thread remain valid throughout the thread's execution; avoid passing the address of stack-local variables.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_exit
void pthread_exit(void *exit_value);
Terminates the calling thread and returns a value that other threads can retrieve via pthread_join(). This function does not return to the caller.
Calling pthread_exit() is equivalent to returning from the thread entry function but can be called from any function invoked by the thread. On termination, the following cleanup actions are performed:
- Cleanup functions registered via
pthread_cleanup_push()are called (in reverse registration order). - Destructors for thread-specific data are called (for every non-
NULLthread-specific data key). - If the thread is joinable, the thread ID and return value are retained until another thread calls
pthread_join(). - If the thread is detached, all resources are released immediately.
Parameters:
exit_valueThread return value, an untyped pointer that can carry the address of arbitrary data.pthread_join()on this thread can obtain this value. If the thread is canceled, the return value isPTHREAD_CANCELED.
Returns:
This function does not return. After calling, the calling thread terminates.
Notes:
- Do not call
pthread_exit()inmain(); it terminates the main thread but not the process, which may orphan other threads. - If the thread is detached,
exit_valueis ignored, because no thread can obtain it viapthread_join(). - Thread termination does not automatically close open file descriptors or release allocated memory, which are shared by the whole process.
- Returning from the thread entry function implicitly calls
pthread_exit()with the return value as the exit value. - If the thread holds mutexes, release them before calling
pthread_exit(), otherwise deadlock may occur.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_join
int pthread_join(pthread_t thread, pthread_addr_t *value);
Type notes:
pthread_addr_tis equivalent tovoid *, a NuttX type alias.
Blocks the calling thread until the specified thread terminates. If the thread has already terminated, pthread_join() returns immediately. On success, the target thread is "joined" and its resources are reclaimed.
Each joinable thread can be joined only once. Joining a thread that has already been joined or detached causes undefined behavior. A thread cannot join itself; doing so causes deadlock.
Parameters:
threadID of the thread to wait for. Must be joinable; cannot be a detached thread or a thread that has already been joined.valuePointer to a pointer that receives the thread's return value. If non-NULL, the target thread's return value (frompthread_exit()or the entry function return) is stored in*value. If the thread was canceled,*valueis set toPTHREAD_CANCELED. PassNULLif the return value is not needed.
Returns:
Returns 0 on success, or an error code on failure:
EDEADLKA deadlock was detected (e.g., a thread attempting to join itself), orthreadspecifies a thread that is waiting to join the calling thread.EINVALthreadis not joinable, or another thread is already waiting to join it.ESRCHNo thread with IDthreadcan be found.
Notes:
pthread_join()blocks the caller until the target thread terminates. If the target has already terminated, the call returns immediately.- After joining, the thread ID is reclaimed and should not be used again.
- If multiple threads attempt to join the same thread simultaneously, the behavior is undefined.
- Failing to join a joinable thread leaks resources (similar to a memory leak); the thread's resources are not reclaimed.
- For threads whose return value is not needed, set them detached at creation or call
pthread_detach()afterward. - In openvela, the thread ID is actually a process ID (
pid_t) and can be used with other system calls.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_detach
int pthread_detach(pthread_t thread);
Marks the specified thread as detached. A detached thread releases all resources automatically upon termination, without needing another thread to call pthread_join(). Once detached, the thread cannot be joined, and its return value cannot be retrieved.
A thread can be made detached in two ways:
- By setting
PTHREAD_CREATE_DETACHEDin the attribute object at creation. - By calling
pthread_detach()after creation.
A thread can also detach itself via pthread_detach(pthread_self()).
Parameters:
threadID of the thread to detach. Can be another thread's ID or the calling thread's own ID (viapthread_self()).
Returns:
Returns 0 on success, or an error code on failure:
EINVALthreadis not joinable (possibly already detached).ESRCHNo thread with IDthreadcan be found.
Notes:
- After detaching,
pthread_join()cannot be called for this thread; doing so returns an error. - Detached state is irreversible; a detached thread cannot become joinable again.
- For threads whose return value or completion is not needed, set them detached to avoid resource leaks.
- Detaching does not affect thread execution, only how resources are reclaimed after termination.
- Calling
pthread_detach()again on an already-detached thread returnsEINVAL. - The main thread can be detached, but this is usually not good practice because main thread termination ends the entire process.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_cancel
int pthread_cancel(pthread_t thread);
Sends a cancellation request to the specified thread. Whether the thread responds depends on its cancel state (set via pthread_setcancelstate()) and cancel type (set via pthread_setcanceltype()).
If the cancellation request is delivered successfully, the target thread's state and type determine when and how the cancellation is processed:
- If the cancel state is
PTHREAD_CANCEL_DISABLE, the request is pending until the state becomesPTHREAD_CANCEL_ENABLE. - If the state is
PTHREAD_CANCEL_ENABLEand the type isPTHREAD_CANCEL_DEFERRED, cancellation occurs at the next cancellation point. - If the type is
PTHREAD_CANCEL_ASYNCHRONOUS, cancellation may occur immediately (but may also be deferred).
Parameters:
threadID of the thread to cancel. Cannot cancel self (usepthread_exit()).
Returns:
Returns 0 on success, or an error code on failure:
ESRCHNo thread with IDthreadcan be found.
Notes:
pthread_cancel()only sends a request; it does not wait for the thread to actually terminate.- A canceled thread's exit value is
PTHREAD_CANCELED. - Asynchronous cancellation (
PTHREAD_CANCEL_ASYNCHRONOUS) is dangerous and should be used only in specific cases, because the thread may be canceled at any point, possibly causing resource leaks or data inconsistency. - Deferred cancellation (
PTHREAD_CANCEL_DEFERRED, the default) is safer; the thread is canceled only at cancellation points, includingpthread_testcancel(),pthread_join(),pthread_cond_wait(), and other blocking calls. - Cleanup handlers (registered via
pthread_cleanup_push()) and thread-specific data destructors are run when a thread is canceled. - If the thread holds locks or other resources, use cleanup handlers to ensure proper release.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_setcancelstate
int pthread_setcancelstate(int state, int *oldstate);
Sets the calling thread's cancel state, controlling whether it can be canceled.
Parameters:
stateNew cancel state. Valid values:PTHREAD_CANCEL_ENABLECancellation enabled (default). The thread can respond to cancellation requests.PTHREAD_CANCEL_DISABLECancellation disabled. Requests are held pending until the state becomes enabled.
oldstateIf non-NULL, stores the previous cancel state. PassNULLif not needed.
Returns:
Returns 0 on success, or an error code on failure:
EINVALstateis not a valid cancel state.
Notes:
- Newly created threads default to
PTHREAD_CANCEL_ENABLE. - Disabling cancellation does not discard pending requests; it only defers processing.
- Even with cancellation disabled, the thread can still terminate via
pthread_exit(). - When executing critical sections (such as resource allocation and initialization), temporarily disable cancellation and re-enable it when done.
- The cancel state is thread-local; each thread has its own independent state.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_setcanceltype
int pthread_setcanceltype(int type, int *oldtype);
Sets the calling thread's cancel type, controlling how it responds to cancellation requests.
Parameters:
typeNew cancel type. Valid values:PTHREAD_CANCEL_DEFERREDDeferred cancellation (default). Requests are handled at the next cancellation point. Cancellation points include blocking functions such aspthread_testcancel(),pthread_join(),pthread_cond_wait(),pthread_cond_timedwait(), andsem_wait().PTHREAD_CANCEL_ASYNCHRONOUSAsynchronous cancellation. The thread may be canceled at any time (actual behavior is implementation-dependent). This mode is dangerous and should be avoided.
oldtypeIf non-NULL, stores the previous cancel type. PassNULLif not needed.
Returns:
Returns 0 on success, or an error code on failure:
EINVALtypeis not a valid cancel type.
Notes:
- Newly created threads default to
PTHREAD_CANCEL_DEFERRED. - Deferred cancellation is the recommended type because it only responds at well-defined cancellation points, ensuring the thread is in a known state.
- Asynchronous cancellation may interrupt the thread at any instruction, possibly causing resource leaks, data corruption, or undefined behavior. Use it only when you are sure the thread code is async-cancel-safe.
- In asynchronous cancellation, do not call non-async-cancel-safe functions, including most library functions.
- The cancel type is thread-local.
- Even if asynchronous cancel is set, the implementation may treat it as deferred.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_testcancel
void pthread_testcancel(void);
Creates a cancellation point. If there is a pending cancellation request and the cancel state is enabled, the thread is canceled and does not return. This explicitly checks and responds to cancellation requests.
Cancellation points are where a thread can respond to cancellation requests. POSIX defines some functions (such as pthread_join() and sem_wait()) as required cancellation points, and pthread_testcancel() allows creating one at any point.
Parameters:
None.
Returns:
If there is no pending cancellation request, the function returns normally. If there is one, the function does not return and the thread is canceled.
Notes:
- If the cancel state is
PTHREAD_CANCEL_DISABLE,pthread_testcancel()has no effect and returns directly. - Typically used in long-running, computation-intensive code to provide opportunities to respond to cancellation requests.
- Call
pthread_testcancel()periodically at appropriate locations (e.g., inside loops) to ensure timely response. - If the thread is canceled, cleanup handlers and thread-specific data destructors run.
- Calling too frequently may impact performance; call at logically appropriate locations.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_self
pthread_t pthread_self(void);
Gets the calling thread's ID. The ID uniquely identifies a thread within a process and can be used with functions such as pthread_join(), pthread_detach(), and pthread_equal().
In openvela, pthread_t is actually a pid_t, i.e., the thread ID is the same as the process ID.
Parameters:
None.
Returns:
Returns the calling thread's ID. This function always succeeds.
Notes:
- Thread IDs remain constant for the lifetime of the thread.
- After termination and joining, thread IDs may be reused.
- Do not rely on the numeric value or order of thread IDs; they are opaque identifiers.
pthread_detach(pthread_self())can be used to detach the current thread.- In openvela, thread IDs can be used with system calls such as sending signals.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_equal
int pthread_equal(pthread_t t1, pthread_t t2);
Compares two thread IDs for equality. Because the internal representation of a thread ID may be a complex data structure, POSIX requires this function instead of direct == comparison.
Parameters:
t1First thread ID.t2Second thread ID.
Returns:
Returns nonzero if the two thread IDs are equal; 0 otherwise.
Notes:
- In openvela,
pthread_tis a simple integer type (pid_t) and can be compared directly with==; however, for portability, usepthread_equal(). - Terminated thread IDs may be reused, so ID uniqueness across thread lifetimes should not be assumed.
- Commonly used to check whether a thread ID is the current thread:
pthread_equal(thread_id, pthread_self()).
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_yield
void pthread_yield(void);
Voluntarily yields the processor to allow other threads to run. This is an optimization hint; actual behavior depends on the scheduling policy.
After calling pthread_yield(), the calling thread is placed at the end of its priority queue, and the scheduler selects the next runnable thread. If no other ready thread of equal or higher priority exists, the calling thread may continue immediately.
Parameters:
None.
Returns:
No return value.
Notes:
- This is a non-standard extension interface, but is available on many systems (Linux, BSD, etc.).
- In POSIX, use
sched_yield()instead. - Suitable for cooperative multitasking, where a thread voluntarily yields to others.
- Do not rely on
pthread_yield()to solve synchronization problems; use appropriate synchronization primitives (mutexes, condition variables). - Overuse may hurt performance; use only when clearly needed.
- In real-time systems, the behavior depends on the scheduling policy (FIFO, RR, etc.).
POSIX Compatibility: Compatible extension interface (non-POSIX standard, but widely supported).
pthread_once
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
Ensures that the initialization function init_routine is called only once during the process lifetime, regardless of how many threads call pthread_once(). This is a thread-safe one-time initialization mechanism, commonly used for lazy initialization of global resources.
once_control must be a static or global variable initialized with PTHREAD_ONCE_INIT. Multiple threads can call pthread_once() simultaneously, but init_routine runs only once; other threads block until initialization completes.
Parameters:
once_controlControl variable that tracks initialization state. Must be initialized withPTHREAD_ONCE_INIT(e.g.,pthread_once_t once = PTHREAD_ONCE_INIT;).init_routineInitialization function with no parameters and no return value. Called only once during the process lifetime.
Returns:
Returns 0 on success, or an error code on failure:
EINVALonce_controlorinit_routineisNULL.
Notes:
pthread_once()is thread-safe and can be called simultaneously from multiple threads.- The init routine should complete quickly to avoid blocking other threads waiting for initialization.
- If the init routine calls
pthread_once()with the sameonce_control, behavior is undefined (possible deadlock). - The init routine should not call
pthread_exit()or be canceled; otherwise initialization is considered incomplete, and the next call runs the init routine again. - Commonly used for singletons, global resource initialization, etc.
once_controlshould not be modified directly; only viapthread_once().
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_atfork
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
Registers handlers to be executed around fork() calls. These handlers address issues that fork() introduces in multi-threaded environments, particularly lock state consistency.
When fork() is called, handlers are executed in the following order:
- Before
fork(), allpreparehandlers are called in the parent process (in reverse registration order). fork()creates the child process.- All
childhandlers are called in the child process (in registration order). - All
parenthandlers are called in the parent process (in registration order).
Parameters:
prepareCalled in the parent beforefork(). Typically acquires all locks to ensure a consistent state. May beNULL.parentCalled in the parent afterfork(). Typically releases locks acquired inprepare. May beNULL.childCalled in the child afterfork(). Typically re-initializes lock state and other resources. May beNULL.
Returns:
Returns 0 on success, or an error code on failure:
ENOMEMInsufficient memory to record the handlers.
Notes:
- Multiple calls to
pthread_atfork()may register multiple handler groups. preparehandlers run in reverse registration order;parentandchildhandlers run in registration order.- Using
fork()in multithreaded programs is dangerous: the child inherits only the calling thread, but other threads' lock states are inherited, possibly causing deadlock. - Handlers should run quickly and avoid calling functions that may block or use locks.
- In the child, only async-signal-safe functions should be called (such as the
exec()family). - As an RTOS, openvela may have limited or no
fork()support; this interface is mainly for compatibility.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Thread Attributes
pthread_attr_init
int pthread_attr_init(pthread_attr_t *attr);
Initializes a thread attribute object to default values. Attribute objects specify various thread attributes at creation time, such as stack size, scheduling policy, priority, and detach state.
After initialization, the attribute object contains the following defaults:
- Detach state:
PTHREAD_CREATE_JOINABLE - Stack size:
PTHREAD_STACK_DEFAULT(system default) - Scheduling policy:
SCHED_OTHER(or the system default) - Scheduling inheritance:
PTHREAD_INHERIT_SCHED - Scope:
PTHREAD_SCOPE_SYSTEM
Parameters:
attrPointer to the attribute object to initialize.
Returns:
Returns 0 on success, or an error code on failure:
ENOMEMInsufficient memory to initialize the attribute object.
Notes:
- After initialization, individual attributes can be modified via the
pthread_attr_set*()functions. - The same attribute object can be used to create multiple threads.
- When no longer needed, destroy the attribute object via
pthread_attr_destroy()to release resources. - Modifications to the attribute object do not affect threads already created; they only affect subsequent threads created using this object.
- In openvela, the attribute object is a simple struct that does not involve dynamic memory allocation.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_destroy
int pthread_attr_destroy(pthread_attr_t *attr);
Destroys a thread attribute object, releasing its resources. A destroyed attribute object cannot be used again unless re-initialized.
Parameters:
attrPointer to the attribute object to destroy.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattris not a valid attribute object.
Notes:
- Destroying an attribute object does not affect threads already created using it.
- A destroyed attribute object can be re-initialized via
pthread_attr_init()and reused. - In openvela, attribute objects typically do not involve dynamic memory; this function is mainly for POSIX compatibility.
- Always pair
pthread_attr_init()withpthread_attr_destroy()following resource-management best practices.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_setdetachstate
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
Sets the detach state in a thread attribute object. The detach state determines how resources are reclaimed after the thread terminates.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.detachstateDetach state. Valid values:PTHREAD_CREATE_JOINABLEJoinable (default); requires another thread to callpthread_join()to reclaim resources.PTHREAD_CREATE_DETACHEDDetached; resources are released automatically upon termination.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, ordetachstateis not a valid value.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_getdetachstate
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
Gets the detach state from a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.detachstatePointer to an integer variable for storing the detach state. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrordetachstateisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_setstacksize
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
Sets the stack size in a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.stacksizeStack size (bytes). Cannot be less thanPTHREAD_STACK_MIN.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orstacksizeis less thanPTHREAD_STACK_MIN.
Notes:
- Set the stack size based on the thread's actual needs; too small may cause stack overflow.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_getstacksize
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
Gets the stack size from a thread attribute object.
Parameters:
attrPointer to the thread attribute object.stacksizePointer to asize_tfor storing the stack size. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALstacksizeisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_setstackaddr
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);
Sets the stack address in a thread attribute object. Allows the application to specify pre-allocated stack memory for the thread.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.stackaddrStarting address of the stack memory. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorstackaddrisNULL.
Notes:
- This interface is marked obsolete by POSIX; use
pthread_attr_setstack()instead, which sets both stack address and stack size. - When using a custom stack, the application is responsible for allocating and freeing the stack memory.
- Stack memory must remain valid for the thread's lifetime.
POSIX Compatibility: Compatible with the POSIX interface of the same name (obsolete).
pthread_attr_getstackaddr
int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr);
Gets the stack address from a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.stackaddrPointer to a pointer variable for storing the stack address. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorstackaddrisNULL.
Notes:
- This interface is marked obsolete by POSIX; use
pthread_attr_getstack()instead.
POSIX Compatibility: Compatible with the POSIX interface of the same name (obsolete).
pthread_attr_setstack
int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);
Sets both stack address and stack size in a thread attribute object. A combined replacement for pthread_attr_setstackaddr() and pthread_attr_setstacksize().
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.stackaddrStarting address of the stack memory. Cannot beNULL.stacksizeStack size (bytes). Cannot be less thanPTHREAD_STACK_MIN.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorstackaddrisNULL, orstacksizeis less thanPTHREAD_STACK_MIN.
Notes:
- When using a custom stack, the application is responsible for allocating and freeing the memory, which must remain valid for the thread's lifetime.
- Stack size should account for local variables, function call depth, etc.
- In openvela, the value of
PTHREAD_STACK_MINdepends on system configuration.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_getstack
int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize);
Gets both stack address and stack size from a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.stackaddrPointer to a pointer variable for storing the stack address. Cannot beNULL.stacksizePointer to asize_tfor storing the stack size. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattr,stackaddr, orstacksizeisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_setguardsize
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
Sets the stack guard size in a thread attribute object. The guard region is an inaccessible memory area at the end of the stack that detects stack overflow.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.guardsizeGuard size (bytes). Setting 0 disables stack protection.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL.
Notes:
- If
pthread_attr_setstack()specifies a custom stack, the guard setting may be ignored. - The actual guard size may be rounded up by the system to a multiple of the page size.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_getguardsize
int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize);
Gets the stack guard size from a thread attribute object.
Parameters:
attrPointer to the thread attribute object.guardsizePointer to asize_tfor storing the guard size. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALguardsizeisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_setschedpolicy
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
Sets the scheduling policy in a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.policyScheduling policy. Valid values:SCHED_OTHERDefault scheduling policy.SCHED_FIFOFirst-in, first-out real-time scheduling.SCHED_RRRound-robin real-time scheduling (requiresCONFIG_RR_INTERVAL > 0).SCHED_SPORADICSporadic scheduling (requiresCONFIG_SCHED_SPORADIC).
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orpolicyis not a valid scheduling policy.
Notes:
- Availability of
SCHED_RRandSCHED_SPORADICdepends on system configuration.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_getschedpolicy
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
Gets the scheduling policy from a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.policyPointer to an integer variable for storing the scheduling policy. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorpolicyisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_setschedparam
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
Sets the scheduling parameters in a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.paramPointer to the scheduling parameter structure. Cannot beNULL. Main fields:sched_priorityThread priority.sched_ss_low_prioritySporadic scheduling low priority (requiresCONFIG_SCHED_SPORADIC).sched_ss_repl_periodSporadic scheduling replenish period.sched_ss_init_budgetSporadic scheduling initial budget.sched_ss_max_replSporadic scheduling maximum replenishments.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorparamisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_getschedparam
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
Gets the scheduling parameters from a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.paramPointer to a scheduling parameter structure for storing the result. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorparamisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_setinheritsched
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
Sets the scheduling inheritance mode in a thread attribute object. Determines whether the new thread inherits the creator's scheduling attributes or uses those explicitly specified in the attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.inheritschedInheritance mode. Valid values:PTHREAD_INHERIT_SCHEDInherit the creating thread's scheduling policy and parameters (default).PTHREAD_EXPLICIT_SCHEDUse the scheduling policy and parameters set in the attribute object.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orinheritschedis not a valid value.
Notes:
- When set to
PTHREAD_EXPLICIT_SCHED, also set the scheduling policy and parameters viapthread_attr_setschedpolicy()andpthread_attr_setschedparam().
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_getinheritsched
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched);
Gets the scheduling inheritance mode from a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.inheritschedPointer to an integer variable for storing the inheritance mode. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorinheritschedisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_setscope
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
Sets the contention scope in a thread attribute object. The contention scope defines which threads the thread competes with for resources such as CPU.
Parameters:
attrPointer to the thread attribute object.scopeContention scope. Valid values:PTHREAD_SCOPE_SYSTEMSystem-level contention; the thread competes with all threads in the system.PTHREAD_SCOPE_PROCESSProcess-level contention; the thread competes only with threads in the same process.
Returns:
Returns 0 on success, or an error code on failure:
EINVALscopeis not a valid value.ENOTSUPRequested contention scope is not supported. In openvela,PTHREAD_SCOPE_PROCESSis not supported.
Notes:
- openvela only supports
PTHREAD_SCOPE_SYSTEM, which is also the default. PassingPTHREAD_SCOPE_PROCESSreturnsENOTSUP. - In an RTOS environment, all threads naturally contend at the system level.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_getscope
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);
Gets the contention scope from a thread attribute object.
Parameters:
attrPointer to the thread attribute object.scopePointer to an integer variable for storing the contention scope.
Returns:
Returns 0 on success.
Notes:
- In openvela, always returns
PTHREAD_SCOPE_SYSTEM.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_attr_setaffinity_np
int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset);
Sets the CPU affinity mask in a thread attribute object. Threads created with this attribute are limited to running on the specified CPU set.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.cpusetsizeSize (in bytes) of thecpusetbuffer; must besizeof(cpu_set_t).cpusetPointer to the CPU set, specifying which CPUs the thread may run on. Cannot beNULL, and the set cannot be empty.
Returns:
Returns 0 on success.
Notes:
- Available only when SMP (
CONFIG_SMP) is enabled. - Unlike
pthread_setaffinity_np(), this function sets the affinity in the attribute object, and it takes effect atpthread_create(). - Use macros such as
CPU_ZERO()andCPU_SET()to manipulatecpu_set_t.
POSIX Compatibility: Compatible with the Linux extension interface (non-POSIX standard).
pthread_attr_getaffinity_np
int pthread_attr_getaffinity_np(const pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset);
Gets the CPU affinity mask from a thread attribute object.
Parameters:
attrPointer to the thread attribute object. Cannot beNULL.cpusetsizeSize (in bytes) of thecpusetbuffer; must besizeof(cpu_set_t).cpusetPointer to a CPU set for storing the affinity mask. Cannot beNULL.
Returns:
Returns 0 on success.
Notes:
- Available only when SMP (
CONFIG_SMP) is enabled.
POSIX Compatibility: Compatible with the Linux extension interface (non-POSIX standard).
Thread Scheduling
pthread_getschedparam
int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param);
Gets the scheduling policy and parameters of the specified thread.
Parameters:
threadThread ID.policyPointer to an integer variable for storing the scheduling policy. Cannot beNULL.paramPointer to a scheduling parameter structure for storing the result. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALpolicyorparamisNULL.ESRCHThe specified thread cannot be found.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_setschedparam
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);
Sets the scheduling policy and parameters of the specified thread.
Parameters:
threadThread ID.policyScheduling policy:SCHED_FIFO,SCHED_RR,SCHED_OTHER, orSCHED_SPORADIC.paramPointer to the scheduling parameter structure.
Returns:
Returns 0 on success, or an error code on failure:
EINVALInvalid argument.ESRCHThe specified thread cannot be found.EPERMNo permission to modify the scheduling parameters.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_setschedprio
int pthread_setschedprio(pthread_t thread, int prio);
Sets the priority of the specified thread without changing the scheduling policy.
Parameters:
threadThread ID.prioNew priority value.
Returns:
Returns 0 on success, or an error code on failure:
EINVALPriority value is invalid.ESRCHThe specified thread cannot be found.
Notes:
- This function modifies only the priority; the current scheduling policy and other parameters (such as sporadic scheduling parameters) are preserved.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_setaffinity_np
int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
Sets the thread's CPU affinity mask. If the thread is not currently running on a CPU specified by cpuset, it is migrated to one of them.
Parameters:
threadThread ID.cpusetsizeSize (in bytes) of thecpusetbuffer; typicallysizeof(cpu_set_t).cpusetPointer to a CPU set specifying CPUs the thread may run on.
Returns:
Returns 0 on success, or an error code on failure:
EINVALInvalid argument.ESRCHThe specified thread cannot be found.
Notes:
- Available only when SMP (
CONFIG_SMP) is enabled. - Use macros such as
CPU_ZERO()andCPU_SET()to manipulatecpu_set_t.
POSIX Compatibility: Compatible with the Linux extension interface (non-POSIX standard).
pthread_getaffinity_np
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);
Gets the thread's CPU affinity mask.
Parameters:
threadThread ID.cpusetsizeSize (in bytes) of thecpusetbuffer; typicallysizeof(cpu_set_t).cpusetPointer to a CPU set for storing the thread's affinity mask.
Returns:
Returns 0 on success, or an error code on failure:
EINVALInvalid argument.ESRCHThe specified thread cannot be found.
Notes:
- Available only when SMP (
CONFIG_SMP) is enabled.
POSIX Compatibility: Compatible with the Linux extension interface (non-POSIX standard).
pthread_setconcurrency
int pthread_setconcurrency(int new_level);
Sets the concurrency level hint. This function hints to the system the desired number of concurrent threads; the system may use it to optimize thread scheduling.
Parameters:
new_levelDesired concurrency level. 0 means let the system decide. Cannot be negative.
Returns:
Returns 0 on success, or an error code on failure:
EINVALnew_levelis negative.
Notes:
- This function is merely a hint; the system does not guarantee the actual concurrency level matches the set value.
- In openvela, this value is stored in a global variable and does not affect actual scheduling behavior.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_getconcurrency
int pthread_getconcurrency(void);
Gets the current concurrency level hint value.
Parameters:
None.
Returns:
Returns the value previously set via pthread_setconcurrency(). Returns 0 if never set.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Mutexes
pthread_mutex_init
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
Initializes a mutex. Mutexes protect shared resources, ensuring that only one thread accesses the protected critical section at a time.
If attr is NULL, the mutex uses default attributes: type PTHREAD_MUTEX_NORMAL, no priority inheritance or protection protocol, and process-private.
A mutex can also be initialized statically with PTHREAD_MUTEX_INITIALIZER:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
Parameters:
mutexPointer to the mutex object to initialize.attrPointer to a mutex attribute object. IfNULL, default attributes are used. Attributes include mutex type (normal, recursive, errorcheck), priority protocol, robustness, and more.
Returns:
Returns 0 on success, or an error code on failure:
EAGAINInsufficient system resources to initialize the mutex.ENOMEMInsufficient memory.EPERMCaller lacks permission.EINVALInvalid attribute values inattr.
Notes:
- After initialization, the mutex is unlocked.
- Do not re-initialize an already-initialized mutex; this causes undefined behavior.
- When no longer needed, destroy the mutex via
pthread_mutex_destroy(). - Statically initialized mutexes do not require explicit destruction.
- Mutex type affects repeated-lock and error-detection behavior:
PTHREAD_MUTEX_NORMAL: No deadlock detection; repeated locking causes deadlock.PTHREAD_MUTEX_ERRORCHECK: Detects deadlocks and errors; slightly lower performance.PTHREAD_MUTEX_RECURSIVE: Allows the same thread to lock multiple times; requires an equal number of unlocks.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutex_destroy
int pthread_mutex_destroy(pthread_mutex_t *mutex);
Destroys a mutex and releases its resources.
Parameters:
mutexPointer to the mutex to destroy. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALmutexisNULLor not properly initialized.EBUSYThe mutex is currently locked; cannot destroy.
Notes:
- A locked mutex cannot be destroyed.
- Once destroyed, the mutex cannot be reused unless re-initialized.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutex_lock
int pthread_mutex_lock(pthread_mutex_t *mutex);
Locks a mutex. If the mutex is currently unlocked, the calling thread acquires it and returns immediately. If another thread holds the lock, the calling thread blocks until it becomes available.
The specific behavior depends on the mutex type:
- NORMAL (default): If the lock is already held by the current thread, relocking deadlocks.
- ERRORCHECK: If the lock is already held by the current thread, returns
EDEADLK. - RECURSIVE: If the lock is already held by the current thread, increments the lock count; requires an equal number of unlocks.
Parameters:
mutexPointer to the mutex to lock.
Returns:
Returns 0 on success, or an error code on failure:
EDEADLKMutex isPTHREAD_MUTEX_ERRORCHECKand the current thread already holds it (deadlock detection).EINVALMutex is not properly initialized.EOWNERDEADThe mutex is robust and the previous owner terminated without releasing it. The caller now owns the mutex; callpthread_mutex_consistent()to make it consistent, or unlock and no longer use it.ENOTRECOVERABLEThe robust mutex is in an unrecoverable state and can no longer be used.
Notes:
- Threads holding locks should release them as soon as possible to avoid long waits by other threads.
- Avoid calling potentially blocking functions (e.g., I/O operations) while holding a lock; this can cause performance issues.
- Avoid nested locking of multiple mutexes, which can cause deadlock. If nested locking is required, use a consistent lock order.
- After locking, use a
try-finallypattern or cleanup handlers to ensure the lock is always released. - If the thread is canceled, use cleanup handlers (
pthread_cleanup_push/pop) to ensure the lock is released. - Priority inversion: If priority inheritance is enabled, a low-priority thread holding the lock has its priority temporarily raised to the highest priority among waiters.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutex_trylock
int pthread_mutex_trylock(pthread_mutex_t *mutex);
Tries to lock a mutex (non-blocking). If the mutex is currently available, the function acquires the lock and returns immediately. If the mutex is already locked, returns EBUSY immediately without blocking.
This is the non-blocking version of pthread_mutex_lock(), suitable for scenarios where waiting is undesirable, such as polling or deadlock avoidance.
Parameters:
mutexPointer to the mutex to try to lock.
Returns:
Returns 0 on success, or an error code on failure:
EBUSYThe mutex is already locked and cannot be acquired. This is not a real error; it just indicates the lock is currently unavailable.EINVALThe mutex is not properly initialized.EDEADLKMutex isPTHREAD_MUTEX_ERRORCHECKand the current thread already holds it.EOWNERDEADThe robust mutex's previous owner terminated without releasing it.ENOTRECOVERABLEThe robust mutex is in an unrecoverable state.
Notes:
- If
EBUSYis returned, the caller may retry later or perform other actions. - For recursive mutexes, if the current thread already holds the lock,
pthread_mutex_trylock()succeeds and increments the lock count. - Commonly used to avoid deadlock: when trying to acquire multiple locks, release held locks and retry if some lock cannot be acquired.
- Do not call
pthread_mutex_trylock()in a tight loop (busy-waiting); it wastes CPU resources. - Suitable for non-blocking algorithms or timeout mechanisms.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutex_timedlock
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime);
Locks a mutex with a timeout. If the mutex cannot be acquired immediately, blocks until the lock becomes available or the timeout expires.
Parameters:
mutexPointer to the mutex to lock. Cannot beNULL.abstimeAbsolute timeout (based onCLOCK_REALTIME).
Returns:
Returns 0 on success, or an error code on failure:
ETIMEDOUTThe lock could not be acquired within the timeout.EINVALmutexisNULLor not properly initialized.EDEADLKMutex isPTHREAD_MUTEX_ERRORCHECKand the current thread already holds it.
Notes:
- For recursive mutexes, if the current thread already holds the lock, the call succeeds and increments the lock count, regardless of timeout.
abstimeis an absolute time, not a relative one. Compute it based onclock_gettime(CLOCK_REALTIME, ...).
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutex_unlock
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Unlocks a mutex, making it available for other waiting threads. Only the owning thread can unlock; otherwise, behavior depends on the mutex type.
For recursive mutexes, each pthread_mutex_unlock() call decrements the lock count; the lock is truly released only when the count reaches zero.
Parameters:
mutexPointer to the mutex to unlock.
Returns:
Returns 0 on success, or an error code on failure:
EPERMThe current thread does not own the mutex. ForPTHREAD_MUTEX_ERRORCHECK, unlocking a mutex not held returns this error. ForPTHREAD_MUTEX_NORMAL, behavior is undefined.EINVALThe mutex is not properly initialized or has been destroyed.
Notes:
- Must be unlocked by the same thread that locked the mutex; other threads cannot unlock on its behalf.
- Unlocking an unlocked mutex is undefined (for NORMAL) or returns an error (for ERRORCHECK).
- After unlocking, if threads are waiting for the lock, one of them is awakened and acquires the lock. Which one is awakened depends on the scheduling policy.
- When an exception or cancellation occurs while holding the lock, ensure the lock is released via cleanup handlers or exception handling.
- Unlock operations should be as fast as possible; avoid invoking unlock outside the lock-protected critical section.
- For priority-inheritance mutexes, unlocking restores the thread's original priority.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutex_consistent
int pthread_mutex_consistent(pthread_mutex_t *mutex);
Marks a robust mutex as consistent. When a robust mutex's previous owner terminates without releasing, pthread_mutex_lock() returns EOWNERDEAD; the new owner should call this function to restore consistency.
Parameters:
mutexPointer to a robust mutex in an inconsistent state. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALmutexisNULL, or not a robust mutex, or not in an inconsistent state.
Notes:
- Requires
PTHREAD_MUTEX_ROBUSTset in the mutex attributes. - If you unlock directly without calling this function, the mutex enters an unrecoverable state, and subsequent
pthread_mutex_lock()calls returnENOTRECOVERABLE.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutex_setprioceiling
int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *old_ceiling);
Dynamically modifies the priority ceiling of a mutex. This function first locks the mutex, modifies the ceiling, and then unlocks, ensuring the operation is atomic.
Parameters:
mutexPointer to the mutex.prioceilingNew priority ceiling value.old_ceilingIf non-NULL, stores the previous ceiling.
Returns:
Returns 0 on success, or an error code on failure:
EINVALInvalid argument, orCONFIG_PRIORITY_PROTECTis not enabled.EPERMCannot lock the mutex.
Notes:
- Requires
CONFIG_PRIORITY_PROTECT. When disabled, always returnsEINVAL. - The mutex protocol must be
PTHREAD_PRIO_PROTECTfor this to be meaningful. - This function internally performs lock/unlock; the caller must not already hold the mutex.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutex_getprioceiling
int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, int *prioceiling);
Gets the current priority ceiling of a mutex.
Parameters:
mutexPointer to the mutex.prioceilingPointer to an integer variable for storing the ceiling.
Returns:
Returns 0 on success, or an error code on failure:
EINVALInvalid argument, orCONFIG_PRIORITY_PROTECTis not enabled.
Notes:
- Requires
CONFIG_PRIORITY_PROTECT.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Mutex Attributes
pthread_mutexattr_init
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
Initializes a mutex attribute object to default values. Defaults: type PTHREAD_MUTEX_NORMAL, protocol PTHREAD_PRIO_NONE, process-private, non-robust.
Parameters:
attrPointer to the mutex attribute object to initialize. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_destroy
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
Destroys a mutex attribute object.
Parameters:
attrPointer to the mutex attribute object to destroy. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_settype
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
Sets the mutex type. The type determines repeated-lock and error-detection behavior.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.typeMutex type:PTHREAD_MUTEX_NORMALNo deadlock detection; repeated locking causes deadlock (default).PTHREAD_MUTEX_ERRORCHECKDetects deadlocks; repeated locking returnsEDEADLK.PTHREAD_MUTEX_RECURSIVEAllows the same thread to lock multiple times; requires an equal number of unlocks.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, ortypeis not a valid value.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_gettype
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
Gets the mutex type.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.typePointer to an integer variable for storing the mutex type. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrortypeisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_setpshared
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
Sets the process-shared attribute in a mutex attribute object.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.psharedProcess-shared attribute:PTHREAD_PROCESS_PRIVATE(0) Process-private (default).PTHREAD_PROCESS_SHARED(1) Shared across processes.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orpsharedis neither 0 nor 1.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_getpshared
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared);
Gets the process-shared attribute from a mutex attribute object.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.psharedPointer to an integer variable for storing the process-shared attribute. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorpsharedisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_setprotocol
int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol);
Sets the mutex priority protocol. The protocol determines how threads holding the lock address priority inversion.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.protocolPriority protocol:PTHREAD_PRIO_NONENo priority protocol (default).PTHREAD_PRIO_INHERITPriority inheritance; a low-priority thread holding the lock has its priority temporarily raised to the highest among waiters (requiresCONFIG_PRIORITY_INHERITANCE).PTHREAD_PRIO_PROTECTPriority ceiling protection (requiresCONFIG_PRIORITY_PROTECT).
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orprotocolis invalid or unsupported.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_getprotocol
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *protocol);
Gets the mutex priority protocol.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.protocolPointer to an integer variable for storing the protocol. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorprotocolisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_setrobust
int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robust);
Sets the mutex robustness attribute. A robust mutex avoids permanent deadlock if its owner terminates abnormally.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.robustRobustness attribute:PTHREAD_MUTEX_STALLEDNon-robust (default); the lock becomes permanently unusable if the owner terminates.PTHREAD_MUTEX_ROBUSTRobust; if the owner terminates, the next locker receivesEOWNERDEADand can recover viapthread_mutex_consistent().
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orrobustis not a valid value.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_getrobust
int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr, int *robust);
Gets the mutex robustness attribute.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.robustPointer to an integer variable for storing the robustness. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorrobustisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_setprioceiling
int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling);
Sets the priority ceiling in a mutex attribute object. When the mutex protocol is PTHREAD_PRIO_PROTECT, the holder's priority is raised to this ceiling to avoid priority inversion.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.prioceilingPriority ceiling; must be betweensched_get_priority_min(SCHED_FIFO)andsched_get_priority_max(SCHED_FIFO).
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orprioceilingis out of the valid priority range.
Notes:
- Requires
CONFIG_PRIORITY_PROTECT. When disabled, this function always returnsEINVAL. - Should be used together with
pthread_mutexattr_setprotocol(attr, PTHREAD_PRIO_PROTECT).
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_mutexattr_getprioceiling
int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling);
Gets the priority ceiling from a mutex attribute object.
Parameters:
attrPointer to the mutex attribute object. Cannot beNULL.prioceilingPointer to an integer variable for storing the priority ceiling. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorprioceilingisNULL, orCONFIG_PRIORITY_PROTECTis not enabled.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Condition Variables
pthread_cond_init
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
Initializes a condition variable. A condition variable can also be initialized statically with PTHREAD_COND_INITIALIZER.
Parameters:
condPointer to the condition variable to initialize. Cannot beNULL.attrCondition variable attributes. IfNULL, default attributes are used (CLOCK_REALTIME, process-private).
Returns:
Returns 0 on success, or an error code on failure:
EINVALcondisNULL.ENOMEMInsufficient memory.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_cond_destroy
int pthread_cond_destroy(pthread_cond_t *cond);
Destroys a condition variable.
Parameters:
condPointer to the condition variable to destroy. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALcondisNULLor not properly initialized.EBUSYA thread is waiting on the condition variable.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_cond_wait
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
Waits for a condition variable to be signaled. This function atomically releases the mutex and blocks on the condition variable. When the condition variable is signaled via pthread_cond_signal() or pthread_cond_broadcast(), the thread wakes up, re-acquires the mutex, and returns.
Condition variables are commonly used to implement producer-consumer patterns or other scenarios requiring thread coordination. Typical usage:
pthread_mutex_lock(&mutex);
while (!condition) {
pthread_cond_wait(&cond, &mutex);
}
// Condition met; process data
pthread_mutex_unlock(&mutex);
Parameters:
condPointer to the condition variable.mutexPointer to the associated mutex. Must already be locked by the calling thread.
Returns:
Returns 0 on success, or an error code on failure:
EINVALcondormutexis not properly initialized, or a different mutex is used.EPERMThe calling thread does not hold the mutex.
Notes:
- The associated mutex must be held before calling; otherwise behavior is undefined.
- On return, the mutex is re-acquired, even on error.
- Due to possible spurious wakeups, check the condition in a loop:
while (!condition) pthread_cond_wait(...). A spurious wakeup is when the thread wakes up without being signaled. - The condition variable itself stores no state; it is merely a synchronization primitive. The actual condition (boolean expression) is maintained by the application, typically via shared variables.
- The mutex is atomically released while waiting, avoiding the race condition between releasing the lock and blocking.
- If the thread is canceled, the mutex is re-acquired and cleanup handlers are called. Cleanup handlers should release the lock.
- Multiple threads can wait on the same condition variable simultaneously.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_cond_timedwait
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime);
Waits on a condition variable with a timeout. Behavior is the same as pthread_cond_wait(), but returns automatically after the timeout.
Parameters:
condPointer to the condition variable.mutexPointer to the associated mutex; must be locked before the call.abstimeAbsolute timeout. The clock source depends on the condition variable attributes (defaultCLOCK_REALTIME).
Returns:
Returns 0 on success, or an error code on failure:
ETIMEDOUTNo signal was received within the timeout.EINVALInvalid arguments.
Notes:
- Even on timeout, the mutex is re-acquired.
- Still check the condition in a loop, as spurious wakeups are possible.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_cond_clockwait
int pthread_cond_clockwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
clockid_t clockid, const struct timespec *abstime);
Waits on a condition variable using a specified clock. Allows specifying the clock source directly at wait time, without relying on the attribute object.
Parameters:
condPointer to the condition variable.mutexPointer to the associated mutex; must be locked before the call.clockidClock ID, such asCLOCK_REALTIMEorCLOCK_MONOTONIC.abstimeAbsolute timeout based on the specified clock.
Returns:
Returns 0 on success, or an error code on failure:
ETIMEDOUTNo signal was received within the timeout.EINVALInvalid arguments.
POSIX Compatibility: Compatible extension interface.
pthread_cond_signal
int pthread_cond_signal(pthread_cond_t *cond);
Wakes at least one thread waiting on the condition variable. If multiple threads are waiting, the scheduling policy determines which is awakened. If no thread is waiting, this call has no effect (signal is lost).
Unlike pthread_cond_broadcast(), pthread_cond_signal() wakes only one thread, suitable for scenarios where only one thread can handle the condition; this avoids unnecessary wakeups and context switches.
Parameters:
condPointer to the condition variable to signal.
Returns:
Returns 0 on success, or an error code on failure:
EINVALcondis not properly initialized.
Notes:
- You do not need to hold the associated mutex to call
pthread_cond_signal(), but it is generally recommended to hold it to avoid race conditions. - Awakened threads do not execute immediately; they first try to re-acquire the mutex. Releasing the lock immediately after signaling is a good practice.
- If you signal without holding the lock after modifying the condition, a lost-wakeup problem may occur: a waiter may be preempted between checking the condition and calling wait.
- Typical pattern:
pthread_mutex_lock(&mutex); // Modify shared state to make the condition true condition = true; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - If the condition may satisfy multiple waiters, use
pthread_cond_broadcast(). - POSIX does not guarantee signal fairness; thread starvation is possible.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_cond_broadcast
int pthread_cond_broadcast(pthread_cond_t *cond);
Wakes all threads waiting on the condition variable. All awakened threads compete to re-acquire the associated mutex. If no thread is waiting, the call has no effect.
Unlike pthread_cond_signal(), broadcast wakes all waiters, suitable when the condition change may affect multiple threads or when it is unclear which thread should be awakened.
Parameters:
condPointer to the condition variable to broadcast.
Returns:
Returns 0 on success, or an error code on failure:
EINVALcondis not properly initialized.
Notes:
- Similar to
pthread_cond_signal(), the associated mutex should typically be held when calling. - Awakened threads serialize on the mutex; only one thread at a time can acquire the mutex and proceed.
- Using broadcast may cause a "thundering herd": many threads wake up but only a few can actually handle the condition; the others go back to waiting, causing unnecessary context switches.
- Suitable scenarios:
- Condition changes affect all waiters (e.g., resource state change, shutdown signal)
- It is unclear which thread should handle the condition
- All threads need to re-evaluate their waiting conditions
- Typical pattern:
pthread_mutex_lock(&mutex); // Modify shared state affecting all waiters shutdown = true; pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mutex); - If only one thread needs to be awakened, prefer
pthread_cond_signal()for efficiency.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Condition Variable Attributes
pthread_condattr_init
int pthread_condattr_init(pthread_condattr_t *attr);
Initializes a condition variable attribute object to default values. Defaults:
- Process-shared attribute:
PTHREAD_PROCESS_PRIVATE - Clock attribute:
CLOCK_REALTIME
Attribute objects are used when calling pthread_cond_init() to specify the behavior of the condition variable. The same attribute object can be used to initialize multiple condition variables.
Parameters:
attrPointer to the condition variable attribute object to initialize. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL.
Notes:
- When no longer needed, destroy with
pthread_condattr_destroy(). - Modifications to the attribute object do not affect condition variables already created with it.
- To use
CLOCK_MONOTONICas the timeout clock (to avoid system time adjustments), callpthread_condattr_setclock()after initialization. - In openvela, the attribute object is a simple struct (containing
psharedandclockid), with no dynamic memory allocation.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_condattr_destroy
int pthread_condattr_destroy(pthread_condattr_t *attr);
Destroys a condition variable attribute object, releasing its resources. A destroyed attribute object cannot be used again unless re-initialized with pthread_condattr_init().
Parameters:
attrPointer to the condition variable attribute object to destroy. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULLor not a valid attribute object.
Notes:
- Destruction does not affect condition variables already created with this object.
- In openvela, the attribute object does not use dynamic memory; this function is mainly for POSIX compatibility.
- Always pair
pthread_condattr_init()withpthread_condattr_destroy().
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_condattr_getpshared
int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared);
Gets the process-shared attribute from a condition variable attribute object. The process-shared attribute determines whether the condition variable can be accessed by threads in multiple processes.
Parameters:
attrPointer to the condition variable attribute object. Cannot beNULL.psharedPointer to an integer variable for storing the current process-shared attribute. Cannot beNULL. Returned value is one of:PTHREAD_PROCESS_PRIVATEThe condition variable may only be used by threads in the same process (default).PTHREAD_PROCESS_SHAREDThe condition variable may be used by threads across processes, provided it is allocated in shared memory.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorpsharedisNULL.
Notes:
- In openvela, due to the RTOS memory model,
PTHREAD_PROCESS_SHAREDbehavior may differ from Linux. - Default is
PTHREAD_PROCESS_PRIVATE.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_condattr_setpshared
int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared);
Sets the process-shared attribute of a condition variable attribute object. This attribute determines whether the condition variable can be manipulated by threads in different processes.
When set to PTHREAD_PROCESS_SHARED, any thread with access to the memory holding the condition variable can operate on it. When set to PTHREAD_PROCESS_PRIVATE, only threads in the same process as the initializer can operate on it. Using a private condition variable from threads in a different process is undefined.
Parameters:
attrPointer to the condition variable attribute object. Cannot beNULL.psharedProcess-shared attribute value; must be one of:PTHREAD_PROCESS_PRIVATEProcess-private (default).PTHREAD_PROCESS_SHAREDShared across processes.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orpsharedis neitherPTHREAD_PROCESS_SHAREDnorPTHREAD_PROCESS_PRIVATE.
Notes:
- When using
PTHREAD_PROCESS_SHARED, the condition variable must be allocated in shared memory accessible to all relevant processes. - The mutex associated with the condition variable should also be set as process-shared.
- Modifying the attribute object does not affect already-created condition variables.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_condattr_getclock
int pthread_condattr_getclock(const pthread_condattr_t *attr, clockid_t *clock_id);
Gets the clock attribute from a condition variable attribute object. The clock attribute determines which clock pthread_cond_timedwait() uses for timeout calculation.
Parameters:
attrPointer to the condition variable attribute object. Cannot beNULL.clock_idPointer to aclockid_tvariable for storing the current clock attribute. Returned value is one of:CLOCK_REALTIMESystem real-time clock (default); affected by system time adjustments (e.g., NTP).CLOCK_MONOTONICMonotonic clock; unaffected by system time adjustments.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL.
Notes:
- Default clock is
CLOCK_REALTIME. - If the application requires accurate timeouts or the system time may be adjusted,
CLOCK_MONOTONICis recommended.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_condattr_setclock
int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id);
Sets the clock attribute of a condition variable attribute object. This attribute specifies the clock source pthread_cond_timedwait() uses for timeout calculation.
Choosing the right clock is critical for timeout behavior:
CLOCK_REALTIME: Uses the system real-time clock. The timeout is an absolute time. If the system time is moved forward, premature timeouts may occur; if moved backward, timeouts may be delayed.CLOCK_MONOTONIC: Uses a monotonically increasing clock unaffected by system time adjustments; suitable when precise timeout control is needed.
Parameters:
attrPointer to the condition variable attribute object. Cannot beNULL.clock_idClock ID; must be one of:CLOCK_REALTIMESystem real-time clock (default).CLOCK_MONOTONICMonotonic clock.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orclock_idis neitherCLOCK_REALTIMEnorCLOCK_MONOTONIC.
Notes:
- openvela only supports
CLOCK_REALTIMEandCLOCK_MONOTONIC; passing other clock IDs (e.g.,CLOCK_PROCESS_CPUTIME_ID) returnsEINVAL. - Modifying the clock attribute does not affect already-created condition variables; it only affects those created later using this attribute object.
- When using
CLOCK_MONOTONIC, theabstimepassed topthread_cond_timedwait()should be based onclock_gettime(CLOCK_MONOTONIC, ...). pthread_cond_clockwait()allows specifying the clock at wait time without relying on the attribute object.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Read-Write Locks
pthread_rwlock_init
int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
Initializes a read-write lock. Read-write locks allow multiple threads to hold read locks simultaneously, but write locks are exclusive.
Parameters:
rwlockPointer to the read-write lock to initialize. Cannot beNULL.attrRead-write lock attributes. IfNULL, defaults are used.
Returns:
Returns 0 on success, or an error code on failure:
EINVALrwlockisNULL.ENOMEMInsufficient memory.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlock_destroy
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
Destroys a read-write lock.
Parameters:
rwlockPointer to the read-write lock to destroy. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALrwlockisNULL.EBUSYThe lock is currently held.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlock_rdlock
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
Acquires a read lock. If no write lock is currently held, the call succeeds immediately; otherwise it blocks. Multiple threads may hold read locks simultaneously.
Parameters:
rwlockPointer to the read-write lock.
Returns:
Returns 0 on success, or an error code on failure:
EINVALrwlockis not properly initialized.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlock_tryrdlock
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
Tries to acquire a read lock (non-blocking).
Parameters:
rwlockPointer to the read-write lock.
Returns:
Returns 0 on success, or an error code on failure:
EBUSYA write lock is held; cannot acquire a read lock.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlock_timedrdlock
int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const struct timespec *abstime);
Acquires a read lock with a timeout. If the read lock cannot be acquired immediately, blocks until it becomes available or the timeout expires. Timeout is based on CLOCK_REALTIME.
Parameters:
rwlockPointer to the read-write lock.abstimeAbsolute timeout (based onCLOCK_REALTIME).
Returns:
Returns 0 on success, or an error code on failure:
ETIMEDOUTThe read lock could not be acquired within the timeout.EBUSYRead lock unavailable.EINVALInvalid arguments.
Notes:
- Internally calls
pthread_rwlock_clockrdlock()withCLOCK_REALTIME. - For
CLOCK_MONOTONIC, usepthread_rwlock_clockrdlock().
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlock_clockrdlock
int pthread_rwlock_clockrdlock(pthread_rwlock_t *rwlock, clockid_t clockid,
const struct timespec *abstime);
Acquires a read lock with a timeout using a specified clock.
Parameters:
rwlockPointer to the read-write lock.clockidClock ID, such asCLOCK_REALTIMEorCLOCK_MONOTONIC.abstimeAbsolute timeout based on the specified clock.
Returns:
Returns 0 on success, or an error code on failure:
ETIMEDOUTThe read lock could not be acquired within the timeout.EINVALInvalid arguments.
POSIX Compatibility: Compatible extension interface.
pthread_rwlock_wrlock
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
Acquires a write lock. Write locks are exclusive; the call waits until all read and write locks are released.
Parameters:
rwlockPointer to the read-write lock.
Returns:
Returns 0 on success, or an error code on failure:
EINVALrwlockis not properly initialized.EAGAINThe number of writers has reached the maximum.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlock_trywrlock
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
Tries to acquire a write lock (non-blocking).
Parameters:
rwlockPointer to the read-write lock.
Returns:
Returns 0 on success, or an error code on failure:
EBUSYA read or write lock is held; cannot acquire a write lock.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlock_timedwrlock
int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *abstime);
Acquires a write lock with a timeout. If the write lock cannot be acquired immediately, blocks until it becomes available or the timeout expires. Timeout is based on CLOCK_REALTIME.
Parameters:
rwlockPointer to the read-write lock.abstimeAbsolute timeout (based onCLOCK_REALTIME).
Returns:
Returns 0 on success, or an error code on failure:
ETIMEDOUTThe write lock could not be acquired within the timeout.EAGAINThe number of writers has reached the maximum.EINVALInvalid arguments.
Notes:
- Internally calls
pthread_rwlock_clockwrlock()withCLOCK_REALTIME.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlock_clockwrlock
int pthread_rwlock_clockwrlock(pthread_rwlock_t *rwlock, clockid_t clockid,
const struct timespec *abstime);
Acquires a write lock with a timeout using a specified clock.
Parameters:
rwlockPointer to the read-write lock.clockidClock ID, such asCLOCK_REALTIMEorCLOCK_MONOTONIC.abstimeAbsolute timeout based on the specified clock.
Returns:
Returns 0 on success, or an error code on failure:
ETIMEDOUTThe write lock could not be acquired within the timeout.EAGAINThe number of writers has reached the maximum.EINVALInvalid arguments.
POSIX Compatibility: Compatible extension interface.
pthread_rwlock_unlock
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
Releases a read-write lock (either read or write).
Parameters:
rwlockPointer to the read-write lock.
Returns:
Returns 0 on success, or an error code on failure:
EINVALrwlockis not properly initialized.EPERMThe current thread does not hold the lock.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Read-Write Lock Attributes
pthread_rwlockattr_init
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
Initializes a read-write lock attribute object to default values. Default process-shared attribute is PTHREAD_PROCESS_PRIVATE.
Parameters:
attrPointer to the read-write lock attribute object to initialize. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlockattr_destroy
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
Destroys a read-write lock attribute object.
Parameters:
attrPointer to the read-write lock attribute object to destroy. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlockattr_setpshared
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
Sets the process-shared attribute of a read-write lock attribute object.
Parameters:
attrPointer to the read-write lock attribute object. Cannot beNULL.psharedProcess-shared attribute:PTHREAD_PROCESS_PRIVATEorPTHREAD_PROCESS_SHARED.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orpsharedis not a valid value.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_rwlockattr_getpshared
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *pshared);
Gets the process-shared attribute from a read-write lock attribute object.
Parameters:
attrPointer to the read-write lock attribute object. Cannot beNULL.psharedPointer to an integer variable for storing the attribute. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorpsharedisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Barriers
pthread_barrier_init
int pthread_barrier_init(pthread_barrier_t *barrier,
const pthread_barrierattr_t *attr, unsigned int count);
Initializes a barrier. Barriers synchronize multiple threads; all threads must arrive at the barrier before any can continue.
Parameters:
barrierPointer to the barrier to initialize. Cannot beNULL.attrBarrier attributes. IfNULL, defaults are used.countNumber of threads required to reach the barrier. Must be greater than 0.
Returns:
Returns 0 on success, or an error code on failure:
EINVALbarrierisNULL, orcountis 0.ENOMEMInsufficient memory.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_barrier_destroy
int pthread_barrier_destroy(pthread_barrier_t *barrier);
Destroys a barrier.
Parameters:
barrierPointer to the barrier to destroy. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALbarrierisNULL.EBUSYThreads are waiting on the barrier.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_barrier_wait
int pthread_barrier_wait(pthread_barrier_t *barrier);
Waits at a barrier. When all threads (the number specified by the count parameter of pthread_barrier_init) have called this function, all are released simultaneously.
Parameters:
barrierPointer to the barrier.
Returns:
One thread returns PTHREAD_BARRIER_SERIAL_THREAD (this thread can be used for cleanup work); others return 0.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Barrier Attributes
pthread_barrierattr_init
int pthread_barrierattr_init(pthread_barrierattr_t *attr);
Initializes a barrier attribute object to default values. Default process-shared attribute is PTHREAD_PROCESS_PRIVATE.
Parameters:
attrPointer to the barrier attribute object to initialize. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_barrierattr_destroy
int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
Destroys a barrier attribute object.
Parameters:
attrPointer to the barrier attribute object to destroy. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_barrierattr_setpshared
int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared);
Sets the process-shared attribute of a barrier attribute object.
Parameters:
attrPointer to the barrier attribute object. Cannot beNULL.psharedProcess-shared attribute:PTHREAD_PROCESS_PRIVATEorPTHREAD_PROCESS_SHARED.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrisNULL, orpsharedis not a valid value.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_barrierattr_getpshared
int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared);
Gets the process-shared attribute from a barrier attribute object.
Parameters:
attrPointer to the barrier attribute object. Cannot beNULL.psharedPointer to an integer variable for storing the attribute. Cannot beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALattrorpsharedisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Spinlocks
pthread_spin_init
int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
Initializes a spinlock. Spinlocks acquire the lock via busy-waiting, suitable for very short critical sections.
Parameters:
lockPointer to the spinlock to initialize. Cannot beNULL.psharedShared attribute:PTHREAD_PROCESS_PRIVATEorPTHREAD_PROCESS_SHARED.
Returns:
Returns 0 on success, or an error code on failure:
EINVALlockisNULL.
Notes:
- Do not use spinlocks for scenarios where the lock is held for long periods; this wastes CPU.
- Do not call potentially blocking functions while holding a spinlock.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_spin_destroy
int pthread_spin_destroy(pthread_spinlock_t *lock);
Destroys a spinlock.
Parameters:
lockPointer to the spinlock to destroy.
Returns:
Returns 0 on success, or an error code on failure:
EINVALlockis not properly initialized.EBUSYThe spinlock is currently locked.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_spin_lock
int pthread_spin_lock(pthread_spinlock_t *lock);
Acquires a spinlock. If the lock is already held, the calling thread busy-waits until the lock is available.
Parameters:
lockPointer to the spinlock.
Returns:
Returns 0 on success, or an error code on failure:
EINVALlockis not properly initialized.EDEADLKThe current thread already holds the lock (implementation-dependent).
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_spin_trylock
int pthread_spin_trylock(pthread_spinlock_t *lock);
Tries to acquire a spinlock (non-blocking).
Parameters:
lockPointer to the spinlock.
Returns:
Returns 0 on success, or an error code on failure:
EBUSYThe spinlock is already locked.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_spin_unlock
int pthread_spin_unlock(pthread_spinlock_t *lock);
Releases a spinlock.
Parameters:
lockPointer to the spinlock.
Returns:
Returns 0 on success, or an error code on failure:
EINVALlockis not properly initialized.EPERMThe current thread does not hold the lock.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Thread-Specific Data
pthread_key_create
int pthread_key_create(pthread_key_t *key, void (*destructor)(void *));
Creates a thread-specific data key. Each thread can use the key to store and retrieve its own private data.
Parameters:
keyPointer to apthread_key_tvariable for storing the created key. Cannot beNULL.destructorDestructor called automatically for non-NULLdata when the thread exits. May beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EAGAINSystem key count limit reached (PTHREAD_KEYS_MAX).ENOMEMInsufficient memory.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_key_delete
int pthread_key_delete(pthread_key_t key);
Deletes a thread-specific data key. Destructors are not called, and per-thread data associated with the key is not released.
Parameters:
keyKey to delete.
Returns:
Returns 0 on success, or an error code on failure:
EINVALkeyis invalid.
Notes:
- After deleting the key, each thread should release its associated data; otherwise memory leaks occur.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_setspecific
int pthread_setspecific(pthread_key_t key, const void *value);
Sets thread-specific data for the calling thread.
Parameters:
keyData key; must be a valid key created bypthread_key_create().valueValue to store. May beNULL.
Returns:
Returns 0 on success, or an error code on failure:
EINVALkeyis invalid.ENOMEMInsufficient memory.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_getspecific
void *pthread_getspecific(pthread_key_t key);
Gets thread-specific data for the calling thread.
Parameters:
keyData key.
Returns:
Returns the value associated with the key. Returns NULL if the key is invalid or no value has been set.
Notes:
- This function does not return an error code; it cannot distinguish between "not set" and "set to NULL".
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Thread Cleanup
pthread_cleanup_push
void pthread_cleanup_push(void (*routine)(void *), void *arg);
Registers a thread cleanup function. The cleanup function runs when the thread is canceled, calls pthread_exit(), or calls pthread_cleanup_pop(1).
Parameters:
routineCleanup function. Cannot beNULL.argArgument passed to the cleanup function.
Returns:
No return value.
Notes:
- Must be paired with
pthread_cleanup_pop()and in the same function scope. - Cleanup functions run in reverse registration order (last registered runs first).
- Commonly used to ensure mutexes are released on thread cancellation.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
pthread_cleanup_pop
void pthread_cleanup_pop(int execute);
Removes the most recently registered cleanup function and optionally executes it.
Parameters:
executeIf nonzero, removes and executes the cleanup function; if zero, only removes it.
Returns:
No return value.
Notes:
- Must be paired with
pthread_cleanup_push(). - Even if
executeis 0, the cleanup function is removed from the stack.
POSIX Compatibility: Compatible with the POSIX interface of the same name.
Extension Interfaces
pthread_setname_np
int pthread_setname_np(pthread_t thread, const char *name);
Sets a thread's name. Thread names are used for debugging and logging and can be viewed via ps or debuggers.
Parameters:
threadThread ID.nameThread name string.
Returns:
Returns 0 on success, or an error code on failure:
ESRCHThe specified thread cannot be found.EINVALnameisNULL.
POSIX Compatibility: Compatible with the Linux extension interface.
pthread_getname_np
int pthread_getname_np(pthread_t thread, char *name, size_t len);
Gets a thread's name.
Parameters:
threadThread ID.nameBuffer for storing the name.lenBuffer size.
Returns:
Returns 0 on success, or an error code on failure:
ESRCHThe specified thread cannot be found.EINVALnameisNULL.
POSIX Compatibility: Compatible with the Linux extension interface.
pthread_gettid_np
pid_t pthread_gettid_np(pthread_t thread);
Gets the thread's kernel thread ID (pid_t).
Parameters:
threadThread ID.
Returns:
Returns the kernel thread ID.
Notes:
- In openvela,
pthread_tis itselfpid_t, so this function returns the input value directly.
POSIX Compatibility: Compatible extension interface.
pthread_getcpuclockid
int pthread_getcpuclockid(pthread_t thread, clockid_t *clockid);
Gets the CPU clock ID of a thread. This clock measures CPU time consumed by the specified thread.
Parameters:
threadThread ID.clockidPointer to aclockid_tvariable for storing the clock ID.
Returns:
Returns 0 on success, or an error code on failure:
ESRCHThe specified thread cannot be found.EINVALclockidisNULL.
POSIX Compatibility: Compatible with the POSIX interface of the same name.