--- Cannot embed stylesheet: [Errno 2] No such file or directory: '../../../aros.css' --->
int pthread_attr_destroy( pthread_attr_t *attr)
Clear a thread attribute object after its last use. This implementation zeroes the object and does not free any memory.
attr - Non-NULL writable attribute object that is no longer in use.
0 on success; EINVAL if attr is NULL. Errors are returned directly.
Include <pthread.h>; link with pthread. The call does not block or affect an existing worker, whose attributes were copied at creation. A caller-supplied stack remains caller-owned and is not released. Reinitialize the object before using it for another creation request; a zeroed object is not equivalent to pthread_attr_init() defaults. Exclude concurrent access while destroying it.
int pthread_attr_getaffinity_np( const pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset)
Return the CPUs that threads created with attr may run on.
attr - Initialized attribute object. cpusetsize - Size of *cpuset in bytes. cpuset - Receives the CPUs.
0 on success; EINVAL if attr or cpuset is NULL, or if a set made with pthread_attr_setaffinity_np() does not fit in cpusetsize bytes. Errors are returned directly.
Include <pthread.h>; link with pthread. Non-portable (glibc). If no set was given with pthread_attr_setaffinity_np(), every CPU is returned (the thread then inherits its creator's affinity).
int pthread_attr_getdetachstate( const pthread_attr_t *attr, int *detachstate)
Read the detach state stored in a thread attribute object.
attr - Initialized thread attributes.
detachstate - Optional output for PTHREAD_CREATE_JOINABLE or
PTHREAD_CREATE_DETACHED; NULL suppresses the write.
0 on success; EINVAL if attr is NULL.
Reads the stored field; it does not inspect any running thread. Errors are returned directly.
int pthread_attr_getschedparam( const pthread_attr_t *attr, struct sched_param *param)
Read the scheduling parameters stored in a thread attribute object.
attr - Initialized thread attributes.
param - Optional writable struct sched_param receiving a copy of the
stored parameters.
0 on success; EINVAL if attr is NULL.
This is a copy of the attribute field, not a query of the task scheduler. A NULL output pointer is accepted.
int pthread_attr_getstack( const pthread_attr_t *attr, void **stackaddr, size_t *stacksize)
Read the requested stack address and size from thread attributes.
attr - Initialized attributes.
stackaddr - Optional output receiving the stored stack pointer; may be
NULL.
stacksize - Optional output receiving the stored size in bytes; may be
NULL.
0 on success; EINVAL if attr is NULL.
The values describe an attribute object, not the current stack of a live thread. No allocation or validation occurs.
int pthread_attr_getstacksize( const pthread_attr_t *attr, size_t *stacksize)
Read the stack size stored in thread attributes.
attr - Initialized attributes.
stacksize - Optional output for the stored byte count; NULL is
accepted.
The result of pthread_attr_getstack(attr, NULL, stacksize): 0 or EINVAL.
This function does not query a running task or determine a minimum usable stack size.
int pthread_attr_init( pthread_attr_t *attr)
Initialize a caller-provided thread attribute object. Clear its fields, select a joinable worker with no supplied stack, copy the current task priority, and set the stack size to the current task's stack extent.
attr - Non-NULL writable attribute object to initialize.
0 on success; EINVAL if attr is NULL. Errors are returned directly.
Include <pthread.h>; link with pthread. Call in task context. No stack or thread is allocated. The default size comes from tc_SPUpper minus tc_SPLower; it is not a fixed PTHREAD_STACK_MIN allocation. Set an appropriate size explicitly when the new worker needs a different one. pthread_create() copies the object, so it need not outlive creation. Destroy it with pthread_attr_destroy() when no longer needed. Do not modify an object concurrently with a reader.
int pthread_attr_setaffinity_np( pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset)
Set the CPUs that threads created with attr may run on.
attr - Initialized writable attribute object.
cpusetsize - Size of *cpuset in bytes (sizeof(cpu_set_t), or
CPU_ALLOC_SIZE() for a set of another size).
cpuset - The CPUs, numbered as KrnGetCPUNumber() numbers them.
0 on success; EINVAL if attr or cpuset is NULL, or if cpuset names no CPU that exists. Errors are returned directly.
Include <pthread.h>; link with pthread. Non-portable (glibc). CPUs beyond those the system has are ignored. Without this call a new thread inherits its creator's affinity. On a uniprocessor build only CPU 0 exists.
int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate)
Choose whether new threads are joinable or detached.
attr - Initialized attributes to update. detachstate - PTHREAD_CREATE_JOINABLE or PTHREAD_CREATE_DETACHED.
0 on success; EINVAL for a NULL attr or any other detach state.
The selection takes effect when pthread_create() copies these attributes. Changing an attribute object does not detach an existing thread.
int pthread_attr_setschedparam( pthread_attr_t *attr, const struct sched_param *param)
Store scheduling parameters for a subsequently created thread.
attr - Initialized attributes to update. param - Non-NULL scheduling parameters to copy.
0 on success; EINVAL if attr or param is NULL.
The entire struct sched_param is copied. The setter does not validate its priority; thread creation uses the stored priority.
The pthread_create() path does not implement scheduling inheritance or contention-scope controls.
int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize)
Store a stack buffer address and requested size for future thread creation.
attr - Attributes to modify.
stackaddr - Caller-owned stack pointer; NULL selects the
runtime-provided stack.
stacksize - Stack extent in bytes. With a non-NULL stackaddr this must
be nonzero.
0 on success; EINVAL if attr is NULL or a non-NULL stackaddr is paired with zero size.
The function stores the two values without allocating, checking alignment, enforcing PTHREAD_STACK_MIN, or checking actual accessible memory. Keep a supplied buffer valid throughout the worker lifetime.
Not all invalid stack sizes and pointers are rejected by the setter. A successful result does not establish that subsequent thread creation can use the buffer.
int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize)
Set the stack size for subsequent worker creation and clear any previously supplied stack address. This delegates to pthread_attr_setstack(attr, NULL, stacksize).
attr - Initialized writable attribute object.
stacksize - Requested size in bytes. Zero leaves process creation to
use its default stack allocation.
0 on success; EINVAL if attr is NULL. Errors are returned directly.
Include <pthread.h>; link with pthread. No memory is allocated, resized or freed. The change affects later pthread_create() calls only. Clearing a supplied stack pointer does not transfer or release that storage. Exclude concurrent access to attr.
All size values are accepted without checking PTHREAD_STACK_MIN, alignment or whether the size can support the worker. Successful attribute assignment does not establish that creation will succeed or that the resulting stack is sufficient.
int pthread_barrier_destroy( pthread_barrier_t *barrier)
Destroy a barrier that has no arriving or departing participants.
barrier - Initialized, externally quiescent barrier.
0 if destruction proceeds; EINVAL for NULL; EBUSY if the mutex cannot be acquired, a generation is active, or the condition destroy fails.
Attempts a nonblocking lock and checks internal generation state before destroying the embedded condition and mutex. Do not reuse the storage without initialization.
A successful probe does not exclude new arrivals; external quiescence is required. The return value from the final mutex destruction is ignored.
int pthread_barrier_init( pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
Initialize a reusable barrier for a fixed number of participating threads.
barrier - Writable barrier storage not currently in use.
attr - Barrier attributes; currently ignored.
count - Number of arrivals required to complete each generation; must
be nonzero.
0 on success; EINVAL if barrier is NULL or count is zero.
Stores count and initializes an embedded condition variable and mutex. All participants must reach the barrier before they can proceed. Caller owns the barrier storage.
The return values of the embedded mutex and condition initializers are not checked. No maximum participant count or overflow guard is enforced.
int pthread_barrier_wait( pthread_barrier_t *barrier)
Wait for all members of a barrier generation and release them together.
barrier - Initialized barrier shared by the participating threads.
PTHREAD_BARRIER_SERIAL_THREAD for the final arrival; 0 for other arrivals after the generation completes; EINVAL for NULL.
Uses an embedded mutex and condition variable. The last arrival broadcasts to waiting peers. A departing generation must finish before the next generation is admitted.
The implementation does not propagate embedded mutex/condition failures. If a participant exits or never arrives, other participants may wait indefinitely.
int pthread_cancel( pthread_t thread)
Mark a live worker as having a pending cancellation request and signal it with SIGBREAKF_CTRL_C. Cancellation takes effect when the worker processes the request with cancellation enabled. Acceptance does not wait for the worker to finish.
thread - Identifier of a live worker created by pthread_create().
Coordinate its lifetime with joining, detaching and other requests.
0 if the request was recorded. ESRCH if no allocated record is found, the record has no parent, or cancellation is already pending. An enabled asynchronous request for the calling worker exits through pthread_testcancel() and does not return. Errors are returned directly.
Include <pthread.h>; link with pthread. A new worker uses enabled, deferred cancellation. Disabled cancellation remains pending. Use pthread_join() on a joinable worker to observe completion and obtain PTHREAD_CANCELED; do not free worker-owned resources on request success. Cleanup handlers run when cancellation reaches pthread_exit().
The default build does not enable USE_ASYNC_CANCEL. Selecting PTHREAD_CANCEL_ASYNCHRONOUS does not make a signal forcibly terminate another worker. Deferred cancellation requires a reached cancellation check; pthread_join() does not repeat that check while blocked. Record access is not serialized here, and finished joinable workers are not rejected by a finished-state check. Passing such an identifier can signal a stale task pointer. Repeated requests return ESRCH even while the target still exists. Do not target the initial program task: it has no worker exit jump point.
void pthread_cleanup_pop( int execute)
Remove the most recently registered cancellation cleanup handler.
execute - Nonzero to invoke the removed handler immediately; zero to
discard it without invocation.
No return value. A missing handler is treated as an empty pop.
Removes the tail record from the current pthread cleanup list, optionally invokes its callback with the stored argument, then frees the record.
No dynamic balancing or thread-identity validation is performed. A previous failed push can leave the pop operating on another registered handler.
void pthread_cleanup_push( void (*routine)(void *), void *arg)
Register a callback to run when the current pthread unwinds its cleanup stack.
routine - Callback that accepts one void * argument; NULL is silently
ignored.
arg - Pointer passed to the callback; must remain valid until
invocation or removal.
No return value. On allocation failure the handler is silently not registered.
Allocates a cleanup record and appends it to the calling thread's list. A matching pthread_cleanup_pop() normally removes the most recently pushed record. These are implemented as callable functions, not lexical pairing macros.
Allocation failure is not reported. If registration fails, a later pop may remove an older handler. Normal return from the thread start routine does not run the cleanup list in this implementation.
int pthread_cond_broadcast( pthread_cond_t *cond)
Signal every registered waiter on cond. If no task is waiting, the call has no retained effect. It does not change the application's predicate or transfer ownership of the associated mutex.
cond - Initialized condition variable, or a supported static initializer.
Its storage must remain valid throughout signalling and all waits.
0 after signalling, including when no waiter is present. EINVAL if cond is NULL. Errors are returned directly.
Include <pthread.h>; link with pthread. Call from task context; acquiring the internal condition semaphore can block. This is not an interrupt or asynchronous signal-handler interface. Protect the predicate with the same mutex used by waiters and recheck it in a loop after waking. A woken task must reacquire that mutex before returning from its wait. Explicit initialization before sharing avoids the lazy-init race.
Signals are task bits, not queued notifications. Repeated broadcasts may coalesce. A waiter remains listed until it has reacquired its mutex, and no ordering or fairness guarantee is provided.
int pthread_cond_destroy( pthread_cond_t *cond)
Clear a condition variable after checking that its internal semaphore is available and its waiter list is empty.
cond - Unused condition variable. Prevent all new waits and signals
before destruction and until its storage has been released.
0 on success, including an uninitialized static condition (left as is). EINVAL if cond is NULL. EBUSY if its semaphore cannot be acquired immediately or its waiter list is nonempty. Errors are returned directly.
Include <pthread.h>; link with pthread. The probe does not wait. No caller storage is freed. Reinitialize before reuse. A waiter remains on the internal list until it has reacquired its application mutex, so a signalled waiter can still make this call report EBUSY.
The implementation releases its semaphore before zeroing the object. The empty-list probe cannot make concurrent destruction safe. Establish that all potential users have finished outside this call.
int pthread_cond_init( pthread_cond_t *cond, const pthread_condattr_t *attr)
Initialize a condition variable with an empty waiter list. Select the absolute-deadline clock from attr, or CLOCK_REALTIME by default.
cond - Non-NULL writable condition storage, not already in use.
attr - Attributes initialized with pthread_condattr_init(), or NULL.
On AROS, CLOCK_REALTIME and CLOCK_MONOTONIC are accepted.
0 on success. EINVAL if cond is NULL or attr specifies an unsupported clock on AROS. Validation failure leaves cond unchanged. Errors are returned directly.
Include <pthread.h>; link with pthread. No waiter or timer is allocated. The caller retains the storage until no task can wait or signal and pthread_cond_destroy() has completed. Attributes are copied and need not outlive the condition. Initialize before publishing to other tasks. Use pthread_condattr_init(), not manual zeroing: clock identifier 0 denotes CLOCK_MONOTONIC on AROS, not the realtime default.
Process-sharing attributes are ignored. Reinitialization of an active condition is not detected. Static lazy initialization elsewhere in this implementation is not serialized against simultaneous first use.
int pthread_cond_signal( pthread_cond_t *cond)
Signal the first registered waiter on cond. If no task is waiting, the call has no retained effect. It does not change the application's predicate or transfer ownership of the associated mutex.
cond - Initialized condition variable, or a supported static initializer.
Its storage must remain valid throughout signalling and all waits.
0 after signalling, including when no waiter is present. EINVAL if cond is NULL. Errors are returned directly.
Include <pthread.h>; link with pthread. Call from task context; acquiring the internal condition semaphore can block. This is not an interrupt or asynchronous signal-handler interface. Protect the predicate with the same mutex used by waiters and recheck it in a loop after waking. A woken task must reacquire that mutex before returning from its wait. Explicit initialization before sharing avoids the lazy-init race.
Signalling does not remove or reserve the selected waiter. Repeated calls before that waiter removes itself can target it again, coalescing signals and leaving other waiters asleep. Do not assume successive calls wake distinct waiters.
int pthread_cond_timedwait( pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
Wait on cond as pthread_cond_wait() does, with an absolute deadline measured against the clock selected at condition initialization. Reacquire mutex before returning from the wait, including on timeout. Test the protected predicate after every return; a zero result does not certify that a condition signal or predicate change occurred.
cond - Initialized condition variable. Defaults to CLOCK_REALTIME;
CLOCK_MONOTONIC is selected through condition attributes.
mutex - Initialized mutex owned exactly once by the caller. Use the
same mutex for the predicate and concurrent waits on cond.
abstime - Absolute deadline with tv_nsec in 0..999999999. This
implementation also accepts NULL for an untimed wait. The value
is read during setup and is not retained after the call.
0 after a nontimeout wake; ETIMEDOUT if the timer signal was observed. EINVAL for NULL cond/mutex, an invalid nanosecond field, failure to open timer.device, or failure to read the selected clock. Setup errors occur before releasing mutex. Errors are returned directly. Cancellation can exit the worker after the mutex has been reacquired.
Include <pthread.h>; link with pthread. Call from the initial program task or a registered worker. Keep both objects valid through all waits. The wait creates a timer request and closes it before returning. Reacquiring mutex may block past the deadline; this is not a bound on return time. Install cancellation cleanup that releases mutex. The deadline is converted once to a relative timer interval. Later changes to the realtime clock do not adjust it. Nonpositive intervals are changed to 1 ms. Positive fractions are truncated to microseconds, with a minimum timer request of 1 microsecond.
If timeout, condition and cancellation signals arrive together, timeout takes precedence and cancellation is not tested on that return. Mutex lock/unlock failures are ignored. Multiple recursive acquisitions do not fully release mutex. Signal-allocation failure uses CTRL_D for the timer and CTRL_E for the condition; those bits are not cleared by the fallback setup and can collide with application signal use. Explicit initialization before sharing avoids unsynchronized lazy init.
int pthread_cond_timedwait_relative_np( pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *reltime)
Wait on a condition variable using a relative time interval.
cond - Initialized condition variable.
mutex - Locked mutex associated with the condition.
reltime - Relative duration passed to the shared condition-wait
implementation.
Returns the status of _pthread_cond_timedwait(), including timeout and argument errors established by that implementation.
Calls the existing condition-wait helper with relative mode enabled. The caller must hold the mutex and recheck its shared predicate after waking; cancellation can exit the worker.
int pthread_cond_wait( pthread_cond_t *cond, pthread_mutex_t *mutex)
Register the caller as a waiter, release one acquisition of mutex, wait for a condition or CTRL_C signal, and reacquire mutex before removing the waiter. A return does not establish that the application's predicate is true; always test it again while holding mutex.
cond - Initialized condition variable, or a supported static initializer.
mutex - Initialized mutex owned exactly once by the calling task.
Use the same mutex for all concurrent waits on cond and for the
protected predicate. Retain both objects until all users finish.
0 after waking and reacquiring a valid mutex. EINVAL if cond or mutex is NULL. Errors are returned directly. Pending enabled cancellation observed after a CTRL_C wake exits the worker instead of returning.
// mutex is locked; ready is protected by mutex.
int error = 0;
while (!ready) {
error = pthread_cond_wait(&cond, &mutex);
if (error != 0)
break;
}
// Examine ready or handle the error before using protected data.
Include <pthread.h>; link with pthread. Call from the initial program task or a registered worker. There is no timeout. The mutex is reacquired before cancellation cleanup; arrange for a cleanup handler to release it. Other CTRL_C wakes can produce a zero result without a condition signal. This implementation does not return EINTR for those wakes. Initialize the objects before concurrent use.
Mutex ownership and matching are not validated, and lock/unlock errors are ignored. Waiting while holding multiple recursive acquisitions does not fully release the mutex and can deadlock other participants. Signal allocation failure uses the task's CTRL_E bit; the fallback does not clear an already pending bit and can consume unrelated use of that signal. Unregistered tasks cannot safely process cancellation.
int pthread_condattr_destroy( pthread_condattr_t *attr)
Clear a condition-variable attribute object after use.
attr - Initialized condition attribute object no longer needed.
0 on success; EINVAL if attr is NULL.
Zeros the attribute storage. It does not deallocate the caller-owned object or affect condition variables already initialized from it.
int pthread_condattr_getclock( const pthread_condattr_t *attr, clockid_t *clock_id)
Read the deadline clock selected in condition attributes.
attr - Initialized condition attributes. clock_id - Non-NULL writable output for the clock ID.
0 on success; EINVAL if either pointer is NULL.
Reports the stored field. It does not query timer.device or the clock currently used by a running wait.
int pthread_condattr_init( pthread_condattr_t *attr)
Initialize condition-variable attributes with the default realtime clock.
attr - Writable condition attribute object.
0 on success; EINVAL if attr is NULL.
Clears the object and sets cond_clock to CLOCK_REALTIME when the symbol is available. Initialize attributes before passing them to pthread_cond_init().
int pthread_condattr_setclock( pthread_condattr_t *attr, clockid_t clock_id)
Select the clock used to interpret an absolute condition-wait deadline.
attr - Initialized condition attribute object. clock_id - CLOCK_REALTIME or CLOCK_MONOTONIC.
0 on success; EINVAL if attr is NULL or clock_id is unsupported.
Stores the chosen clock. pthread_cond_init() copies it into the condition variable; changing attributes later does not change existing conditions.
int pthread_create( pthread_t *thread, const pthread_attr_t *attr, void *(*start)(void *), void *arg)
Start a worker running start(arg). The worker may execute before this call returns. A normal return from start stores its pointer result for pthread_join(); pthread_exit() also runs registered cleanup handlers. The attributes are copied. With NULL attributes, the worker is joinable, uses the creator's priority and stack extent, and starts with deferred cancellation enabled. A joinable worker retains its slot until joined; a detached worker releases its slot when it finishes.
thread - Non-NULL writable output for the new thread identifier.
attr - Initialized attributes, or NULL for defaults. May be destroyed
after this call. A supplied stack remains caller-owned and must
remain valid until the worker has finished using it.
start - Non-NULL worker entry point. Receives arg unchanged.
arg - Borrowed argument pointer, which may be NULL. Its storage and
everything reachable through it must outlive the worker's use.
0 on success; *thread receives the identifier. EINVAL if thread or start is NULL. EAGAIN if no slot is available, a thread record cannot be allocated, or the process-creation result is observed as NULL. On error, *thread is unchanged. Errors are returned directly.
Include <pthread.h> and link with the pthread link library. Call from task context with its runtime initialized. Creation can wait for the internal thread semaphore and system allocation; it has no timeout. The worker runs in a DOS process and applies attr's scheduling priority. Scheduling inheritance and contention-scope fields are not implemented by this creation path. The start routine must return a pointer whose lifetime permits its eventual use by the joiner, not worker-stack data. Worker exit runs non-NULL thread-specific destructors before releasing its C runtime. Destructors are skipped during program-wide teardown. Join or detach every successfully created joinable worker. Identifiers are reused; they are not permanent handles.
An immediately finishing detached worker can clear its record before the creator tests inf->task after releasing the thread semaphore. Thus an EAGAIN result does not establish that the entry point never ran. Returning from start bypasses the cleanup-handler list in this implementation. Use balanced cleanup operations or pthread_exit() when those handlers must run.
int pthread_detach( pthread_t thread)
Detach a thread so that its identifier slot can be released without joining.
thread - Identifier of the worker to detach.
0 on success; ESRCH if the slot or its task is unavailable; EINVAL if the thread is already detached.
A running detached worker releases its slot on exit. An already-finished joinable worker has its slot cleared immediately. No implicit pthread_join() is performed.
Identifier records may be reused, and the initial program task is not excluded by an explicit worker-only check. Synchronize lifecycle operations and avoid stale identifiers.
int pthread_equal( pthread_t t1, pthread_t t2)
Compare two thread identifier values. This implementation compares the numeric identifiers without looking up either thread.
t1 - First thread identifier. t2 - Second thread identifier.
Nonzero (1) if the values are equal; 0 otherwise. No errors are reported.
Include <pthread.h>; link with pthread. This call neither blocks nor changes thread state. Equality does not prove that a thread exists or is still running. An identifier may be reused after its slot is released, so equal values obtained at different times need not name the same worker lifetime.
void pthread_exit( void *value_ptr)
Finish the calling worker with value_ptr as its result. Run registered cleanup handlers in reverse registration order, then return control to the worker starter without returning to this caller. The starter runs thread-specific destructors and C runtime leave hooks before marking the worker finished or releasing its detached record.
value_ptr - Result pointer to make available to pthread_join(); may be
NULL. The pointer is stored unchanged, not copied or freed. Any
pointed-to result must remain valid after the worker's stack and
runtime have been released.
Does not return for a worker created by pthread_create().
Include <pthread.h>; link with pthread. Call only from a registered worker after its entry point has started. Cleanup handlers run in that worker's context and must return normally. Their execution can block. Held mutexes and other application resources are not released automatically; arrange explicit cleanup before exiting. Non-NULL thread-specific values with destructors are cleared before invocation. Reinstalled values can cause further passes, up to PTHREAD_DESTRUCTOR_ITERATIONS. Program-wide teardown skips these destructors. A joinable completion record remains until joined.
The initial program task has no initialized exit jump point. Calling pthread_exit() there, or from an unregistered task, is unsupported. TLS destructors run while the runtime holds its shared TLS semaphore; creating or deleting keys from a destructor can contend for an exclusive acquisition and must not be relied on.
int pthread_getaffinity_np( pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset)
Return the CPUs a running thread may run on.
thread - Registered pthread identifier (pthread_self() for the
caller).
cpusetsize - Size of *cpuset in bytes.
cpuset - Receives the CPUs, numbered as KrnGetCPUNumber() numbers
them.
0 on success; ESRCH if thread is not a live thread; EINVAL if cpuset is NULL or too small for the system's CPUs; ENOMEM if no CPU mask could be allocated. Errors are returned directly.
Include <pthread.h>; link with pthread. Non-portable (glibc). On a uniprocessor build the set is always CPU 0.
int pthread_getattr_np( pthread_t thread, pthread_attr_t *attr)
Snapshot the attributes of a registered pthread and its current stack extent.
thread - Registered pthread identifier. attr - Non-NULL writable output attributes.
0 on success; EINVAL if attr is NULL; ESRCH if thread lookup fails.
Copies the attributes captured at creation, then replaces stackaddr with tc_SPLower and stacksize with tc_SPUpper - tc_SPLower from the current Exec task. The result is a snapshot, not a live object.
No live-task guard or synchronization protects the task stack fields. A stale identifier can dereference an invalid task. No atomic snapshot against an in-progress stack swap is guaranteed.
int pthread_getname_np( pthread_t thread, char *name, size_t len)
Copy the current Exec task name for a pthread into a caller-owned buffer.
thread - Registered pthread identifier. name - Non-NULL writable output buffer. len - Capacity of name in bytes, including the trailing NUL.
0 on success; ERANGE if name is NULL, len is zero, the identifier cannot be located, or the destination is too small.
Copies the NUL-terminated task name after comparing strlen(name)+1 against len. No destination bytes are written when that size check fails.
The task pointer and source string are not protected against concurrent task completion or renaming.
int pthread_getschedparam( pthread_t thread, int *policy, struct sched_param *param)
Report the current Exec priority for a pthread and a fixed scheduling policy.
thread - Allocated pthread identifier.
policy - Non-NULL output; receives SCHED_NORMAL.
param - Non-NULL output; sched_priority receives the Exec task
priority.
0 on success; EINVAL if either output is NULL; ESRCH if thread lookup fails.
Reads tc_Node.ln_Pri directly from the associated task. Other fields of *param are not initialized by this function.
The task pointer is not checked for NULL before dereference. A finished or invalidated slot can therefore cause invalid memory access.
void *pthread_getspecific( pthread_key_t key)
Read the calling thread's pointer slot for key. The pointer is returned unchanged; the call neither copies nor frees the pointed-to data.
key - Live key allocated by pthread_key_create(), with its lifetime
protected against concurrent deletion and reuse.
The stored pointer, or NULL if the slot is NULL or key is outside 0..PTHREAD_KEYS_MAX-1. There is no separate error result.
Include <pthread.h>; link with pthread. This is a nonblocking slot read. A new worker's slots start as NULL. A task that is not a pthread (another program calling into a shared library, a raw subtask) has slots of its own, and its destructors never run. Values belong to the application and remain valid only for the lifetime established by that application.
The call does not check whether an in-range key is allocated. Deleting or recreating a key does not clear old slot contents, so it can return a stale pointer.
int pthread_join( pthread_t thread, void **value_ptr)
Wait for a joinable worker to finish, optionally copy its result pointer, and release its thread record for reuse. A worker that has already finished is collected without waiting for another completion signal.
thread - Valid joinable worker identifier. Must not identify the caller.
Exactly one caller may join it; do not detach it concurrently.
value_ptr - Writable pointer output, or NULL to discard the result.
The result is the start routine's return value, the value passed
to pthread_exit(), or PTHREAD_CANCELED after cancellation.
0 after collection. ESRCH if the record is absent or no longer active. EINVAL if it is detached, or changes identity/state before collection. On failure, value_ptr is not written. Errors are returned directly. Pending enabled cancellation at the entry check exits the caller.
Include <pthread.h>; link with pthread. Call from the initial program task or a registered worker, in task context. The wait has no timeout. The result is copied, not freed; arranging its lifetime and disposal remains the application's responsibility. Successful collection ends the identifier's lifetime. Worker destructors and runtime leave hooks precede the completion indication.
Self-join is not detected and can block indefinitely. Multiple joiners overwrite the single waiter field and can strand earlier callers. Cancellation is checked only before entering the wait loop. The loop waits for SIGBREAKF_CTRL_F, not the CTRL_C cancellation signal, and does not recheck cancellation after waking. This call cannot be relied on as an interruptible wait. It also consumes that task signal.
int pthread_key_create( pthread_key_t *key, void (*destructor)(void *))
Reserve the lowest free thread-specific key and associate an optional destructor with it. Each registered thread has a separate pointer slot for the key. Allocation is limited to PTHREAD_KEYS_MAX (64) keys shared by this pthread runtime.
key - Non-NULL writable output for the allocated key.
destructor - Callback for non-NULL values at worker exit, or NULL.
Keep the callback code valid for every possible invocation.
0 on success, with *key set. EINVAL if key is NULL; EAGAIN if every key is in use. The output is unchanged on failure. Errors are returned directly.
Include <pthread.h>; link with pthread. Allocation can wait for the TLS semaphore. Creating a key does not allocate or take ownership of values. Set each thread's value with pthread_setspecific(). The application must eventually delete the key after its users have finished. At normal worker exit, a non-NULL value is cleared before its destructor is called in the exiting worker. A destructor may install another value; at most PTHREAD_DESTRUCTOR_ITERATIONS passes are made. Values without a destructor are not freed. Program-wide teardown skips destructors.
Reusing a deleted key does not clear old per-thread values. A thread can read a stale pointer, and the new destructor can receive it. Avoid reuse while any surviving thread may retain a value for that slot. Destructors execute under the shared TLS semaphore. Key creation and deletion require exclusive acquisition; do not rely on those operations from a destructor. Initial-task exit does not use the worker destructor path.
int pthread_key_delete( pthread_key_t key)
Release a thread-specific storage key for future reuse.
key - Previously allocated key below PTHREAD_KEYS_MAX.
0 if a used key is marked free; EINVAL if the key is out of range or already unused.
The key table is protected by its internal semaphore. Deletion clears the registered destructor but does not invoke it or free values stored by individual threads.
int pthread_kill( pthread_t thread, int sig)
Provide the pthread_kill entry point without signal delivery support.
thread - Thread identifier; ignored. sig - Signal number; ignored.
Always returns EINVAL. No signal is delivered.
The present implementation contains only a diagnostic trace and the EINVAL return. Do not use it to probe thread existence or deliver POSIX signals.
Signal delivery is not implemented for this entry point.
int pthread_mutex_destroy( pthread_mutex_t *mutex)
Clear an unused mutex after checking that its semaphore can be acquired and no condition wait is recorded. No caller-owned storage is freed.
mutex - Unlocked mutex with no users or waiters. Prevent new operations
for the entire destruction and storage-release interval.
0 on success, including an uninitialized static semaphore (left as is). EINVAL if mutex is NULL. EBUSY if AttemptSemaphore() fails or the condition-wait count is nonzero. Errors are returned directly.
Include <pthread.h>; link with pthread. The ownership probe does not wait. An initialized mutex is zeroed after the probe is released. Reinitialize before reuse. EBUSY is a diagnostic, not a substitute for establishing that all potential users have finished.
Exec permits recursive acquisition by the owner, so the probe does not reject a mutex still held by the caller. It can report success and clear that live lock. Concurrent acquisition after the probe is also not excluded by the implementation. Destroy only after external quiescence.
int pthread_mutex_init( pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Initialize a mutex's embedded Exec semaphore, copy its kind from attr (or use PTHREAD_MUTEX_DEFAULT), and clear its condition-wait count.
mutex - Non-NULL writable mutex storage that is not already in use. attr - Initialized mutex attributes, or NULL for the default kind.
0 on success; EINVAL if mutex is NULL. Errors are returned directly.
Include <pthread.h>; link with pthread. The caller owns the storage and must retain it until the unlocked, unused mutex has been destroyed. No heap storage is allocated. Initialize before publishing the mutex to other tasks. Attributes are copied and may then be destroyed. Reinitializing a live mutex is invalid; no busy check is performed.
The supplied kind is not validated here. Process-sharing attributes are ignored. Lazy initialization of static mutexes is not serialized, so explicit initialization before concurrent use avoids that race.
int pthread_mutex_lock( pthread_mutex_t *mutex)
Acquire a mutex, waiting for its current owner to release it if needed. A recursive mutex increments its nesting count when acquired by its owner. Initialize a static mutex lazily if its semaphore is uninitialized.
mutex - Initialized mutex, or a supported static initializer. Its
storage must remain valid throughout all acquisition and use.
0 with the mutex acquired. EINVAL if mutex is NULL. EDEADLK if the calling task already owns an ERRORCHECK mutex. Errors are returned directly; errno is not the result channel.
Include <pthread.h>; link with pthread. Call from task context where waiting is permitted. There is no timeout or cancellation check. Pair every successful acquisition with pthread_mutex_unlock(). Explicitly initialize before concurrent use; the lazy path is not protected against simultaneous first use.
NORMAL uses the recursive Exec semaphore path without rejecting an owner reacquisition. It therefore permits recursion here, although pthread_mutex_trylock() rejects the same case with EBUSY. Use the RECURSIVE kind when nested ownership is required.
int pthread_mutex_timedlock( pthread_mutex_t *mutex, const struct timespec *abstime)
Try to acquire an exclusive mutex until an absolute deadline.
mutex - Mutex to acquire.
abstime - Absolute realtime deadline; NULL takes the ordinary
pthread_mutex_lock() path.
0 when the timed helper reports success; EINVAL for NULL mutex, invalid nanoseconds, or timer-device failure; EDEADLK for detected nonrecursive self-lock; ETIMEDOUT if the deadline has passed. Other try-lock errors propagate.
First attempts immediate acquisition. If busy, opens timer.device, converts the absolute timestamp against gettimeofday(), and waits for a semaphore acquisition or timer reply. Errors are returned directly.
A NULL deadline is treated as an unbounded lock rather than rejected. An immediately successful pthread_mutex_trylock() is followed by another timed semaphore acquisition instead of an immediate return. This can increase the Exec semaphore nest count twice, so one pthread_mutex_unlock() may not fully release the mutex. No independently selected clock is supported.
int pthread_mutex_trylock( pthread_mutex_t *mutex)
Attempt to acquire a mutex without waiting for another owner. A recursive mutex may be reacquired by its owner. Initialize a static mutex lazily if its semaphore is uninitialized.
mutex - Initialized mutex, or a supported static initializer. Keep its
storage valid until it is unlocked and no longer in use.
0 with one acquisition held. EBUSY if the semaphore cannot be acquired, or if the caller owns a nonrecursive mutex. EINVAL if mutex is NULL. Errors are returned directly.
Include <pthread.h>; link with pthread. Call from task context. This function does not enqueue a wait or check cancellation. A successful call must be paired with pthread_mutex_unlock(); failure grants no ownership. Explicit initialization before sharing avoids the unsynchronized lazy-initialization path.
Owner reacquisition of an ERRORCHECK mutex returns EBUSY here, whereas pthread_mutex_lock() returns EDEADLK. Owner reacquisition of NORMAL is rejected here but allowed by the blocking lock implementation.
int pthread_mutex_unlock( pthread_mutex_t *mutex)
Release one acquisition of a mutex owned by the calling task. A recursive mutex remains owned until every nested acquisition has been released.
mutex - Mutex owned by the caller. No other task may destroy it during
this operation.
0 after ReleaseSemaphore(). EINVAL if mutex is NULL. EPERM if a non-NORMAL mutex is not owned by the caller. Errors are returned directly.
Include <pthread.h>; link with pthread. Use from task context. The call does not wait for ownership or check cancellation. Releasing the last acquisition allows another waiting task to proceed. It does not free the mutex storage.
NORMAL performs no ownership check before ReleaseSemaphore(). Passing an unowned or already unlocked mutex is invalid and may corrupt its state. A successful return is not independent proof of prior ownership. An uninitialized semaphore also takes a lazy-initialization path; that path does not make unlocking without an acquisition valid.
int pthread_mutexattr_destroy( pthread_mutexattr_t *attr)
Clear a mutex attribute object after its last use.
attr - Non-NULL writable mutex attribute object that is no longer in use.
0 on success; EINVAL if attr is NULL. Errors are returned directly.
Include <pthread.h>; link with pthread. The call zeroes the object; it allocates and releases no resources and does not block. Existing mutexes retain their copied kind. Exclude concurrent access and call pthread_mutexattr_init() before using the object again.
int pthread_mutexattr_gettype( pthread_mutexattr_t *attr, int *kind)
Read the mutex type stored in a mutex attribute object.
attr - Initialized mutex attributes. kind - Optional output receiving the stored mutex type.
0 on success; EINVAL if attr is NULL.
A NULL kind pointer is accepted. The function does not validate the current stored value.
int pthread_mutexattr_init( pthread_mutexattr_t *attr)
Set a mutex attribute object's kind to PTHREAD_MUTEX_DEFAULT, which is PTHREAD_MUTEX_NORMAL in this implementation.
attr - Non-NULL writable mutex attribute object.
0 on success; EINVAL if attr is NULL. Errors are returned directly.
Include <pthread.h>; link with pthread. No mutex or other resource is allocated, and the call does not block. pthread_mutex_init() copies the kind; the attribute object need not outlive the initialized mutex. Exclude concurrent access to attr.
Only kind is initialized. The process-sharing field is left untouched, and pthread_mutex_init() ignores that field. This call does not provide process-shared synchronization.
int pthread_mutexattr_settype( pthread_mutexattr_t *attr, int kind)
Set the kind to be copied by subsequent pthread_mutex_init() calls.
attr - Initialized writable mutex attribute object.
kind - PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_RECURSIVE or
PTHREAD_MUTEX_ERRORCHECK. PTHREAD_MUTEX_DEFAULT aliases NORMAL.
0 on success. EINVAL if attr is NULL or kind is outside the supported range; the object is unchanged on failure. Errors are returned directly.
Include <pthread.h>; link with pthread. This changes no existing mutex, allocates no resources and does not block. Exclude concurrent access to the attribute object. Recursive locks require a matching unlock for each acquisition. ERRORCHECK diagnoses a blocking lock by the owner with EDEADLK and an unlock by a non-owner with EPERM.
NORMAL does not implement a strict nonrecursive lock: pthread_mutex_lock() permits repeated acquisition by its owner, while pthread_mutex_trylock() returns EBUSY for that case. Do not depend on owner recursion for NORMAL.
int pthread_once( pthread_once_t *once_control, void (*init_routine)(void))
Execute an initialization routine at most once per correctly initialized control object.
once_control - Shared control object initialized with
PTHREAD_ONCE_INIT.
init_routine - Non-NULL callback invoked without arguments when
initialization is required.
0 on the implemented paths; EINVAL if either pointer is NULL.
Competing callers synchronize through the control object spinlock. The initializer must be valid for the lifetime of concurrent callers.
A zero-initialized control object is not equivalent to PTHREAD_ONCE_INIT: the initial compare-and-swap path can skip initialization. Cancellation during the callback also has nontrivial state and cleanup implications; do not assume a POSIX retry guarantee without testing.
int pthread_rwlock_destroy( pthread_rwlock_t *lock)
Clear an unused reader-writer lock after a nonblocking semaphore probe.
lock - Initialized, idle lock that no task can acquire concurrently.
0 if the semaphore is uninitialized or the probe succeeds; EINVAL if lock is NULL; EBUSY if the exclusive probe fails.
If the semaphore is initialized, attempts exclusive acquisition, releases it, and zeros the lock storage.
The probe is not a synchronization barrier against subsequent acquisitions. A lock held by the calling owner may pass Exec recursive acquisition checks. External quiescence is required.
int pthread_rwlock_init( pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr)
Initialize the Exec shared/exclusive semaphore used by a reader-writer lock.
lock - Writable lock storage not currently used by another task. attr - Attributes; accepted but ignored.
0 on success; EINVAL if lock is NULL.
Initializes the embedded Exec SignalSemaphore. The caller owns the lock storage; destroy only when no holders or waiters remain.
No process-sharing attributes, fairness policy, or other optional lock attributes are consumed.
int pthread_rwlock_rdlock( pthread_rwlock_t *lock)
Acquire a shared reader lock, waiting if exclusive ownership prevents it.
lock - Reader-writer lock to acquire.
0 after acquisition; EINVAL if lock is NULL. Cancellation at the initial check may terminate the calling thread.
Calls pthread_testcancel(), lazily initializes static locks, then blocks in ObtainSemaphoreShared(). Release with pthread_rwlock_unlock().
No explicit deadlock test is active for a caller already holding a write lock; the source contains a disabled ownership check. Concurrent lazy initialization is unguarded.
int pthread_rwlock_timedrdlock( pthread_rwlock_t *lock, const struct timespec *abstime)
Acquire a shared reader lock subject to an absolute deadline.
lock - Reader-writer lock to acquire.
abstime - Absolute realtime deadline; NULL selects an unbounded read
lock.
0 on success; EINVAL for NULL lock, malformed nanoseconds, or timer-device failure; ETIMEDOUT after the deadline; other try-lock errors propagate.
Checks cancellation, tries immediate shared acquisition, then waits using _obtain_sema_timed() and the Exec shared-semaphore mode.
NULL abstime is accepted as an unbounded operation. The timed helper uses gettimeofday(), not a condition-variable clock attribute. Concurrent lazy initialization is unguarded.
int pthread_rwlock_timedwrlock( pthread_rwlock_t *lock, const struct timespec *abstime)
Attempt exclusive writer acquisition until an absolute deadline.
lock - Reader-writer lock to acquire.
abstime - Absolute realtime deadline; NULL takes the ordinary
writer-lock path.
0 on success; EINVAL for NULL lock, invalid nanoseconds, or timer setup failure; ETIMEDOUT on expiry; immediate try-lock errors propagate.
Checks cancellation, first attempts a nonblocking exclusive lock, and waits through the timer/semaphore helper only on EBUSY.
A NULL deadline is not rejected. Unlike pthread_rwlock_wrlock(), this path does not explicitly detect a self-owned write lock before entering timed acquisition.
int pthread_rwlock_tryrdlock( pthread_rwlock_t *lock)
Attempt a shared reader lock without waiting.
lock - Reader-writer lock to acquire.
0 on acquisition; EINVAL if lock is NULL; EBUSY if the shared attempt fails.
Lazily initializes a statically initialized lock and calls AttemptSemaphoreShared(). Unlock once for each successful acquisition.
Lazy initialization is not serialized; initialize explicitly before concurrent first use. Deadlock checks for a caller already holding the write lock are absent.
int pthread_rwlock_trywrlock( pthread_rwlock_t *lock)
Attempt exclusive writer acquisition without blocking.
lock - Reader-writer lock to acquire.
0 on acquisition; EINVAL for NULL; EBUSY if exclusive acquisition fails.
Initializes a static semaphore lazily, then uses Exec AttemptSemaphore().
Exec semaphore ownership can make recursive acquisition succeed; this wrapper does not explicitly reject a writer already owning the lock. Concurrent lazy initialization is also unguarded.
int pthread_rwlock_unlock( pthread_rwlock_t *lock)
Release a reader or writer acquisition of a reader-writer lock.
lock - Reader-writer lock previously acquired by the calling task.
0 if ReleaseSemaphore() is called; EINVAL for NULL; EPERM if the semaphore nest count is below one.
Lazily initializes an invalid static semaphore and uses Exec ReleaseSemaphore() to release one acquisition.
The check examines only ss_NestCount, not a reader ownership list. It cannot reliably reject a thread that does not own a shared acquisition; unlocking from the wrong thread has undefined effects.
int pthread_rwlock_wrlock( pthread_rwlock_t *lock)
Acquire an exclusive writer lock on a reader-writer semaphore.
lock - Reader-writer lock to acquire.
0 after exclusive acquisition; EINVAL if lock is NULL; EDEADLK if the calling task already owns the semaphore.
Checks cancellation, initializes static locks lazily, and waits in ObtainSemaphore(). Release with pthread_rwlock_unlock().
No fairness, writer-preference, or lock-upgrade guarantee is established. Concurrent lazy initialization is unguarded.
int pthread_rwlockattr_destroy( pthread_rwlockattr_t *attr)
Clear an unused reader-writer lock attribute object.
attr - Initialized attributes to invalidate.
0 on success; EINVAL if attr is NULL.
Zeros the caller-owned structure; existing locks are unaffected.
int pthread_rwlockattr_init( pthread_rwlockattr_t *attr)
Initialize attributes for a reader-writer lock.
attr - Writable reader-writer lock attributes.
0 on success; EINVAL if attr is NULL.
Clears the attribute structure. No process-sharing policy is applied by pthread_rwlock_init().
pthread_t pthread_self( void)
Return the identifier associated with the calling task in this pthread runtime's thread table.
None.
The registered worker identifier, or 0 for the initial program task. This implementation also returns 0 for an unregistered task; there is no separate failure result.
Include <pthread.h>; link with pthread. The call does not wait for a worker to finish and transfers no ownership. Compare identifiers with pthread_equal(). A worker identifier is valid only for that worker's lifetime, including any joinable completion record.
Tasks created outside this pthread runtime are not registered by this call. Their fallback value aliases the initial task, so it must not be used to access cancellation state or thread-specific storage from an arbitrary Exec task.
int pthread_setaffinity_np( pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset)
Set the CPUs a running thread may run on.
thread - Registered pthread identifier (pthread_self() for the
caller).
cpusetsize - Size of *cpuset in bytes.
cpuset - The CPUs, numbered as KrnGetCPUNumber() numbers them.
0 on success; ESRCH if thread is not a live thread; EINVAL if cpuset is NULL or names no CPU that exists; ENOMEM if no CPU mask could be allocated. Errors are returned directly.
Include <pthread.h>; link with pthread. Non-portable (glibc). Uses task.resource SetTaskAffinity(): a thread running on a CPU it may no longer use moves at that CPU's next scheduling point. Threads it creates afterwards inherit the new set. On a uniprocessor build only CPU 0 exists.
int pthread_setcancelstate( int state, int *oldstate)
Set the calling thread's cancellation state, optionally saving the previous value. A newly created worker starts with PTHREAD_CANCEL_ENABLE.
state - PTHREAD_CANCEL_ENABLE or PTHREAD_CANCEL_DISABLE. oldstate - Writable output for the previous value, or NULL.
0 on success. EINVAL for any other state; neither the setting nor the optional output is changed on that error. Errors are returned directly.
Include <pthread.h>; link with pthread. The call updates only the current thread record and does not wait. It neither clears a pending request nor tests it. Arrange cleanup before enabling cancellation and use pthread_testcancel() when an immediate deferred check is required.
Re-enabling cancellation does not itself act on a pending request. Only registered workers have the exit context needed to process it; an unregistered task aliases the initial task's state.
int pthread_setcanceltype( int type, int *oldtype)
Set the calling thread's cancellation type, optionally saving the previous value. A newly created worker starts with PTHREAD_CANCEL_DEFERRED.
type - PTHREAD_CANCEL_DEFERRED or PTHREAD_CANCEL_ASYNCHRONOUS. oldtype - Writable output for the previous value, or NULL.
0 on success. EINVAL for any other type; neither the setting nor the optional output is changed on that error. Errors are returned directly.
Include <pthread.h>; link with pthread. The call updates only the current thread record and does not wait. It neither clears a pending request nor tests it. Arrange cleanup before enabling cancellation and use pthread_testcancel() when an immediate deferred check is required.
The default build does not enable the exception handler needed for remote asynchronous cancellation. Accepting the asynchronous constant does not establish that capability. Switching types does not process an already pending request. Use only from a registered worker; an unregistered task aliases the initial task's state.
int pthread_setname_np( pthread_t thread, const char *name)
Replace the Exec task name associated with a pthread identifier.
thread - Registered pthread identifier. name - Non-NULL NUL-terminated replacement name.
0 on success; ERANGE if name is NULL, the identifier cannot be located, or the replacement exceeds the available name space.
For a worker, the name must fit NAMELEN including its terminator. For the initial task, the destination capacity is taken from the length of its existing name plus one.
Writes into the existing Exec task name storage rather than allocating a new buffer. No thread-lifetime or concurrent name-access synchronization is provided.
int pthread_setschedparam( pthread_t thread, int policy, const struct sched_param *param)
Apply a scheduling priority to the Exec task named by a pthread identifier.
thread - Allocated pthread identifier.
policy - Requested POSIX policy; accepted but ignored by this
implementation.
param - Non-NULL struct sched_param containing sched_priority.
0 after calling SetTaskPri(); EINVAL if param is NULL; ESRCH if thread lookup fails.
Only param->sched_priority is passed to Exec. The function does not validate policy or the requested priority.
A record may exist without a live task. No NULL task check protects the SetTaskPri() call.
int pthread_setschedprio( pthread_t thread, int prio)
Set the Exec task priority associated with a pthread identifier.
thread - Existing pthread identifier. prio - Requested task priority.
0 when SetTaskPri() is called; EINVAL if the range comparison rejects prio; ESRCH if the identifier is outside the allocated record range.
The implementation evaluates the value against sched_get_priority_max/min(SCHED_NORMAL), then calls SetTaskPri(). It does not negotiate a distinct POSIX scheduling class.
The comparison uses prio < max or prio > min, so actual accepted values depend on the ordering returned by those helpers. A record within range is not checked for a live task pointer.
int pthread_setspecific( pthread_key_t key, const void *value)
Store value in the calling thread's slot for an allocated key. Replacing a value does not call its destructor or free the previous value.
key - Live key allocated by pthread_key_create(). Prevent its deletion
or reuse during this operation and while its values remain in use.
value - Borrowed pointer to store, or NULL to clear the slot. The caller
owns the data and must arrange its lifetime and eventual release.
0 after storing the pointer. EINVAL if key is out of range or not allocated when checked, ENOMEM if a task that is not a pthread could not get slots; the slot is unchanged on failure. Errors are returned directly.
Include <pthread.h>; link with pthread. The allocation check can wait for the shared TLS semaphore. A task that is not a pthread (another program calling into a shared library, a raw subtask) gets slots of its own on its first store, and its destructors never run. No data storage is allocated or copied. At worker exit, a non-NULL value with an associated destructor is cleared and passed to that destructor, subject to the rules of pthread_key_create(). Clear or dispose of a replaced value explicitly when necessary.
The TLS semaphore is released before the slot is written; concurrent key deletion/reuse is not excluded. Recreated keys retain stale values in surviving threads. Program-wide teardown does not guarantee execution of worker TLS destructors.
int pthread_sigmask( int how, const sigset_t *set, sigset_t *oldset)
Reject a request to inspect or modify the calling thread's signal mask because this operation is not implemented.
how - Requested signal-mask operation; ignored. set - Pointer to the requested signal set; ignored. oldset - Pointer for the previous signal mask; not written.
Always returns -1 and sets errno to ENOSYS.
The thread's signal mask remains unchanged.
int pthread_spin_destroy( pthread_spinlock_t *lock)
Finish using a spinlock after all users have stopped accessing it.
lock - Previously initialized, externally quiescent spinlock.
Always returns 0, including for a NULL pointer.
The implementation does not read or modify the lock word and allocates no memory to release.
No busy, validity, or NULL-pointer check is performed. A successful result does not prove the lock was idle.
int pthread_spin_init( pthread_spinlock_t *lock, int pshared)
Initialize a spinlock in its unlocked state.
lock - Writable pthread_spinlock_t storage. pshared - Process-sharing request; ignored.
0 on success; EINVAL if lock is NULL.
Stores zero in the lock word. Storage is caller-owned and must remain valid while any thread uses it.
No interprocess sharing policy is enforced; reinitializing a held or contended lock is not detected.
int pthread_spin_lock( pthread_spinlock_t *lock)
Acquire a spinlock using an atomic test-and-set loop.
lock - Initialized spinlock to acquire.
0 once the lock is acquired; EINVAL if lock is NULL.
Uses __sync_lock_test_and_set(). On AROS the contended loop yields the processor with sched_yield(); the call can wait indefinitely.
Non-recursive ownership is not tracked. Acquiring a lock already held by the same task can deadlock. The source contains an explicit TODO concerning yield frequency.
int pthread_spin_trylock( pthread_spinlock_t *lock)
Attempt an atomic spinlock acquisition without waiting.
lock - Initialized spinlock to acquire.
0 on acquisition; EINVAL for NULL; EBUSY if test-and-set finds the lock already held.
Does not yield, sleep, or queue a waiter. Each successful acquisition requires a matching unlock.
int pthread_spin_unlock( pthread_spinlock_t *lock)
Clear an acquired spinlock using an atomic release operation.
lock - Lock held by the calling thread.
0 after the atomic release; EINVAL if lock is NULL.
Uses __sync_lock_release(). The caller must establish ownership and the lifetime of the lock word.
No ownership or held-state check is performed. Unlocking an unowned or unlocked spinlock may break mutual exclusion.
void pthread_testcancel( void)
Act on a pending cancellation request at an explicit cancellation point.
Returns no value if cancellation is absent or disabled. If pending and enabled, calls pthread_exit(PTHREAD_CANCELED) and does not return.
A disabled request remains pending; its cancellation wake-up signal is cleared. Use from a task registered with the pthread runtime.
This path dereferences the result of thread lookup without checking for an unregistered caller. It cannot safely provide cancellation for arbitrary Exec tasks.
int sched_get_priority_max( int policy)
Return the upper bound of the library's fixed scheduling-priority range.
policy - Scheduling policy identifier; not inspected.
2 for every policy value.
The result is a library constant, not a query of the current Exec scheduler.
int sched_get_priority_min( int policy)
Return the lower bound of the library's fixed scheduling-priority range.
policy - Scheduling policy identifier; not inspected.
-2 for every policy value.
The result is a library constant, not a query of the current Exec scheduler.
int sched_getcpu( void)
Return the number of the CPU the caller is running on.
The kernel's logical CPU number (0 on a uniprocessor system), or -1 if kernel.resource is not available.
The task may move to another CPU at any time, so the result can be out of date by the time it is used, unless the task's affinity allows only one CPU.
int sched_yield( void)
Give the scheduler an opportunity to run another task.
Always returns 0. No error is reported.
On AROS the kernel's scheduler is run (KrnSchedule()); the task's priority is not changed. The call does not guarantee that another task runs before it returns.
int sem_close( sem_t *sem)
Return from a named-semaphore close request without changing registry state.
sem - Semaphore pointer; not inspected by the implementation.
Always returns 0, including for NULL and invalid pointers.
This is a no-op. It neither frees the object, releases a reference, nor unlinks its name.
The POSIX reference-counting and close lifecycle are not implemented. A success result is not evidence that resources were released.
int sem_destroy( sem_t *sem)
Attempt to destroy an unused unnamed semaphore's internal mutex and condition variable, then clear its count and waiter count.
sem - Initialized semaphore with no active operations or waiters.
Prevent all new operations before destroying or releasing storage.
0 after the internal destruction calls. -1 with errno EINVAL if sem is NULL, or EBUSY if its internal mutex cannot be acquired immediately.
Include <semaphore.h>; link with pthread. The ownership probe does not wait. The caller's storage is not freed. Reinitialize before reuse. Do not use this function to cancel or wake waiting tasks.
Return values from pthread_mutex_destroy() and pthread_cond_destroy() are ignored. A sleeping waiter can leave the mutex available for the probe, so destruction can return 0 despite busy internal objects. Success does not establish that waiting tasks are gone. Quiescence must be established by the application before this call.
int sem_getvalue( sem_t *sem, int *sval)
Read an instantaneous semaphore count or an approximation of blocked waiters.
sem - Initialized semaphore. sval - Non-NULL writable integer output.
0 if an output value is written; -1 with errno=EINVAL if sem or sval is NULL.
When the internal mutex is available, returns value unless a condition wait is recorded, in which case it returns -waiters_count. If the mutex is busy, returns -waiters_count without acquiring it.
The busy-mutex path reads waiters_count without synchronization and can report zero or a negative count even when permits exist. This is not an atomic count/waiter snapshot.
int sem_init( sem_t *sem, int pshared, unsigned int value)
Initialize an unnamed counting semaphore in caller-provided storage. Set its available count to value and initialize the internal mutex and condition variable used to wait for a positive count.
sem - Non-NULL writable semaphore storage that is not already in use.
pshared - Use 0 for threads in the same pthread runtime. The argument
is ignored; nonzero does not enable process sharing.
value - Initial count in 0..SEM_VALUE_MAX.
0 on success. -1 with errno set to EINVAL if sem is NULL or value exceeds SEM_VALUE_MAX. Validation failure leaves the object unchanged.
Include <semaphore.h>; link with pthread. No separate semaphore storage is allocated. Initialize before publishing to other tasks, retain the object while any operation can use it, and destroy it only after all users have finished. Reinitializing an active semaphore is invalid. The semaphore must not be copied while in use.
Process-shared operation is not implemented or rejected. Successful initialization with nonzero pshared does not establish that capability.
sem_t *sem_open( const char *name, int oflag, mode_t mode, unsigned int value)
Look up or create a named semaphore in the pthread library's local registry.
name - Non-NULL NUL-terminated semaphore name.
oflag - Open flags; O_CREAT requests creation, O_EXCL with O_CREAT
rejects an existing name.
mode - Creation permissions; accepted but not used.
value - Initial count for a newly created semaphore; must not exceed
SEM_VALUE_MAX.
Pointer to the named sem_t on success; SEM_FAILED with errno=EINVAL, EEXIST, ENOENT, ENOMEM, or an error from sem_init() on failure.
Initializes a process-local linked list once, searches by FindName(), and allocates a named object only when absent and O_CREAT is set. Existing objects retain their initial count. The returned address is borrowed from the registry, not a separately owned handle.
No cross-process namespace, permissions enforcement, reference counting, or POSIX open-instance ownership is implemented. sem_close() is a no-op; sem_unlink() can immediately invalidate previously returned pointers.
int sem_post( sem_t *sem)
Increment the semaphore count and signal one condition waiter when the recorded waiter count is nonzero. No waiting task owns a particular posted unit until it successfully decrements the count.
sem - Initialized semaphore whose storage remains valid throughout
this operation and all concurrent waits.
0 after incrementing. -1 with errno EINVAL if sem is NULL, or EOVERFLOW if the count is already SEM_VALUE_MAX. No unit is added on overflow. Builds without EOVERFLOW define it as EINVAL in this implementation.
Include <semaphore.h>; link with pthread. The call acquires the internal mutex and can block. It is not safe in interrupt context or an asynchronous signal handler. The semaphore is counting, not owned; a posting task need not have performed a corresponding wait.
pthread_cond_signal() can repeatedly target the same listed waiter before it removes itself. Multiple posts can therefore leave other waiters asleep despite a positive count. No fairness or distinct-waiter wakeup guarantee is provided.
int sem_timedwait( sem_t *sem, const struct timespec *abstime)
Wait for and consume one semaphore permit, subject to an absolute deadline.
sem - Initialized semaphore.
abstime - Absolute deadline forwarded to pthread_cond_timedwait();
NULL requests an unlimited wait.
0 after decrement; -1 on error, with errno=EINVAL for NULL or the status returned by the condition wait, including ETIMEDOUT.
Acquires the embedded mutex, increments waiters_count, loops until a permit arrives or the condition wait fails, and then decrements the waiter count. The default condition clock is CLOCK_REALTIME.
No upfront abstime validation is performed. The implementation enters the timed condition wait only while value is zero; cancellation during that wait needs particular care because waiter accounting and mutex cleanup are not protected by a cleanup handler.
int sem_trywait( sem_t *sem)
Attempt to decrement a semaphore when a positive count is available.
sem - Initialized semaphore.
0 after decrement; -1 with errno=EINVAL for NULL or errno=EAGAIN if the count is zero.
Protects the count with the semaphore's embedded pthread mutex. A successful call consumes one permit without notifying other waiters.
Although the count test is nonblocking, pthread_mutex_lock() can wait for the embedded mutex. The function is therefore not guaranteed to return immediately under contention.
int sem_unlink( const char *name)
Remove a semaphore name and free its registry object immediately.
name - Non-NULL name of an object previously created through
sem_open().
0 if the object is destroyed and removed; -1 with errno=EINVAL for NULL, ENOENT for an unknown name, or an error propagated by sem_destroy().
Looks up the object in the library-local list, calls sem_destroy(), removes its list node, and frees its allocation. All pointers returned by sem_open() for that name then become invalid.
Unlike POSIX deferred unlink semantics, this implementation does not retain an object while it has open users. Synchronize all consumers before unlinking; concurrent semaphore operations can use freed memory.
int sem_wait( sem_t *sem)
Wait until the semaphore count is positive, then decrement it by one. A positive count is consumed without a condition wait. The internal mutex can still delay acquisition even when a unit is available.
sem - Initialized semaphore. Keep its storage valid until every active
operation and waiter has finished.
0 after consuming one unit. -1 with errno EINVAL if sem is NULL. An internal condition-wait failure is returned as -1 with its error number in errno. Cancellation during a condition wait exits the worker instead of returning.
Include <semaphore.h>; link with pthread. Call from the initial program task or a registered worker. There is no timeout. Posting is not tied to ownership; another task can supply the unit with sem_post(). CTRL_C without active cancellation does not produce EINTR: the count is checked again. Do not destroy the semaphore to terminate this wait.
Cancellation inside the condition wait occurs with the internal mutex reacquired. No cleanup handler releases it or decrements waiters_count, so cancellation can leave the semaphore locked and unusable. Avoid cancellation of a worker blocked here; arrange explicit wakeup and orderly termination instead. A pending request is not checked when a unit is available immediately. Repeated posts can also coalesce on one condition waiter; see sem_post().