POSIX Thread

https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/pthread.h.html

Defines

PTHREAD_CREATE_JOINABLE (0x0002u)

Joinable thread attribute.

PTHREAD_CREATE_DETACHED (0x0004u)

Detached thread attribute.

PTHREAD_CANCEL_ENABLE (0x0008u)

Cancel enable attribute.

PTHREAD_CANCEL_DISABLE (0x0010u)

Cancel disable attribute.

PTHREAD_CANCEL_DEFERRED (0x0020u)

Deferred cancel attribute.

PTHREAD_CANCEL_ASYNCHRONOUS (0x0040u)

Asynchronous cancel attribute.

PTHREAD_PRIO_INHERIT (0x0001u)

Priority inheritance protocol.

PTHREAD_PRIO_NONE (0x0002u)

No priority protocol.

PTHREAD_PRIO_PROTECT (0x0004u)

Priority protect protocol.

PTHREAD_MUTEX_DEFAULT (PTHREAD_MUTEX_NORMAL)

Default mutex type.

PTHREAD_MUTEX_ERRORCHECK (0x0008u)

Error-checking mutex type.

PTHREAD_MUTEX_NORMAL (0x0010u)

Normal mutex type.

PTHREAD_MUTEX_RECURSIVE (0x0020u)

Recursive mutex type.

PTHREAD_MUTEX_ROBUST (0x0040u)

Robust mutex type. Not supported.

PTHREAD_MUTEX_STALLED (0x0080u)

Stalled mutex type. Not supported.

PTHREAD_PROCESS_SHARED (0x0100u)

Process-shared mutex attribute. Not supported.

PTHREAD_PROCESS_PRIVATE (0x0200u)

Process-private mutex attribute. Not supported.

PTHREAD_SCOPE_PROCESS (0x0400u)

Process scope mutex attribute. Not supported.

PTHREAD_SCOPE_SYSTEM (0x0800u)

System scope mutex attribute. Not supported.

PTHREAD_INHERIT_SCHED (0x0001u)

A thread created with this setting takes the scheduling policy and priority of its creator.

The policy and priority stored in the attribute object are ignored. The time slice, stack, detach state, name and privilege level still come from the attribute object. The startup thread created by qrt_kernel_boot() has no creator, so it uses the attribute object’s values.

PTHREAD_EXPLICIT_SCHED (0x0002u)

A thread created with this setting takes its scheduling policy and priority from the attribute object. This is the default.

PTHREAD_PRIVILEGED_NP (0x0001u)

Privileged thread attribute.

PTHREAD_UNPRIVILEGED_NP (0x0002u)

Unprivileged thread attribute.

PTHREAD_FPCONTEXT_ENABLE_NP (0x0001u)

Enable FPU context tracking for the thread.

PTHREAD_FPCONTEXT_DISABLE_NP (0x0002u)

Disable FPU context tracking for the thread.

PTHREAD_ONCE_INIT (0)

Once initialization.

PTHREAD_COND_INITIALIZER (0)

Condition variable initialization. Not supported.

PTHREAD_MUTEX_INITIALIZER

Mutex initialization.

A mutex initialized this way is allocated from the kernel heap on its first use. If the heap is exhausted, that call returns ENOMEM and the mutex keeps this initial value, so a later call can retry.

PTHREAD_RWLOCK_INITIALIZER

Read-write lock initialization. Not supported.

PTHREAD_NULL ((pthread_t)-1)

Not equal to valid thread.

PTHREAD_KEYS_MAX (16)

Maximum number of thread-specific data keys.

PTHREAD_DESTRUCTOR_ITERATIONS (1)

Number of iterations for destructors.

Functions

int pthread_mutex_clocklock(pthread_mutex_t *mutex, clockid_t clock_id, const struct timespec *abstime)

Acquire mutex, blocking until abstime on clock_id if it is already held.

Honors the mutex’s type and protocol attributes: error-check detects self-deadlock, recursive permits re-entrant locks up to the kernel’s recursion limit, and priority-protect/inherit promote the owner to keep priority inversion bounded. A PTHREAD_MUTEX_NORMAL mutex (the default type) relocked by its owner is not detected: the call waits until abstime. Every abstime, {0, 0} included, is an absolute time on clock_id; one with negative seconds lies before the epoch and has already passed.

Error numbers:

  • EINVAL: The mutex pointer is NULL or the mutex is not initialized.

  • ENOMEM: This is the first use of a mutex initialized with PTHREAD_MUTEX_INITIALIZER, and the kernel heap has insufficient memory for it.

  • EDEADLK: The mutex is owned by the caller and its type is PTHREAD_MUTEX_ERRORCHECK.

  • EAGAIN: The mutex is recursive and the recursion count saturated.

  • EINVAL: The thread would have blocked but abstime has nanoseconds outside [0, 999’999’999].

  • EINVAL: The thread would have blocked but clock_id is not a supported clock.

  • ETIMEDOUT: abstime passed before the mutex became available; returned at once if it has already passed.

Parameters:
  • mutex – Pointer to the mutex to lock.

  • clock_id – Clock ID to use for the timeout.

  • abstime – Pointer to the absolute time to wait until.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

pthread_mutex_t lock    = PTHREAD_MUTEX_INITIALIZER;
unsigned int    counter = 0u;

int update_with_timeout(void)
{
    struct timespec deadline;
    int             status;

    clock_gettime(CLOCK_MONOTONIC, &deadline);
    deadline.tv_sec += 1;

    status = pthread_mutex_clocklock(&lock, CLOCK_MONOTONIC, &deadline);
    if (status == 0)
    {
        counter++;
        pthread_mutex_unlock(&lock);
    }

    return status;
}

int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime)

Acquire mutex, blocking until abstime on CLOCK_REALTIME if it is already held.

Equivalent to pthread_mutex_clocklock() with clock_id fixed to CLOCK_REALTIME; {0, 0} is an ordinary deadline, and negative seconds lie before the epoch and have passed.

Error numbers:

  • EINVAL: The mutex pointer is NULL or the mutex is not initialized.

  • ENOMEM: This is the first use of a mutex initialized with PTHREAD_MUTEX_INITIALIZER, and the kernel heap has insufficient memory for it.

  • EDEADLK: The mutex is owned by the caller and its type is PTHREAD_MUTEX_ERRORCHECK.

  • EAGAIN: The mutex is recursive and the recursion count saturated.

  • EINVAL: The thread would have blocked but abstime has nanoseconds outside [0, 999’999’999].

  • ETIMEDOUT: abstime passed before the mutex became available; returned at once if it has already passed.

Parameters:
  • mutex – Pointer to the mutex to lock.

  • abstime – Pointer to the absolute time to wait until.

Returns:

0 on success, or an error number on failure.

int pthread_mutex_destroy(pthread_mutex_t *mutex)

Tear down a previously initialized mutex.

The mutex must be currently unlocked; destroying a held mutex fails rather than corrupting kernel bookkeeping. All internal state is reset and the mutex must be re-initialized before reuse.

Error numbers:

  • EINVAL: The mutex pointer is NULL or the mutex is not initialized.

  • EBUSY: The mutex is currently locked.

Parameters:
  • mutex – Pointer to the mutex to destroy.

Returns:

0 on success, or an error number on failure.

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)

Initialize mutex using the type, protocol and ceiling captured in attr, or kernel defaults if attr is NULL.

The default attribute set is PTHREAD_MUTEX_DEFAULT type and PTHREAD_PRIO_NONE protocol with a zero priority ceiling. The statically-initialized form PTHREAD_MUTEX_INITIALIZER produces the same result, but allocates the mutex on its first use.

Error numbers:

  • EINVAL: The mutex pointer is NULL, or attr is non-NULL but has not been initialized or holds a type, protocol or priority ceiling that its setters would not store.

  • ENOMEM: The kernel heap has insufficient memory for the mutex.

Parameters:
  • mutex – Pointer to the mutex to initialize.

  • attr – Pointer to the mutex attributes. NULL for default attributes.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

pthread_mutex_t lock;

int lock_init(void)
{
    pthread_mutexattr_t attr;
    int                 status;

    pthread_mutexattr_init(&attr);
    pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);

    status = pthread_mutex_init(&lock, &attr);

    pthread_mutexattr_destroy(&attr);

    return status;
}

int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, int *prioceiling)

Read the configured priority ceiling of a mutex.

Only meaningful for mutexes whose protocol is not PTHREAD_PRIO_NONE.

Error numbers:

Parameters:
  • mutex – Pointer to the mutex.

  • prioceiling – Pointer to store the priority ceiling value.

Returns:

0 on success, or an error number on failure.

int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *old_ceiling)

Update the priority ceiling of a mutex and optionally return the previous value.

Honors the ceiling invariant: when the protocol is PTHREAD_PRIO_PROTECT, the caller’s priority must not exceed the current ceiling. Non-recursive mutexes cannot have their ceiling changed while held; recursive mutexes can, up to the recursion limit.

On an unlocked mutex the new ceiling is stored and applies from the next lock. When the ceiling of a held PTHREAD_PRIO_PROTECT mutex is raised above its owner’s current priority, the owner is raised to it at once; a lower ceiling leaves the owner’s priority unchanged until it releases the last mutex it holds. A PTHREAD_PRIO_INHERIT mutex stores the ceiling but does not use it. old_ceiling may be NULL.

Error numbers:

  • EINVAL: The mutex pointer is NULL or the mutex is not initialized, the mutex protocol is PTHREAD_PRIO_NONE, prioceiling is below the minimum or above the maximum thread priority, or the protocol is PTHREAD_PRIO_PROTECT and the caller’s priority is above the current ceiling.

  • ENOMEM: This is the first use of a mutex initialized with PTHREAD_MUTEX_INITIALIZER, and the kernel heap has insufficient memory for it.

  • EDEADLK: The mutex is owned by the caller and its type is PTHREAD_MUTEX_ERRORCHECK.

  • EAGAIN: The mutex is held; either it is non-recursive or its recursion count is saturated.

Parameters:
  • mutex – Pointer to the mutex.

  • prioceiling – New priority ceiling value.

  • old_ceiling – Pointer to store the old priority ceiling value.

Returns:

0 on success, or an error number on failure.

int pthread_mutex_lock(pthread_mutex_t *mutex)

Acquire mutex, blocking indefinitely if it is already held.

Equivalent to pthread_mutex_timedlock() with no deadline. Relocking a PTHREAD_MUTEX_NORMAL mutex that the caller already holds deadlocks: the call never returns.

Error numbers:

Parameters:
  • mutex – Pointer to the mutex to lock.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

pthread_mutex_t lock    = PTHREAD_MUTEX_INITIALIZER;
unsigned int    counter = 0u;

void counter_increment(void)
{
    pthread_mutex_lock(&lock);
    counter++;
    pthread_mutex_unlock(&lock);
}

int pthread_mutex_trylock(pthread_mutex_t *mutex)

Acquire mutex if it is free; otherwise fail immediately.

If the mutex is locked by any thread, the caller included, the call returns EBUSY at once instead of waiting. A PTHREAD_MUTEX_RECURSIVE mutex the caller holds is locked one more level instead.

Error numbers:

Parameters:
  • mutex – Pointer to the mutex to lock.

Returns:

0 on success, or an error number on failure.

int pthread_mutex_unlock(pthread_mutex_t *mutex)

Release one level of ownership of mutex and, when fully released, wake one waiter.

For recursive mutexes the call decrements the recursion counter; the mutex is only released and any pending waiters woken once the counter reaches zero. Priority promotions are undone once the thread releases the last mutex it holds.

Error numbers:

Parameters:
  • mutex – Pointer to the mutex to unlock.

Returns:

0 on success, or an error number on failure.

int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)

Invalidate a mutex attributes object so it cannot be used until re-initialized.

Error numbers:

  • EINVAL: attr is NULL or was not previously initialized.

Parameters:
  • attr – Pointer to the mutex attributes to destroy.

Returns:

0 on success, or an error number on failure.

int pthread_mutexattr_init(pthread_mutexattr_t *attr)

Populate attr with default mutex settings: PTHREAD_MUTEX_DEFAULT type, PTHREAD_PRIO_NONE protocol and a zero priority ceiling.

Error numbers:

Parameters:
  • attr – Pointer to the mutex attributes to initialize.

Returns:

0 on success, or an error number on failure.

int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling)

Read the priority ceiling currently stored in attr.

Error numbers:

  • EINVAL: attr or prioceiling is NULL, or attr has not been initialized.

Parameters:
  • attr – Pointer to the mutex attributes object.

  • prioceiling – Pointer to store the priority ceiling value.

Returns:

0 on success, or an error number on failure.

int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling)

Record a new priority ceiling in attr.

The ceiling must lie strictly above the idle priority. Mutexes created from attr afterwards inherit the new value.

Error numbers:

  • EINVAL: attr is NULL, has not been initialized, or prioceiling is below the minimum or above the maximum thread priority.

Parameters:
  • attr – Pointer to the mutex attributes object.

  • prioceiling – New priority ceiling value.

Returns:

0 on success, or an error number on failure.

int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *protocol)

Read the priority protocol currently stored in attr.

Error numbers:

Parameters:
  • attr – Pointer to the mutex attributes object.

  • protocol – Pointer to store the protocol value.

Returns:

0 on success, or an error number on failure.

int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol)

Record a new priority protocol in attr.

Error numbers:

Parameters:
  • attr – Pointer to the mutex attributes object.

  • protocol – New protocol value.

Returns:

0 on success, or an error number on failure.

int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)

Read the mutex type currently stored in attr.

Error numbers:

Parameters:
  • attr – Pointer to the mutex attributes object.

  • type – Pointer to store the type value.

Returns:

0 on success, or an error number on failure.

int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)

Record a new mutex type in attr.

Error numbers:

Parameters:
  • attr – Pointer to the mutex attributes object.

  • type – New type value.

Returns:

0 on success, or an error number on failure.

int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared)

Not supported.

Returns:

ENOSYS.

int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)

Not supported.

Returns:

ENOSYS.

int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr, int *robust)

Not supported.

Returns:

ENOSYS.

int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robust)

Not supported.

Returns:

ENOSYS.

int pthread_mutex_consistent(pthread_mutex_t *mutex)

Not supported.

Returns:

ENOSYS.

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *arg), void *arg)

Spawn a new thread that runs start_routine(arg) under the settings in attr.

When attr is NULL the default attribute set is used. If attr selects PTHREAD_INHERIT_SCHED the new thread takes the caller’s scheduling policy and priority. The inherited priority is the one reported by pthread_getschedparam(), so a temporary raise by a mutex protocol is not inherited. attr is not modified. A stack is allocated from the thread stack pool when stack is NULL in the attributes; otherwise the caller-supplied stack is used as-is. If the new thread’s priority is higher than the priority the caller is running at, the new thread runs before the call returns.

Error numbers:

  • EINVAL: start_routine is NULL, the stack size in attr is not 8-byte aligned, exceeds 1 GiB or cannot hold the thread’s initial context, attr holds a priority, scheduling policy, inherit-scheduler setting, detach state or time slice that its setters would not store, or (with MPU support) the stack set with pthread_attr_setstack() does not form a valid MPU region.

  • EPERM: attr requests a privileged thread while the caller is unprivileged (only with MPU support).

  • ENOMEM: The stack pool or kernel heap is exhausted.

Parameters:
  • thread – Pointer to the thread handle. NULL if not needed.

  • attr – Pointer to the thread attributes. NULL for default attributes.

  • start_routine – Pointer to the function to be executed by the thread.

  • arg – Argument to be passed to the thread function.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

unsigned int counter;

void *worker(void *arg)
{
    counter++;

    return NULL;
}

void *main_thread(void *arg)
{
    pthread_t thread;

    if (pthread_create(&thread, NULL, worker, NULL) == 0)
    {
        pthread_join(thread, NULL);
    }

    return NULL;
}

void pthread_cleanup_push(void (*routine)(void *arg), void *arg)

Register a cleanup handler that will run if the thread exits or is cancelled before the matching pthread_cleanup_pop().

Handler count is limited to QRT_CFG_CLEANUP_LIMIT; a push beyond the limit is ignored. The call is restricted to privileged threads; unprivileged callers are silently ignored.

Handlers run in kernel context, not in the thread, and no thread runs until they return, so they must not block or call kernel services. Handlers still registered when the thread terminates run, most recently pushed first, when its resources are released: inside pthread_join() for a joinable thread, or at the next context switch for a detached thread. The thread’s stack is released only after its handlers have run, so arg may point to one of the thread’s local variables, provided the function that declares it has not returned when the thread terminates.

Parameters:
  • routine – Pointer to the cleanup handler function.

  • arg – Argument to be passed to the cleanup handler.

    #include <pthread.h>
    
    int busy;
    
    void clear_busy(void *arg)
    {
        *(int *)arg = 0;
    }
    
    void *worker(void *arg)
    {
        busy = 1;
        pthread_cleanup_push(clear_busy, &busy);
    
        pthread_testcancel();
    
        pthread_cleanup_pop(1);
    
        return NULL;
    }
    

void pthread_cleanup_pop(int execute)

Discard the most recently pushed cleanup handler, optionally executing it.

Restricted to privileged threads; unprivileged callers are silently ignored.

See also

pthread_cleanup_push() for example.

Parameters:
  • execute – If non-zero, the cleanup handler is executed.

int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)

Read thread's scheduling policy and priority.

For threads that currently own a mutex with priority promotion active, the priority reported is the thread’s saved original priority, not the elevated one.

Error numbers:

  • EINVAL: thread or param is NULL.

  • ESRCH: thread has terminated.

Parameters:
  • thread – The thread to query.

  • policy – Pointer to a location where the scheduling policy will be stored.

  • param – Pointer to a location where the scheduling parameters will be stored.

Returns:

0 on success, or an error number on failure.

int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param)

Replace thread's scheduling policy and priority. May reschedule.

If thread owns a mutex whose protocol has temporarily raised its priority, a new priority below the raised one is stored as the saved original and takes effect when the thread releases the last mutex it holds; a higher one takes effect at once. Otherwise the new priority is applied immediately, and a calling thread that lowers its own priority below that of another ready thread is preempted before the call returns. In both cases pthread_getschedparam() reports the new priority at once. A ready or running thread goes behind the other ready threads of its new priority, also when the priority is unchanged, so a calling thread yields to a ready thread of equal priority.

Error numbers:

Parameters:
  • thread – The thread to set the scheduling policy and parameters for.

  • policy – The new scheduling policy. One of:

  • param – Pointer to a structure containing the new scheduling parameters.

Returns:

0 on success, or an error number on failure.

int pthread_setschedprio(pthread_t thread, int prio)

Replace thread's scheduling priority while keeping its current policy. May reschedule.

Equivalent to pthread_setschedparam() with the thread’s current policy, including its handling of a thread whose priority a mutex protocol has raised, except for where the thread is placed among the ready threads of its priority: an unchanged priority leaves it where it is, a raised one places it behind them and a lowered one ahead of them. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()), which pthread_setschedparam() may not.

Error numbers:

Parameters:
  • thread – The thread to set the priority for.

  • prio – The new priority value.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

void urgent_increment(unsigned int *count)
{
    struct sched_param param;
    int                policy;

    pthread_getschedparam(pthread_self(), &policy, &param);
    pthread_setschedprio(pthread_self(),
                         sched_get_priority_max(policy));

    (*count)++;

    pthread_setschedprio(pthread_self(), param.sched_priority);
}

void pthread_exit(void *value_ptr)

Terminate the calling thread with the given exit value.

Wakes any thread joining it, runs the thread’s thread-specific-data destructors, and releases the thread’s resources; a joinable thread’s resources are retained until it has been joined.

#include <pthread.h>

void exit_on_error(int status)
{
    if (status != 0)
    {
        pthread_exit(NULL);
    }
}

void *worker(void *arg)
{
    exit_on_error(pthread_setname_np(pthread_self(), "worker"));

    return NULL;
}

Parameters:
  • value_ptr – Pointer to the return value of the thread.

int pthread_equal(pthread_t t1, pthread_t t2)

Test whether two thread handles refer to the same thread.

Parameters:
  • t1 – First thread identifier.

  • t2 – Second thread identifier.

Returns:

0 if equal, non-zero otherwise.

pthread_t pthread_self(void)

Return the handle of the calling thread.

Returns:

The calling thread’s ID.

int pthread_cancel(pthread_t thread)

Request cancellation of thread.

A thread with asynchronous cancellation enabled is terminated immediately. Otherwise it is flagged and the actual cancellation occurs at the next cancellation point. Unprivileged callers may only cancel themselves or other unprivileged threads. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()).

Error numbers:

  • EINVAL: thread is NULL or already deleted.

  • EPERM: The caller is an unprivileged thread and the target is a privileged thread (only with MPU support).

Parameters:
  • thread – The thread to cancel.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

unsigned int iterations;

void *worker(void *arg)
{
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

    for (;;)
    {
        iterations++;
        pthread_testcancel();
    }

    return NULL;
}

void worker_stop(pthread_t thread)
{
    pthread_cancel(thread);
    pthread_join(thread, NULL);
}

int pthread_setcancelstate(int state, int *oldstate)

Enable or disable cancellation on the calling thread and report the previous state.

If the new state combines with the current cancel type to be asynchronously cancellable, and a cancellation is pending, the thread is terminated before this call returns.

Error numbers:

Parameters:
Returns:

0 on success, or an error number on failure.

int pthread_setcanceltype(int type, int *oldtype)

Choose whether cancellations on the calling thread are honored only at cancellation points or immediately, and report the previous type.

Switching to PTHREAD_CANCEL_ASYNCHRONOUS is rejected if the thread is currently the target of a pending join.

Error numbers:

See also

pthread_cancel() for example.

Parameters:
Returns:

0 on success, or an error number on failure.

void pthread_testcancel(void)

Yield to a pending cancellation, if cancellation is enabled.

If a cancellation request has been delivered while the thread was in deferred state, the thread is terminated here; otherwise the call returns without effect.

See also

pthread_cancel() for example.

int pthread_join(pthread_t thread, void **value_ptr)

Block the caller until thread exits, optionally collecting its exit value.

A thread can be joined by only one thread at a time. Detached threads, asynchronously-cancellable threads, and self-joins are rejected. If the target has already exited the result is collected immediately.

Error numbers:

  • EINVAL: thread is NULL, detached, asynchronously cancellable, or already being joined by another thread.

  • EDEADLK: The caller tried to join itself.

See also

pthread_create() for example.

Parameters:
  • thread – The thread to wait for.

  • value_ptr – Pointer to a location where the return value of the thread will be stored.

Returns:

0 on success, or an error number on failure.

int pthread_detach(pthread_t thread)

Transition thread to detached state so its resources are reclaimed automatically when it exits.

Error numbers:

  • EINVAL: thread is NULL, already detached, or no longer alive.

Parameters:
  • thread – The thread to detach.

Returns:

0 on success, or EINVAL if the thread does not exist.

int pthread_attr_init(pthread_attr_t *attr)

Populate attr with kernel defaults: QRT_CFG_THREAD_STACK_DEFAULT, PTHREAD_CREATE_JOINABLE, PTHREAD_EXPLICIT_SCHED, SCHED_RR with the default thread priority and the configured time slice, and (with MPU support) PTHREAD_UNPRIVILEGED_NP.

Error numbers:

  • EINVAL: attr is NULL.

    #include <pthread.h>
    
    void *worker(void *arg);
    
    void start_worker(void)
    {
        pthread_attr_t attr;
    
        pthread_attr_init(&attr);
        pthread_attr_setname_np(&attr, "worker");
        pthread_create(NULL, &attr, worker, NULL);
        pthread_attr_destroy(&attr);
    }
    

Parameters:
  • attr – Pointer to the thread attributes object to initialize.

Returns:

0 on success, or an error number on failure.

int pthread_attr_destroy(pthread_attr_t *attr)

Clear a thread attributes object, after which it must be re-initialized before reuse.

Error numbers:

Parameters:
  • attr – Pointer to the thread attributes object to destroy.

Returns:

0 on success, or an error number on failure.

int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)

Read the inherit-scheduling setting stored in attr.

Determines whether threads created from attr inherit the caller’s scheduling policy and priority or use the attribute object’s own.

Error numbers:

  • EINVAL: attr or inheritsched is NULL.

Parameters:
  • attr – Pointer to the thread attributes object.

  • inheritsched – Pointer to a location where the inherit scheduling attribute will be stored.

Returns:

0 on success, or an error number on failure.

int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)

Record an inherit-scheduling setting in attr.

Selects whether threads created from attr inherit the caller’s scheduling policy and priority (PTHREAD_INHERIT_SCHED) or use the attribute object’s own (PTHREAD_EXPLICIT_SCHED, the default).

Error numbers:

Parameters:
Returns:

0 on success, or an error number on failure.

int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)

Read the detach state stored in attr.

Error numbers:

Parameters:
  • attr – Pointer to the thread attributes object.

  • detachstate – Pointer to a location where the detach state attribute will be stored.

Returns:

0 on success, or an error number on failure.

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)

Record the detach state in attr.

Error numbers:

Parameters:
Returns:

0 on success, or an error number on failure.

#include <pthread.h>

void *worker(void *arg);

void start_worker(void)
{
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    pthread_create(NULL, &attr, worker, NULL);
    pthread_attr_destroy(&attr);
}

int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize)

Read the stack base and size stored in attr.

A NULL stack base means pthread_create() will allocate the stack from the kernel pool.

Error numbers:

  • EINVAL: attr, stackaddr or stacksize is NULL.

Parameters:
  • attr – Pointer to the thread attribute object.

  • stackaddr – Pointer to the stack base address.

  • stacksize – Pointer to a size_t variable where the stack size will be stored.

Returns:

0 on success, or an error number on failure.

int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize)

Record a caller-provided stack region in attr.

Both the base address and the size must be 8-byte aligned, and the size must be at least PTHREAD_STACK_MIN and at most 1 GiB. With MPU support the stack must also form a valid MPU region, or pthread_create() fails with EINVAL. On ARMv6-M and ARMv7-M the size must be a power of two and the base aligned to the size; on ARMv8-M both must be multiples of 32 bytes.

Error numbers:

  • EINVAL: attr or stackaddr is NULL, stacksize is below PTHREAD_STACK_MIN or above 1 GiB, or either is not 8-byte aligned.

Parameters:
  • attr – Pointer to the thread attribute object.

  • stackaddr – Pointer to the stack base address.

  • stacksize – Stack size.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>
#include <stdint.h>

uint64_t worker_stack[256] __attribute__((aligned(2048)));

void *worker(void *arg);

void start_worker(void)
{
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setstack(&attr, worker_stack, sizeof(worker_stack));
    pthread_create(NULL, &attr, worker, NULL);
    pthread_attr_destroy(&attr);
}

int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)

Read the stack size stored in attr.

Error numbers:

  • EINVAL: attr or stacksize is NULL.

Parameters:
  • attr – Pointer to the thread attribute object.

  • stacksize – Pointer to a size_t variable where the stack size will be stored.

Returns:

0 on success, or an error number on failure.

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)

Record a requested stack size in attr.

pthread_create() allocates the stack from the thread stack pool. With MPU support the size is rounded up to form a valid MPU region: on ARMv6-M and ARMv7-M to the next power of two, taking twice that from the pool so the stack can be aligned to its size; on ARMv8-M to a multiple of 32 bytes, taking 32 bytes more. The size must be 8-byte aligned, at least PTHREAD_STACK_MIN and at most 1 GiB.

Error numbers:

Parameters:
  • attr – Pointer to the thread attribute object.

  • stacksize – Stack size.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

void *worker(void *arg);

void start_worker(void)
{
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, 4096u);
    pthread_create(NULL, &attr, worker, NULL);
    pthread_attr_destroy(&attr);
}

int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)

Read the scheduling policy stored in attr.

Error numbers:

  • EINVAL: attr or policy is NULL.

Parameters:
  • attr – Pointer to the thread attributes object.

  • policy – Pointer to a location where the scheduling policy attribute will be stored.

Returns:

0 on success, or an error number on failure.

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)

Record a scheduling policy in attr.

The default policy set by pthread_attr_init() is SCHED_RR.

Error numbers:

Parameters:
  • attr – Pointer to the thread attributes object.

  • policy – The scheduling policy attribute to set. One of:

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

void *worker(void *arg);

void start_worker(void)
{
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
    pthread_create(NULL, &attr, worker, NULL);
    pthread_attr_destroy(&attr);
}

int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)

Read the scheduling parameters stored in attr into param.

Error numbers:

  • EINVAL: attr or param is NULL.

Parameters:
  • attr – Pointer to the thread attributes object.

  • param – Pointer to a location where the scheduling parameters will be stored.

Returns:

0 on success, or an error number on failure.

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)

Record a scheduling-parameter block in attr.

The requested priority must lie strictly above the idle priority and must not exceed sched_get_priority_max(). Idle priority is reserved for the kernel and cannot be assigned to threads; it is also the floor for priority promotions applied to threads that hold mutexes with priority ceiling or inheritance protocols. On failure attr is unchanged.

Error numbers:

Parameters:
  • attr – Pointer to the thread attributes object.

  • param – Pointer to the scheduling parameters to set.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

void *worker(void *arg);

void start_worker(void)
{
    pthread_attr_t     attr;
    struct sched_param param;

    param.sched_priority = 10;

    pthread_attr_init(&attr);
    pthread_attr_setschedparam(&attr, &param);
    pthread_create(NULL, &attr, worker, NULL);
    pthread_attr_destroy(&attr);
}

int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)

Not supported.

Returns:

ENOSYS.

int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)

Not supported.

Returns:

ENOSYS.

int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)

Not supported.

Returns:

ENOSYS.

int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)

Not supported.

Returns:

ENOSYS.

int pthread_attr_getname_np(const pthread_attr_t *attr, char *name, size_t len)

Copy the thread name stored in attr into name, truncating to len bytes and ensuring null termination.

At most 16 bytes, including the terminating null, are copied.

Error numbers:

  • EINVAL: attr or name is NULL.

  • ERANGE: len is 0; nothing is written to name.

Parameters:
  • attr – Pointer to the thread attributes object.

  • name – Pointer to a buffer to store the thread name.

  • len – Length of the buffer.

Returns:

0 on success, or an error number on failure.

int pthread_attr_setname_np(pthread_attr_t *attr, const char *name)

Record a thread name in attr.

The name is copied into attr and truncated to 15 characters if longer.

Error numbers:

  • EINVAL: attr or name is NULL.

Parameters:
  • attr – Pointer to the thread attributes object.

  • name – The name to set for the thread.

Returns:

0 on success, or an error number on failure.

int pthread_attr_setprivilege_np(pthread_attr_t *attr, int privilege)

Record the MPU privilege level that threads created from attr will run with.

Available only on builds with MPU support; the default produced by pthread_attr_init() is PTHREAD_UNPRIVILEGED_NP.

Error numbers:

Parameters:
Returns:

0 on success, or an error number on failure.

#include <pthread.h>

void *worker(void *arg);

void start_worker(void)
{
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setprivilege_np(&attr, PTHREAD_PRIVILEGED_NP);
    pthread_create(NULL, &attr, worker, NULL);
    pthread_attr_destroy(&attr);
}

int pthread_attr_getprivilege_np(pthread_attr_t *attr, int *privilege)

Read the privilege level stored in attr.

Error numbers:

  • EINVAL: attr or privilege is NULL.

Parameters:
Returns:

0 on success, or an error number on failure.

int pthread_setprivilege_np(pthread_t thread, int privilege)

Change the MPU privilege level of a live thread.

For the calling thread the change takes effect immediately; for another thread the change applies the next time that thread runs. Only privileged threads may call this. The initial main thread starts privileged; drop its privilege with this call if it is not needed.

Error numbers:

Parameters:
Returns:

0 on success, or an error number on failure.

#include <pthread.h>
#include <qrt.h>
#include <time.h>

volatile unsigned int idle_count;
unsigned int          idle_snapshot;

void count_idle(void)
{
    idle_count++;
}

void *main_thread(void *arg)
{
    struct timespec period = { 0, 10000000L };

    (void)arg;
    (void)qrt_kernel_idlehookregister(count_idle);
    (void)pthread_setprivilege_np(pthread_self(), PTHREAD_UNPRIVILEGED_NP);

    for (;;)
    {
        idle_snapshot = idle_count;
        (void)nanosleep(&period, NULL);
    }
    return NULL;
}

int pthread_setname_np(pthread_t thread, const char *name)

Update the human-readable name of a running thread.

The name buffer is allocated on demand from the kernel heap and the string is copied in, so the call can fail when memory is exhausted.

Error numbers:

  • EINVAL: thread or name is NULL.

  • ENOMEM: The thread name buffer could not be allocated.

Parameters:
  • thread – The thread to set the name of.

  • name – The new name for the thread.

Returns:

0 on success, or an error number on failure.

int pthread_getname_np(pthread_t thread, char *name, size_t len)

Copy a running thread’s name into name, truncating to len bytes and ensuring null termination.

Error numbers:

  • EINVAL: thread or name is NULL.

  • ERANGE: len is 0; nothing is written to name.

Parameters:
  • thread – The thread to get the name of.

  • name – Pointer to a buffer to store the thread name.

  • len – Length of the buffer.

Returns:

0 on success, or an error number on failure.

int pthread_setfpcontext_np(int context)

Enable or disable FPU context tracking for the calling thread.

With PTHREAD_FPCONTEXT_ENABLE_NP, the calling thread is marked as an FPU-using thread: every subsequent context switch involving it preserves the full floating-point register file (S0-S31 and FPSCR), a cost paid only for threads that actually use the FPU. With PTHREAD_FPCONTEXT_DISABLE_NP, the kernel stops saving and restoring the upper floating-point register bank (S16-S31 and FPSCR) on context switches involving this thread. Acts on the calling thread only.

#include <pthread.h>

float level;

void *worker(void *arg)
{
    pthread_setfpcontext_np(PTHREAD_FPCONTEXT_ENABLE_NP);

    level = level * 0.5f;

    pthread_setfpcontext_np(PTHREAD_FPCONTEXT_DISABLE_NP);

    return NULL;
}

Warning

After disabling, the thread must not use any FPU instructions unless FPU access is explicitly re-enabled with pthread_setfpcontext_np. Failing to do so may result in data corruption or undefined behavior.

Parameters:
Returns:

0 on success, EINVAL if context is not a valid value, or ENOSYS if FPU context support is not compiled in.

int pthread_getconcurrency(void)

Not supported.

Returns:

ENOSYS.

int pthread_setconcurrency(int new_level)

Not supported.

Returns:

ENOSYS.

int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))

Not supported.

Returns:

ENOSYS.

void *pthread_getspecific(pthread_key_t key)

Return the value the calling thread has associated with key.

Returns NULL when key is out of range or the thread has not stored a value.

Parameters:
  • key – The key to get the thread-specific data for.

Returns:

The thread-specific data associated with the key, or NULL if not set.

int pthread_setspecific(pthread_key_t key, const void *value)

Bind value to key for the calling thread.

The previous association is overwritten without invoking the destructor.

Parameters:
  • key – The key to set the thread-specific data for.

  • value – The thread-specific data to associate with the key.

Returns:

0 on success, or EINVAL if the key is not valid.

int pthread_key_create(pthread_key_t *key, void (*destructor)(void *value))

Allocate a thread-specific data key with an optional destructor.

The destructor (if non-NULL) is invoked at thread exit for every thread that has stored a non-NULL value under this key. Each thread’s association is cleared before the destructor runs, so destructors do not cascade. Destructors run in kernel context while the thread terminates, and no thread runs until they return, so they must not block or call kernel services. With MPU support only privileged threads can register a destructor; unprivileged threads can still create keys without one. Keys live in a fixed-size table sized by PTHREAD_KEYS_MAX.

Error numbers:

  • EINVAL: key is NULL.

  • EPERM: destructor is non-NULL and the caller is unprivileged (only with MPU support).

  • EAGAIN: No free slot in the key table.

Parameters:
  • key – Pointer to the key to be created.

  • destructor – Pointer to a destructor function to be called when a thread exits.

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

pthread_key_t count_key;

void count_event(void)
{
    unsigned int *count;

    count = pthread_getspecific(count_key);
    (*count)++;
}

void *worker(void *arg)
{
    pthread_setspecific(count_key, arg);

    for (;;)
    {
        count_event();
    }

    return NULL;
}

void start_workers(unsigned int *count_a, unsigned int *count_b)
{
    if (pthread_key_create(&count_key, NULL) == 0)
    {
        pthread_create(NULL, NULL, worker, count_a);
        pthread_create(NULL, NULL, worker, count_b);
    }
}

int pthread_key_delete(pthread_key_t key)

Release key so it can be reused.

Existing per-thread values are not freed and no destructors are run; the caller must release any owned resources before deleting the key.

Parameters:
  • key – The key to be deleted.

Returns:

0 on success, or EINVAL if the key is not valid.

int pthread_kill(pthread_t thread, int sig)

Not supported.

Returns:

ENOSYS.

int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))

Guarantee init_routine runs at most once across all threads that share once_control.

The first caller observing the control object in its initial state runs the routine and marks the control as completed; later callers return immediately. The control object must have been initialized with PTHREAD_ONCE_INIT; any other value counts as completed. The routine runs in kernel context on behalf of that caller, and no thread runs until it returns, so it must not block or call kernel services.

With MPU support only a privileged thread can run the routine. While the control object is in its initial state, an unprivileged caller gets EPERM, the routine does not run and the control object is left unchanged; once it is completed, unprivileged callers return 0 as well. Make the first call from a privileged thread, for example during start-up.

Error numbers:

  • EINVAL: once_control or init_routine is NULL.

  • EPERM: once_control is in its initial state and the caller is unprivileged (only with MPU support).

Returns:

0 on success, or an error number on failure.

#include <pthread.h>

pthread_once_t table_once = PTHREAD_ONCE_INIT;
int            table[16];

void table_init(void)
{
    int i;

    for (i = 0; i < 16; i++)
    {
        table[i] = i * i;
    }
}

int table_get(int index)
{
    pthread_once(&table_once, table_init);

    return table[index];
}

int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)

Not supported.

Returns:

ENOSYS.

int pthread_getcpuclockid(pthread_t thread_id, clockid_t *clock_id)

Not supported.

Returns:

ENOSYS.

int pthread_spin_destroy(pthread_spinlock_t *lock)

Not supported.

Returns:

ENOSYS.

int pthread_spin_init(pthread_spinlock_t *lock, int pshared)

Not supported.

Returns:

ENOSYS.

int pthread_spin_lock(pthread_spinlock_t *lock)

Not supported.

Returns:

ENOSYS.

int pthread_spin_trylock(pthread_spinlock_t *lock)

Not supported.

Returns:

ENOSYS.

int pthread_spin_unlock(pthread_spinlock_t *lock)

Not supported.

Returns:

ENOSYS.

int pthread_barrier_destroy(pthread_barrier_t *barrier)

Not supported.

Returns:

ENOSYS.

int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count)

Not supported.

Returns:

ENOSYS.

int pthread_barrier_wait(pthread_barrier_t *barrier)

Not supported.

Returns:

ENOSYS.

int pthread_barrierattr_destroy(pthread_barrierattr_t *attr)

Not supported.

Returns:

ENOSYS.

int pthread_barrierattr_init(pthread_barrierattr_t *attr)

Not supported.

Returns:

ENOSYS.

int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared)

Not supported.

Returns:

ENOSYS.

int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_clockrdlock(pthread_rwlock_t *rwlock, clockid_t clock_id, const struct timespec *abstime)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const struct timespec *abstime)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_clockwrlock(pthread_rwlock_t *rwlock, clockid_t clock_id, const struct timespec *abstime)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *abstime)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)

Not supported.

Returns:

ENOSYS.

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)

Not supported.

Returns:

ENOSYS.

int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)

Not supported.

Returns:

ENOSYS.

int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)

Not supported.

Returns:

ENOSYS.

int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *pshared)

Not supported.

Returns:

ENOSYS.

int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared)

Not supported.

Returns:

ENOSYS.

int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)

Not supported.

Returns:

ENOSYS.

int pthread_cond_destroy(pthread_cond_t *cond)

Not supported.

Returns:

ENOSYS.

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

Not supported.

Returns:

ENOSYS.

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)

Not supported.

Returns:

ENOSYS.

int pthread_cond_signal(pthread_cond_t *cond)

Not supported.

Returns:

ENOSYS.

int pthread_cond_broadcast(pthread_cond_t *cond)

Not supported.

Returns:

ENOSYS.

int pthread_condattr_init(pthread_condattr_t *attr)

Not supported.

Returns:

ENOSYS.

int pthread_condattr_destroy(pthread_condattr_t *attr)

Not supported.

Returns:

ENOSYS.

int pthread_condattr_getclock(const pthread_condattr_t *attr, clockid_t *clock_id)

Not supported.

Returns:

ENOSYS.

int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)

Not supported.

Returns:

ENOSYS.

int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared)

Not supported.

Returns:

ENOSYS.

int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)

Not supported.

Returns:

ENOSYS.

int pthread_attr_settimeslice_np(pthread_attr_t *attr, const struct timespec *time_slice)

Record the round-robin time slice that threads created from attr will run with.

The duration is converted to ticks at thread creation; only meaningful when the policy is SCHED_RR.

Error numbers:

  • EINVAL: attr or time_slice is NULL, time_slice is not a valid timespec, or it is shorter than QRT_CFG_SCHED_TIME_SLICE_MIN_US (100 us by default).

Parameters:
  • attr – Pointer to the thread attribute object.

  • time_slice – Pointer to a timespec structure that specifies the time slice duration.

Returns:

0 on success, or an error number on failure.

int pthread_attr_gettimeslice_np(pthread_attr_t *attr, struct timespec *time_slice)

Read the round-robin time slice stored in attr.

Error numbers:

  • EINVAL: attr or time_slice is NULL.

Parameters:
  • attr – Pointer to the thread attribute object.

  • time_slice – Pointer to a timespec structure that specifies the time slice duration.

Returns:

0 on success, or an error number on failure.

Limits

PTHREAD_STACK_MIN (512u)

Minimum size, in bytes, for a thread’s stack.

Stack sizes passed to pthread_attr_setstacksize() or pthread_attr_setstack() must be at least this value.