top logo menu kitty mascot
AROS.ORG Developers Localization Bounties

pthread

Index


pthread_attr_destroy() pthread_attr_getdetachstate() pthread_attr_getschedparam() pthread_attr_getstack()
pthread_attr_getstacksize() pthread_attr_init() pthread_attr_setdetachstate() pthread_attr_setschedparam()
pthread_attr_setstack() pthread_attr_setstacksize() pthread_barrier_destroy() pthread_barrier_init()
pthread_barrier_wait() pthread_cancel() pthread_cleanup_pop() pthread_cleanup_push()
pthread_cond_broadcast() pthread_cond_destroy() pthread_cond_init() pthread_cond_signal()
pthread_cond_timedwait() pthread_cond_timedwait_relative_np() pthread_cond_wait() pthread_condattr_destroy()
pthread_condattr_getclock() pthread_condattr_init() pthread_condattr_setclock() pthread_create()
pthread_detach() pthread_equal() pthread_exit() pthread_getattr_np()
pthread_getname_np() pthread_getschedparam() pthread_getspecific() pthread_join()
pthread_key_create() pthread_key_delete() pthread_kill() pthread_mutex_destroy()
pthread_mutex_init() pthread_mutex_lock() pthread_mutex_timedlock() pthread_mutex_trylock()
pthread_mutex_unlock() pthread_mutexattr_destroy() pthread_mutexattr_gettype() pthread_mutexattr_init()
pthread_mutexattr_settype() pthread_once() pthread_rwlock_destroy() pthread_rwlock_init()
pthread_rwlock_rdlock() pthread_rwlock_timedrdlock() pthread_rwlock_timedwrlock() pthread_rwlock_tryrdlock()
pthread_rwlock_trywrlock() pthread_rwlock_unlock() pthread_rwlock_wrlock() pthread_rwlockattr_destroy()
pthread_rwlockattr_init() pthread_self() pthread_setcancelstate() pthread_setcanceltype()
pthread_setname_np() pthread_setschedparam() pthread_setschedprio() pthread_setspecific()
pthread_sigmask() pthread_spin_destroy() pthread_spin_init() pthread_spin_lock()
pthread_spin_trylock() pthread_spin_unlock() pthread_testcancel() sched_get_priority_max()
sched_get_priority_min() sched_yield() sem_close() sem_destroy()
sem_getvalue() sem_init() sem_open() sem_post()
sem_timedwait() sem_trywait() sem_unlink() sem_wait()

pthread_attr_destroy()

Synopsis

int pthread_attr_destroy(
   pthread_attr_t *attr)

Function

Clear a thread attribute object after its last use. This implementation
zeroes the object and does not free any memory.

Inputs

attr - Non-NULL writable attribute object that is no longer in use.

Result

0 on success; EINVAL if attr is NULL. Errors are returned directly.

Notes

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.

pthread_attr_getdetachstate()

Synopsis

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

Function

Read the detach state stored in a thread attribute object.

Inputs

attr - Initialized thread attributes.
detachstate - Optional output for PTHREAD_CREATE_JOINABLE or
              PTHREAD_CREATE_DETACHED; NULL suppresses the write.

Result

0 on success; EINVAL if attr is NULL.

Notes

Reads the stored field; it does not inspect any running thread. Errors
are returned directly.

pthread_attr_getschedparam()

Synopsis

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

Function

Read the scheduling parameters stored in a thread attribute object.

Inputs

attr - Initialized thread attributes.
param - Optional writable struct sched_param receiving a copy of the
        stored parameters.

Result

0 on success; EINVAL if attr is NULL.

Notes

This is a copy of the attribute field, not a query of the task
scheduler. A NULL output pointer is accepted.

pthread_attr_getstack()

Synopsis

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

Function

Read the requested stack address and size from thread attributes.

Inputs

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.

Result

0 on success; EINVAL if attr is NULL.

Notes

The values describe an attribute object, not the current stack of a
live thread. No allocation or validation occurs.

pthread_attr_getstacksize()

Synopsis

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

Function

Read the stack size stored in thread attributes.

Inputs

attr - Initialized attributes.
stacksize - Optional output for the stored byte count; NULL is
            accepted.

Result

The result of pthread_attr_getstack(attr, NULL, stacksize): 0 or
EINVAL.

Notes

This function does not query a running task or determine a minimum
usable stack size.

pthread_attr_init()

Synopsis

int pthread_attr_init(
   pthread_attr_t *attr)

Function

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.

Inputs

attr - Non-NULL writable attribute object to initialize.

Result

0 on success; EINVAL if attr is NULL. Errors are returned directly.

Notes

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.

pthread_attr_setdetachstate()

Synopsis

int pthread_attr_setdetachstate(
   pthread_attr_t *attr, int detachstate)

Function

Choose whether new threads are joinable or detached.

Inputs

attr - Initialized attributes to update.
detachstate - PTHREAD_CREATE_JOINABLE or PTHREAD_CREATE_DETACHED.

Result

0 on success; EINVAL for a NULL attr or any other detach state.

Notes

The selection takes effect when pthread_create() copies these
attributes. Changing an attribute object does not detach an existing
thread.

pthread_attr_setschedparam()

Synopsis

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

Function

Store scheduling parameters for a subsequently created thread.

Inputs

attr - Initialized attributes to update.
param - Non-NULL scheduling parameters to copy.

Result

0 on success; EINVAL if attr or param is NULL.

Notes

The entire struct sched_param is copied. The setter does not validate
its priority; thread creation uses the stored priority.

Bugs

The pthread_create() path does not implement scheduling inheritance or
contention-scope controls.

pthread_attr_setstack()

Synopsis

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

Function

Store a stack buffer address and requested size for future thread
creation.

Inputs

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.

Result

0 on success; EINVAL if attr is NULL or a non-NULL stackaddr is paired
with zero size.

Notes

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.

Bugs

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.

pthread_attr_setstacksize()

Synopsis

int pthread_attr_setstacksize(
   pthread_attr_t *attr,
   size_t stacksize)

Function

Set the stack size for subsequent worker creation and clear any
previously supplied stack address. This delegates to
pthread_attr_setstack(attr, NULL, stacksize).

Inputs

attr - Initialized writable attribute object.
stacksize - Requested size in bytes. Zero leaves process creation to
    use its default stack allocation.

Result

0 on success; EINVAL if attr is NULL. Errors are returned directly.

Notes

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.

Bugs

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.

pthread_barrier_destroy()

Synopsis

int pthread_barrier_destroy(
   pthread_barrier_t *barrier)

Function

Destroy a barrier that has no arriving or departing participants.

Inputs

barrier - Initialized, externally quiescent barrier.

Result

0 if destruction proceeds; EINVAL for NULL; EBUSY if the mutex cannot
be acquired, a generation is active, or the condition destroy fails.

Notes

Attempts a nonblocking lock and checks internal generation state
before destroying the embedded condition and mutex. Do not reuse the
storage without initialization.

Bugs

A successful probe does not exclude new arrivals; external quiescence
is required. The return value from the final mutex destruction is
ignored.

pthread_barrier_init()

Synopsis

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

Function

Initialize a reusable barrier for a fixed number of participating
threads.

Inputs

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.

Result

0 on success; EINVAL if barrier is NULL or count is zero.

Notes

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.

Bugs

The return values of the embedded mutex and condition initializers are
not checked. No maximum participant count or overflow guard is
enforced.

pthread_barrier_wait()

Synopsis

int pthread_barrier_wait(
   pthread_barrier_t *barrier)

Function

Wait for all members of a barrier generation and release them
together.

Inputs

barrier - Initialized barrier shared by the participating threads.

Result

PTHREAD_BARRIER_SERIAL_THREAD for the final arrival; 0 for other
arrivals after the generation completes; EINVAL for NULL.

Notes

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.

Bugs

The implementation does not propagate embedded mutex/condition
failures. If a participant exits or never arrives, other participants
may wait indefinitely.

pthread_cancel()

Synopsis

int pthread_cancel(
   pthread_t thread)

Function

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.

Inputs

thread - Identifier of a live worker created by pthread_create().
    Coordinate its lifetime with joining, detaching and other requests.

Result

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.

Notes

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().

Bugs

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.

pthread_cleanup_pop()

Synopsis

void pthread_cleanup_pop(
   int execute)

Function

Remove the most recently registered cancellation cleanup handler.

Inputs

execute - Nonzero to invoke the removed handler immediately; zero to
          discard it without invocation.

Result

No return value. A missing handler is treated as an empty pop.

Notes

Removes the tail record from the current pthread cleanup list,
optionally invokes its callback with the stored argument, then frees
the record.

Bugs

No dynamic balancing or thread-identity validation is performed. A
previous failed push can leave the pop operating on another registered
handler.

pthread_cleanup_push()

Synopsis

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

Function

Register a callback to run when the current pthread unwinds its
cleanup stack.

Inputs

routine - Callback that accepts one void * argument; NULL is silently
          ignored.
arg - Pointer passed to the callback; must remain valid until
      invocation or removal.

Result

No return value. On allocation failure the handler is silently not
registered.

Notes

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.

Bugs

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.

pthread_cond_broadcast()

Synopsis

int pthread_cond_broadcast(
   pthread_cond_t *cond)

Function

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.

Inputs

cond - Initialized condition variable, or a supported static initializer.
    Its storage must remain valid throughout signalling and all waits.

Result

0 after signalling, including when no waiter is present. EINVAL if cond
is NULL. Errors are returned directly.

Notes

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.

Bugs

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.

pthread_cond_destroy()

Synopsis

int pthread_cond_destroy(
   pthread_cond_t *cond)

Function

Clear a condition variable after checking that its internal semaphore
is available and its waiter list is empty.

Inputs

cond - Unused condition variable. Prevent all new waits and signals
    before destruction and until its storage has been released.

Result

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.

Notes

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.

Bugs

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.

pthread_cond_init()

Synopsis

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

Function

Initialize a condition variable with an empty waiter list. Select the
absolute-deadline clock from attr, or CLOCK_REALTIME by default.

Inputs

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.

Result

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.

Notes

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.

Bugs

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.

pthread_cond_signal()

Synopsis

int pthread_cond_signal(
   pthread_cond_t *cond)

Function

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.

Inputs

cond - Initialized condition variable, or a supported static initializer.
    Its storage must remain valid throughout signalling and all waits.

Result

0 after signalling, including when no waiter is present. EINVAL if cond
is NULL. Errors are returned directly.

Notes

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.

Bugs

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.

pthread_cond_timedwait()

Synopsis

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

Function

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.

Inputs

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.

Result

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.

Notes

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.

Bugs

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.

pthread_cond_timedwait_relative_np()

Synopsis

int pthread_cond_timedwait_relative_np(
   pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *reltime)

Function

Wait on a condition variable using a relative time interval.

Inputs

cond - Initialized condition variable.
mutex - Locked mutex associated with the condition.
reltime - Relative duration passed to the shared condition-wait
          implementation.

Result

Returns the status of _pthread_cond_timedwait(), including timeout and
argument errors established by that implementation.

Notes

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.

pthread_cond_wait()

Synopsis

int pthread_cond_wait(
   pthread_cond_t *cond,
   pthread_mutex_t *mutex)

Function

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.

Inputs

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.

Result

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.

Example

// 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.

Notes

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.

Bugs

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.

pthread_condattr_destroy()

Synopsis

int pthread_condattr_destroy(
   pthread_condattr_t *attr)

Function

Clear a condition-variable attribute object after use.

Inputs

attr - Initialized condition attribute object no longer needed.

Result

0 on success; EINVAL if attr is NULL.

Notes

Zeros the attribute storage. It does not deallocate the caller-owned
object or affect condition variables already initialized from it.

pthread_condattr_getclock()

Synopsis

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

Function

Read the deadline clock selected in condition attributes.

Inputs

attr - Initialized condition attributes.
clock_id - Non-NULL writable output for the clock ID.

Result

0 on success; EINVAL if either pointer is NULL.

Notes

Reports the stored field. It does not query timer.device or the clock
currently used by a running wait.

pthread_condattr_init()

Synopsis

int pthread_condattr_init(
   pthread_condattr_t *attr)

Function

Initialize condition-variable attributes with the default realtime
clock.

Inputs

attr - Writable condition attribute object.

Result

0 on success; EINVAL if attr is NULL.

Notes

Clears the object and sets cond_clock to CLOCK_REALTIME when the
symbol is available. Initialize attributes before passing them to
pthread_cond_init().

pthread_condattr_setclock()

Synopsis

int pthread_condattr_setclock(
   pthread_condattr_t *attr, clockid_t clock_id)

Function

Select the clock used to interpret an absolute condition-wait
deadline.

Inputs

attr - Initialized condition attribute object.
clock_id - CLOCK_REALTIME or CLOCK_MONOTONIC.

Result

0 on success; EINVAL if attr is NULL or clock_id is unsupported.

Notes

Stores the chosen clock. pthread_cond_init() copies it into the
condition variable; changing attributes later does not change existing
conditions.

pthread_create()

Synopsis

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

Function

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.

Inputs

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.

Result

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.

Notes

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.

Bugs

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.

pthread_detach()

Synopsis

int pthread_detach(
   pthread_t thread)

Function

Detach a thread so that its identifier slot can be released without
joining.

Inputs

thread - Identifier of the worker to detach.

Result

0 on success; ESRCH if the slot or its task is unavailable; EINVAL if
the thread is already detached.

Notes

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.

Bugs

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.

pthread_equal()

Synopsis

int pthread_equal(
   pthread_t t1,
   pthread_t t2)

Function

Compare two thread identifier values. This implementation compares the
numeric identifiers without looking up either thread.

Inputs

t1 - First thread identifier.
t2 - Second thread identifier.

Result

Nonzero (1) if the values are equal; 0 otherwise. No errors are reported.

Notes

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.

pthread_exit()

Synopsis

void pthread_exit(
   void *value_ptr)

Function

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.

Inputs

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.

Result

Does not return for a worker created by pthread_create().

Notes

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.

Bugs

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.

pthread_getattr_np()

Synopsis

int pthread_getattr_np(
   pthread_t thread, pthread_attr_t *attr)

Function

Snapshot the attributes of a registered pthread and its current stack
extent.

Inputs

thread - Registered pthread identifier.
attr - Non-NULL writable output attributes.

Result

0 on success; EINVAL if attr is NULL; ESRCH if thread lookup fails.

Notes

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.

Bugs

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.

pthread_getname_np()

Synopsis

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

Function

Copy the current Exec task name for a pthread into a caller-owned
buffer.

Inputs

thread - Registered pthread identifier.
name - Non-NULL writable output buffer.
len - Capacity of name in bytes, including the trailing NUL.

Result

0 on success; ERANGE if name is NULL, len is zero, the identifier
cannot be located, or the destination is too small.

Notes

Copies the NUL-terminated task name after comparing strlen(name)+1
against len. No destination bytes are written when that size check
fails.

Bugs

The task pointer and source string are not protected against
concurrent task completion or renaming.

pthread_getschedparam()

Synopsis

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

Function

Report the current Exec priority for a pthread and a fixed scheduling
policy.

Inputs

thread - Allocated pthread identifier.
policy - Non-NULL output; receives SCHED_NORMAL.
param - Non-NULL output; sched_priority receives the Exec task
        priority.

Result

0 on success; EINVAL if either output is NULL; ESRCH if thread lookup
fails.

Notes

Reads tc_Node.ln_Pri directly from the associated task. Other fields
of *param are not initialized by this function.

Bugs

The task pointer is not checked for NULL before dereference. A
finished or invalidated slot can therefore cause invalid memory
access.

pthread_getspecific()

Synopsis

void *pthread_getspecific(
   pthread_key_t key)

Function

Read the calling thread's pointer slot for key. The pointer is returned
unchanged; the call neither copies nor frees the pointed-to data.

Inputs

key - Live key allocated by pthread_key_create(), with its lifetime
    protected against concurrent deletion and reuse.

Result

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.

Notes

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.

Bugs

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.

pthread_join()

Synopsis

int pthread_join(
   pthread_t thread,
   void **value_ptr)

Function

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.

Inputs

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.

Result

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.

Notes

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.

Bugs

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.

pthread_key_create()

Synopsis

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

Function

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.

Inputs

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.

Result

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.

Notes

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.

Bugs

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.

pthread_key_delete()

Synopsis

int pthread_key_delete(
   pthread_key_t key)

Function

Release a thread-specific storage key for future reuse.

Inputs

key - Previously allocated key below PTHREAD_KEYS_MAX.

Result

0 if a used key is marked free; EINVAL if the key is out of range or
already unused.

Notes

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.

pthread_kill()

Synopsis

int pthread_kill(
   pthread_t thread, int sig)

Function

Provide the pthread_kill entry point without signal delivery support.

Inputs

thread - Thread identifier; ignored.
sig - Signal number; ignored.

Result

Always returns EINVAL. No signal is delivered.

Notes

The present implementation contains only a diagnostic trace and the
EINVAL return. Do not use it to probe thread existence or deliver
POSIX signals.

Bugs

Signal delivery is not implemented for this entry point.

pthread_mutex_destroy()

Synopsis

int pthread_mutex_destroy(
   pthread_mutex_t *mutex)

Function

Clear an unused mutex after checking that its semaphore can be acquired
and no condition wait is recorded. No caller-owned storage is freed.

Inputs

mutex - Unlocked mutex with no users or waiters. Prevent new operations
    for the entire destruction and storage-release interval.

Result

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.

Notes

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.

Bugs

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.

pthread_mutex_init()

Synopsis

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

Function

Initialize a mutex's embedded Exec semaphore, copy its kind from attr
(or use PTHREAD_MUTEX_DEFAULT), and clear its condition-wait count.

Inputs

mutex - Non-NULL writable mutex storage that is not already in use.
attr - Initialized mutex attributes, or NULL for the default kind.

Result

0 on success; EINVAL if mutex is NULL. Errors are returned directly.

Notes

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.

Bugs

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.

pthread_mutex_lock()

Synopsis

int pthread_mutex_lock(
   pthread_mutex_t *mutex)

Function

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.

Inputs

mutex - Initialized mutex, or a supported static initializer. Its
    storage must remain valid throughout all acquisition and use.

Result

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.

Notes

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.

Bugs

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.

pthread_mutex_timedlock()

Synopsis

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

Function

Try to acquire an exclusive mutex until an absolute deadline.

Inputs

mutex - Mutex to acquire.
abstime - Absolute realtime deadline; NULL takes the ordinary
          pthread_mutex_lock() path.

Result

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.

Notes

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.

Bugs

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.

pthread_mutex_trylock()

Synopsis

int pthread_mutex_trylock(
   pthread_mutex_t *mutex)

Function

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.

Inputs

mutex - Initialized mutex, or a supported static initializer. Keep its
    storage valid until it is unlocked and no longer in use.

Result

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.

Notes

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.

Bugs

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.

pthread_mutex_unlock()

Synopsis

int pthread_mutex_unlock(
   pthread_mutex_t *mutex)

Function

Release one acquisition of a mutex owned by the calling task. A recursive
mutex remains owned until every nested acquisition has been released.

Inputs

mutex - Mutex owned by the caller. No other task may destroy it during
    this operation.

Result

0 after ReleaseSemaphore(). EINVAL if mutex is NULL. EPERM if a
non-NORMAL mutex is not owned by the caller. Errors are returned directly.

Notes

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.

Bugs

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.

pthread_mutexattr_destroy()

Synopsis

int pthread_mutexattr_destroy(
   pthread_mutexattr_t *attr)

Function

Clear a mutex attribute object after its last use.

Inputs

attr - Non-NULL writable mutex attribute object that is no longer in use.

Result

0 on success; EINVAL if attr is NULL. Errors are returned directly.

Notes

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.

pthread_mutexattr_gettype()

Synopsis

int pthread_mutexattr_gettype(
   pthread_mutexattr_t *attr, int *kind)

Function

Read the mutex type stored in a mutex attribute object.

Inputs

attr - Initialized mutex attributes.
kind - Optional output receiving the stored mutex type.

Result

0 on success; EINVAL if attr is NULL.

Notes

A NULL kind pointer is accepted. The function does not validate the
current stored value.

pthread_mutexattr_init()

Synopsis

int pthread_mutexattr_init(
   pthread_mutexattr_t *attr)

Function

Set a mutex attribute object's kind to PTHREAD_MUTEX_DEFAULT, which is
PTHREAD_MUTEX_NORMAL in this implementation.

Inputs

attr - Non-NULL writable mutex attribute object.

Result

0 on success; EINVAL if attr is NULL. Errors are returned directly.

Notes

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.

Bugs

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.

pthread_mutexattr_settype()

Synopsis

int pthread_mutexattr_settype(
   pthread_mutexattr_t *attr,
   int kind)

Function

Set the kind to be copied by subsequent pthread_mutex_init() calls.

Inputs

attr - Initialized writable mutex attribute object.
kind - PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_RECURSIVE or
    PTHREAD_MUTEX_ERRORCHECK. PTHREAD_MUTEX_DEFAULT aliases NORMAL.

Result

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.

Notes

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.

Bugs

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.

pthread_once()

Synopsis

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

Function

Execute an initialization routine at most once per correctly
initialized control object.

Inputs

once_control - Shared control object initialized with
               PTHREAD_ONCE_INIT.
init_routine - Non-NULL callback invoked without arguments when
               initialization is required.

Result

0 on the implemented paths; EINVAL if either pointer is NULL.

Notes

Competing callers synchronize through the control object spinlock. The
initializer must be valid for the lifetime of concurrent callers.

Bugs

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. On __mc68000__, its spin-lock helper also uses the
problematic test-and-set replacement.

pthread_rwlock_destroy()

Synopsis

int pthread_rwlock_destroy(
   pthread_rwlock_t *lock)

Function

Clear an unused reader-writer lock after a nonblocking semaphore
probe.

Inputs

lock - Initialized, idle lock that no task can acquire concurrently.

Result

0 if the semaphore is uninitialized or the probe succeeds; EINVAL if
lock is NULL; EBUSY if the exclusive probe fails.

Notes

If the semaphore is initialized, attempts exclusive acquisition,
releases it, and zeros the lock storage.

Bugs

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.

pthread_rwlock_init()

Synopsis

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

Function

Initialize the Exec shared/exclusive semaphore used by a reader-writer
lock.

Inputs

lock - Writable lock storage not currently used by another task.
attr - Attributes; accepted but ignored.

Result

0 on success; EINVAL if lock is NULL.

Notes

Initializes the embedded Exec SignalSemaphore. The caller owns the
lock storage; destroy only when no holders or waiters remain.

Bugs

No process-sharing attributes, fairness policy, or other optional lock
attributes are consumed.

pthread_rwlock_rdlock()

Synopsis

int pthread_rwlock_rdlock(
   pthread_rwlock_t *lock)

Function

Acquire a shared reader lock, waiting if exclusive ownership prevents
it.

Inputs

lock - Reader-writer lock to acquire.

Result

0 after acquisition; EINVAL if lock is NULL. Cancellation at the
initial check may terminate the calling thread.

Notes

Calls pthread_testcancel(), lazily initializes static locks, then
blocks in ObtainSemaphoreShared(). Release with
pthread_rwlock_unlock().

Bugs

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.

pthread_rwlock_timedrdlock()

Synopsis

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

Function

Acquire a shared reader lock subject to an absolute deadline.

Inputs

lock - Reader-writer lock to acquire.
abstime - Absolute realtime deadline; NULL selects an unbounded read
          lock.

Result

0 on success; EINVAL for NULL lock, malformed nanoseconds, or
timer-device failure; ETIMEDOUT after the deadline; other try-lock
errors propagate.

Notes

Checks cancellation, tries immediate shared acquisition, then waits
using _obtain_sema_timed() and the Exec shared-semaphore mode.

Bugs

NULL abstime is accepted as an unbounded operation. The timed helper
uses gettimeofday(), not a condition-variable clock attribute.
Concurrent lazy initialization is unguarded.

pthread_rwlock_timedwrlock()

Synopsis

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

Function

Attempt exclusive writer acquisition until an absolute deadline.

Inputs

lock - Reader-writer lock to acquire.
abstime - Absolute realtime deadline; NULL takes the ordinary
          writer-lock path.

Result

0 on success; EINVAL for NULL lock, invalid nanoseconds, or timer
setup failure; ETIMEDOUT on expiry; immediate try-lock errors
propagate.

Notes

Checks cancellation, first attempts a nonblocking exclusive lock, and
waits through the timer/semaphore helper only on EBUSY.

Bugs

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.

pthread_rwlock_tryrdlock()

Synopsis

int pthread_rwlock_tryrdlock(
   pthread_rwlock_t *lock)

Function

Attempt a shared reader lock without waiting.

Inputs

lock - Reader-writer lock to acquire.

Result

0 on acquisition; EINVAL if lock is NULL; EBUSY if the shared attempt
fails.

Notes

Lazily initializes a statically initialized lock and calls
AttemptSemaphoreShared(). Unlock once for each successful acquisition.

Bugs

Lazy initialization is not serialized; initialize explicitly before
concurrent first use. Deadlock checks for a caller already holding the
write lock are absent.

pthread_rwlock_trywrlock()

Synopsis

int pthread_rwlock_trywrlock(
   pthread_rwlock_t *lock)

Function

Attempt exclusive writer acquisition without blocking.

Inputs

lock - Reader-writer lock to acquire.

Result

0 on acquisition; EINVAL for NULL; EBUSY if exclusive acquisition
fails.

Notes

Initializes a static semaphore lazily, then uses Exec
AttemptSemaphore().

Bugs

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.

pthread_rwlock_unlock()

Synopsis

int pthread_rwlock_unlock(
   pthread_rwlock_t *lock)

Function

Release a reader or writer acquisition of a reader-writer lock.

Inputs

lock - Reader-writer lock previously acquired by the calling task.

Result

0 if ReleaseSemaphore() is called; EINVAL for NULL; EPERM if the
semaphore nest count is below one.

Notes

Lazily initializes an invalid static semaphore and uses Exec
ReleaseSemaphore() to release one acquisition.

Bugs

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.

pthread_rwlock_wrlock()

Synopsis

int pthread_rwlock_wrlock(
   pthread_rwlock_t *lock)

Function

Acquire an exclusive writer lock on a reader-writer semaphore.

Inputs

lock - Reader-writer lock to acquire.

Result

0 after exclusive acquisition; EINVAL if lock is NULL; EDEADLK if the
calling task already owns the semaphore.

Notes

Checks cancellation, initializes static locks lazily, and waits in
ObtainSemaphore(). Release with pthread_rwlock_unlock().

Bugs

No fairness, writer-preference, or lock-upgrade guarantee is
established. Concurrent lazy initialization is unguarded.

pthread_rwlockattr_destroy()

Synopsis

int pthread_rwlockattr_destroy(
   pthread_rwlockattr_t *attr)

Function

Clear an unused reader-writer lock attribute object.

Inputs

attr - Initialized attributes to invalidate.

Result

0 on success; EINVAL if attr is NULL.

Notes

Zeros the caller-owned structure; existing locks are unaffected.

pthread_rwlockattr_init()

Synopsis

int pthread_rwlockattr_init(
   pthread_rwlockattr_t *attr)

Function

Initialize attributes for a reader-writer lock.

Inputs

attr - Writable reader-writer lock attributes.

Result

0 on success; EINVAL if attr is NULL.

Notes

Clears the attribute structure. No process-sharing policy is applied
by pthread_rwlock_init().

pthread_self()

Synopsis

pthread_t pthread_self(
   void)

Function

Return the identifier associated with the calling task in this pthread
runtime's thread table.

Inputs

None.

Result

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.

Notes

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.

Bugs

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.

pthread_setcancelstate()

Synopsis

int pthread_setcancelstate(
   int state,
   int *oldstate)

Function

Set the calling thread's cancellation state, optionally saving the
previous value. A newly created worker starts with PTHREAD_CANCEL_ENABLE.

Inputs

state - PTHREAD_CANCEL_ENABLE or PTHREAD_CANCEL_DISABLE.
oldstate - Writable output for the previous value, or NULL.

Result

0 on success. EINVAL for any other state; neither the setting nor the
optional output is changed on that error. Errors are returned directly.

Notes

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.

Bugs

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.

pthread_setcanceltype()

Synopsis

int pthread_setcanceltype(
   int type,
   int *oldtype)

Function

Set the calling thread's cancellation type, optionally saving the
previous value. A newly created worker starts with PTHREAD_CANCEL_DEFERRED.

Inputs

type - PTHREAD_CANCEL_DEFERRED or PTHREAD_CANCEL_ASYNCHRONOUS.
oldtype - Writable output for the previous value, or NULL.

Result

0 on success. EINVAL for any other type; neither the setting nor the
optional output is changed on that error. Errors are returned directly.

Notes

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.

Bugs

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.

pthread_setname_np()

Synopsis

int pthread_setname_np(
   pthread_t thread, const char *name)

Function

Replace the Exec task name associated with a pthread identifier.

Inputs

thread - Registered pthread identifier.
name - Non-NULL NUL-terminated replacement name.

Result

0 on success; ERANGE if name is NULL, the identifier cannot be
located, or the replacement exceeds the available name space.

Notes

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.

Bugs

Writes into the existing Exec task name storage rather than allocating
a new buffer. No thread-lifetime or concurrent name-access
synchronization is provided.

pthread_setschedparam()

Synopsis

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

Function

Apply a scheduling priority to the Exec task named by a pthread
identifier.

Inputs

thread - Allocated pthread identifier.
policy - Requested POSIX policy; accepted but ignored by this
         implementation.
param - Non-NULL struct sched_param containing sched_priority.

Result

0 after calling SetTaskPri(); EINVAL if param is NULL; ESRCH if thread
lookup fails.

Notes

Only param->sched_priority is passed to Exec. The function does not
validate policy or the requested priority.

Bugs

A record may exist without a live task. No NULL task check protects
the SetTaskPri() call.

pthread_setschedprio()

Synopsis

int pthread_setschedprio(
   pthread_t thread, int prio)

Function

Set the Exec task priority associated with a pthread identifier.

Inputs

thread - Existing pthread identifier.
prio - Requested task priority.

Result

0 when SetTaskPri() is called; EINVAL if the range comparison rejects
prio; ESRCH if the identifier is outside the allocated record range.

Notes

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.

Bugs

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.

pthread_setspecific()

Synopsis

int pthread_setspecific(
   pthread_key_t key,
   const void *value)

Function

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.

Inputs

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.

Result

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.

Notes

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.

Bugs

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.

pthread_sigmask()

Synopsis

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

Function

Reject a request to inspect or modify the calling thread's signal
mask because this operation is not implemented.

Inputs

how - Requested signal-mask operation; ignored.
set - Pointer to the requested signal set; ignored.
oldset - Pointer for the previous signal mask; not written.

Result

Always returns -1 and sets errno to ENOSYS.

Notes

The thread's signal mask remains unchanged.

pthread_spin_destroy()

Synopsis

int pthread_spin_destroy(
   pthread_spinlock_t *lock)

Function

Finish using a spinlock after all users have stopped accessing it.

Inputs

lock - Previously initialized, externally quiescent spinlock.

Result

Always returns 0, including for a NULL pointer.

Notes

The implementation does not read or modify the lock word and allocates
no memory to release.

Bugs

No busy, validity, or NULL-pointer check is performed. A successful
result does not prove the lock was idle.

pthread_spin_init()

Synopsis

int pthread_spin_init(
   pthread_spinlock_t *lock, int pshared)

Function

Initialize a spinlock in its unlocked state.

Inputs

lock - Writable pthread_spinlock_t storage.
pshared - Process-sharing request; ignored.

Result

0 on success; EINVAL if lock is NULL.

Notes

Stores zero in the lock word. Storage is caller-owned and must remain
valid while any thread uses it.

Bugs

No interprocess sharing policy is enforced; reinitializing a held or
contended lock is not detected.

pthread_spin_lock()

Synopsis

int pthread_spin_lock(
   pthread_spinlock_t *lock)

Function

Acquire a spinlock using an atomic test-and-set loop.

Inputs

lock - Initialized spinlock to acquire.

Result

0 once the lock is acquired; EINVAL if lock is NULL.

Notes

Uses __sync_lock_test_and_set(). On AROS the contended loop yields the
processor with sched_yield(); the call can wait indefinitely.

Bugs

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. The __mc68000__ replacement for
test-and-set returns the newly written value, so this loop cannot
observe an unlocked value through that replacement.

pthread_spin_trylock()

Synopsis

int pthread_spin_trylock(
   pthread_spinlock_t *lock)

Function

Attempt an atomic spinlock acquisition without waiting.

Inputs

lock - Initialized spinlock to acquire.

Result

0 on acquisition; EINVAL for NULL; EBUSY if test-and-set finds the
lock already held.

Notes

Does not yield, sleep, or queue a waiter. Each successful acquisition
requires a matching unlock.

Bugs

The __mc68000__ replacement for test-and-set returns the written value
instead of the old value; with a nonzero lock request this path
reports EBUSY even on an initially clear lock.

pthread_spin_unlock()

Synopsis

int pthread_spin_unlock(
   pthread_spinlock_t *lock)

Function

Clear an acquired spinlock using an atomic release operation.

Inputs

lock - Lock held by the calling thread.

Result

0 after the atomic release; EINVAL if lock is NULL.

Notes

Uses __sync_lock_release(). The caller must establish ownership and
the lifetime of the lock word.

Bugs

No ownership or held-state check is performed. Unlocking an unowned or
unlocked spinlock may break mutual exclusion.

pthread_testcancel()

Synopsis

void pthread_testcancel(
   void)

Function

Act on a pending cancellation request at an explicit cancellation
point.

Result

Returns no value if cancellation is absent or disabled. If pending and
enabled, calls pthread_exit(PTHREAD_CANCELED) and does not return.

Notes

A disabled request remains pending; its cancellation wake-up signal is
cleared. Use from a task registered with the pthread runtime.

Bugs

This path dereferences the result of thread lookup without checking
for an unregistered caller. It cannot safely provide cancellation for
arbitrary Exec tasks.

sched_get_priority_max()

Synopsis

int sched_get_priority_max(
   int policy)

Function

Return the upper bound of the library's fixed scheduling-priority
range.

Inputs

policy - Scheduling policy identifier; not inspected.

Result

2 for every policy value.

Notes

The result is a library constant, not a query of the current
Exec scheduler.

sched_get_priority_min()

Synopsis

int sched_get_priority_min(
   int policy)

Function

Return the lower bound of the library's fixed scheduling-priority
range.

Inputs

policy - Scheduling policy identifier; not inspected.

Result

-2 for every policy value.

Notes

The result is a library constant, not a query of the current
Exec scheduler.

sched_yield()

Synopsis

int sched_yield(
   void)

Function

Give the scheduler an opportunity to run another task.

Result

Always returns 0. No error is reported.

Notes

On AROS, temporarily sets the calling Exec task's priority to -10
and then restores its previous priority. The call does not
guarantee that another task runs before it returns.

sem_close()

Synopsis

int sem_close(
   sem_t *sem)

Function

Return from a named-semaphore close request without changing registry
state.

Inputs

sem - Semaphore pointer; not inspected by the implementation.

Result

Always returns 0, including for NULL and invalid pointers.

Notes

This is a no-op. It neither frees the object, releases a reference,
nor unlinks its name.

Bugs

The POSIX reference-counting and close lifecycle are not implemented.
A success result is not evidence that resources were released.

sem_destroy()

Synopsis

int sem_destroy(
   sem_t *sem)

Function

Attempt to destroy an unused unnamed semaphore's internal mutex and
condition variable, then clear its count and waiter count.

Inputs

sem - Initialized semaphore with no active operations or waiters.
    Prevent all new operations before destroying or releasing storage.

Result

0 after the internal destruction calls. -1 with errno EINVAL if sem is
NULL, or EBUSY if its internal mutex cannot be acquired immediately.

Notes

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.

Bugs

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.

sem_getvalue()

Synopsis

int sem_getvalue(
   sem_t *sem, int *sval)

Function

Read an instantaneous semaphore count or an approximation of blocked
waiters.

Inputs

sem - Initialized semaphore.
sval - Non-NULL writable integer output.

Result

0 if an output value is written; -1 with errno=EINVAL if sem or sval
is NULL.

Notes

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.

Bugs

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.

sem_init()

Synopsis

int sem_init(
   sem_t *sem,
   int pshared,
   unsigned int value)

Function

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.

Inputs

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.

Result

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.

Notes

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.

Bugs

Process-shared operation is not implemented or rejected. Successful
initialization with nonzero pshared does not establish that capability.

sem_open()

Synopsis

sem_t *sem_open(
   const char *name, int oflag, mode_t mode, unsigned int value)

Function

Look up or create a named semaphore in the pthread library's local
registry.

Inputs

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.

Result

Pointer to the named sem_t on success; SEM_FAILED with errno=EINVAL,
EEXIST, ENOENT, ENOMEM, or an error from sem_init() on failure.

Notes

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.

Bugs

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.

sem_post()

Synopsis

int sem_post(
   sem_t *sem)

Function

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.

Inputs

sem - Initialized semaphore whose storage remains valid throughout
    this operation and all concurrent waits.

Result

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.

Notes

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.

Bugs

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.

sem_timedwait()

Synopsis

int sem_timedwait(
   sem_t *sem, const struct timespec *abstime)

Function

Wait for and consume one semaphore permit, subject to an absolute
deadline.

Inputs

sem - Initialized semaphore.
abstime - Absolute deadline forwarded to pthread_cond_timedwait();
          NULL requests an unlimited wait.

Result

0 after decrement; -1 on error, with errno=EINVAL for NULL or the
status returned by the condition wait, including ETIMEDOUT.

Notes

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.

Bugs

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.

sem_trywait()

Synopsis

int sem_trywait(
   sem_t *sem)

Function

Attempt to decrement a semaphore when a positive count is available.

Inputs

sem - Initialized semaphore.

Result

0 after decrement; -1 with errno=EINVAL for NULL or errno=EAGAIN if
the count is zero.

Notes

Protects the count with the semaphore's embedded pthread mutex. A
successful call consumes one permit without notifying other waiters.

Bugs

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.


sem_wait()

Synopsis

int sem_wait(
   sem_t *sem)

Function

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.

Inputs

sem - Initialized semaphore. Keep its storage valid until every active
    operation and waiter has finished.

Result

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.

Notes

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.

Bugs

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().