This section describes the API for the POSIX threads and timers in ChorusOS (see intro(2K)).
The POSIX threads provide a limited POSIX-compliant programming and execution environment including thread management and thread synchronization functions. It is complemented by the POSIX timers, which adds POSIX real-time clock and timer features. POSIX-THREADS is based on the draft standard P1003.1c (Threads Extension) Draft 8, POSIX-TIMERS on IEEE Std 1003.1b-1993.
Symbols corresponding to POSIX numerical limits are defined in <limits.h>. However if a definition of one of the values defined by POSIX is omitted from <limits.h>, its actual value is provided by the sysconf(3POSIX) function.
As different POSIX profiles may be supported by the same set of header files, the POSIX-THREADS/POSIX-TIMERS option symbols are defined in <unistd.h>. An application may always choose to interrogate a value at run-time to take advantage of the current configuration using the sysconf(3POSIX) function.
The following POSIX option symbols are defined in the context of these features. For POSIX-THREADS:
_POSIX_SEMAPHORES _POSIX_THREADS _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_THREAD_ATTR_STACKSIZE _POSIX_THREAD_ATTR_STACKADDR
However, some features in the POSIX standards associated with these option symbols are not supported in ChorusOS. In other cases, the semantics provided are slightly different, as follows:
No interfaces related to thread cancellation are provided.
Threads are awakened by sem_post, pthread_mutex_unlock, and pthread_cond_signal in the order in which they had blocked on the respective synchronization object, rather than in priority order.
The symbols _SC_PTHREAD_THREADS_MAX and _SC_PTHREAD_KEYS_MAX respectively, define limits on the number of threads and the number of thread-specific data keys per system rather than per process (actor) as defined in POSIX.
Most functions are identical in user and supervisor actors. However, an application running in supervisor mode may not create a thread with a pre-allocated stack.
In all other areas, an attempt has been made to conform precisely to the specifications of the two POSIX standards.
A POSIX application runs as a Chorus actor. The POSIX interfaces described in this manual are seen as extensions to the standard ChorusOS programming environment. In several areas, ChorusOS and POSIX semantics interact.
The SCHED_FIFO and SCHED_RR scheduling policies are provided as specified in POSIX 1003.1b. (A third policy, SCHED_OTHER, is identical to SCHED_RR.) The SCHED_FIFO policy provides strict preemptive scheduling within a range of priorities that may be obtained using sched_get_priority_min and sched_get_priority_max. Except when thread priorities are dynamically modified, a running thread continues executing until it blocks voluntarily or is preempted by a thread of higher priority, in which case it is queued at the head of the list of runnable threads corresponding to its priority level. The SCHED_RR policy is the same except that a thread that executes longer than a pre-defined quantum (obtainable using sched_rr_get_interval) may be descheduled and queued behind any other runnable threads waiting to execute at the same priority.
The POSIX threads are mapped one-to-one onto ChorusOS threads: the POSIX SCHED_FIFO and SCHED_RR scheduling policies are mapped onto the K_SCHED_FIFO and K_SCHED_RR scheduling classes, respectively. The priority mapping is defined below. Note that the priority systems scales are reversed:
In the ChorusOS scheduling classes, a larger numeric priority value indicates a lower thread priority.
Under the SCHED_FIFO and SCHED_RR policies, a higher priority value indicates a higher thread priority.
POSIX priorities in the range POSIX_FIFO_MIN (0) to POSIX_FIFO_MAX (255) are mapped one-to-one onto the CHORUS K_SCHED_FIFO class priority range K_FIFO_PRIOMIN (255) to K_FIFO_PRIOMAX (0).
POSIX priorities in the range POSIX_RR_MIN (0) to POSIX_RR_MAX (255) are mapped one-to-one onto the CHORUS K_SCHED_RR class priority range K_RR_PRIOMON (255) to K_RR_PRIOMAX (0).
The default policy and priority are determined as follows. The first invocation of a substantive function of either the POSIX-THREADS or the POSIX-TIMERS (if included) features triggers initialization of both features. (Calls that create or manipulate threads, thread attribute objects, or timers are considered substantive for this purpose.) At that point the calling thread, which is normally the initial thread of the actor, is transformed into a POSIX thread (pthread), as if it had been created using y pthread_create in the state PTHREAD_CREATE_DETACHED (see pthread_create(3POSIX), pthread_attr_init(3POSIX)). Its ChorusOS thread priority is obtained (see threadScheduler(2K)) and mapped into a POSIX policy and priority using the reverse of the mappings defined above. These policy and priority values become the defaults for threads created in PTHREAD_EXPLICIT_SCHED (see pthread_attr_init(3POSIX)). Note that this procedure can only operate correctly if the calling thread is in the ChorusOS K_SCHED_FIFO or K_SCHED_RR class. If the calling thread is in a different CHORUS scheduling class, then the default policy is set to SCHED_RR and the default priority is set to POSIX_RR_MIN.
All threads are scheduled on a system-wide basis, according to their priority (and scheduling class). Hence the POSIX option PTHREAD_SCOPE_PROCESS is not supported (see pthread_attr_setscope(3POSIX)).
POSIX applications are expected to use POSIX facilities for thread management wherever possible, rather than the corresponding ChorusOS facilities. However, some applications may involve threads which are not pthreads (not created by pthread_create), such as message handlers in supervisor actors. Furthermore, certain ChorusOS thread management services with no POSIX analogues may be useful in some applications.
When POSIX threads are created using the facilities in this manual, the POSIX thread identifier type pthread_t is equivalent to the ChorusOS thread local identifier. That is, the value returned by the thread argument of pthread_create is always equal to the threadli of the underlying ChorusOS thread.
As mentioned earlier, the first invocation of POSIX-THREADS or POSIX-TIMERS transforms the calling thread into a pthread. Other threads in the actor are not pthreads unless created by pthread_create. However, many POSIX services may be invoked by pure ChorusOS threads. In particular, POSIX mutexes, condition variables, and semaphores may be freely used for synchronization between and among POSIX threads and pure CHORUS threads. Certain POSIX functions have limitations regarding invocation from pure CHORUS threads.
May be used to create a POSIX thread; the PTHREAD_EXPLICIT_SCHED attribute is assumed. PTHREAD_INHERIT_SCHED is ignored if specified
Deletes the calling thread, ignoring the status argument. (Non-pthreads cannot be joined using pthread_join)
Requires that the caller be a POSIX thread; otherwise an error (ENOSYS) is returned
The following CHORUS Core Executive system calls may be useful in manipulating POSIX threads.
If a pthread is aborted while blocked or executing in certain POSIX functions, the result is the same as that defined in POSIX on arrival of a caught signal. In particular, pthread_join, sem_wait, sem_trywait, and nanosleep return EINTR and may take other actions in the event of a thread abort (see the corresponding manual pages for details). Otherwise, no support for thread abort is provided at the POSIX level.
The following interface object types are used in the definition of the various POSIX functions. Formal definitions are found in <pthread.h>, <time.h>, <sched.h>, or <signal.h>.
POSIX thread identifier (equal to the corresponding threadli)
POSIX thread attribute object (see pthread_attr_init(3POSIX))
Mutex, or blocking binary semaphore (see pthread_mutex_init(3POSIX))
Mutex attribute object; no attributes currently defined (see pthread_mutexattr_init(3POSIX))
Condition variable (see pthread_cond_init(3POSIX))
Condition variable attribute object; no attributes currently defined (see pthread_condattr_init(3POSIX))
Key for lookup of per-thread data within actor (see pthread_key_create(3POSIX))
Counting semaphore (see sem_init(3POSIX))
(standard C type) used for passing an arbitrary untyped value (not necessarily a pointer) in pthread_exit, pthread_join, pthread_setspecific, and pthread_getspecific
Variable used to record the initialization of a dynamic library (see pthread_once(3POSIX))
Scheduling parameter structure, defined for each scheduling policy. For the policies currently supported, there is only one member, sched_priority.
Clock identifier. Only one clock, the system realtime clock, is supported. (see clock_settime(3POSIX))
Structure defining action to take on asynchronous event notification. Contains a notification routine address and a single argument (see timer_create(3POSIX))
Identifier of one-shot or periodic timer (see timer_create(3POSIX))
Standard time interval specification, in terms of seconds and additional nanoseconds.
Timer setting. Contains one struct timespec defining the time interval or absolute time, and another specifying the reload interval for a periodic timer.
Object size in bytes.
WARNING: error reporting conventions are inconsistent by design in the POSIX-THREADS and POSIX-TIMERS features (see intro(2K)). Error returns from POSIX-compliant interfaces follow the corresponding POSIX standards precisely, in which two different styles of return code are used:
(those beginning with sem_, sched_, clock_, and timer_; and nanosleep) return -1 in case of error and store the error code in errno.
(those beginning with pthread_) return the error code directly and do not set errno.
In addition, error codes are used differently in some cases. For example, an unsuccessful sem_trywait (1003.1b) returns EAGAIN, whereas an unsuccessful pthread_mutex_try (1003.1c) returns EBUSY. Invalid virtual addresses are flagged with EFAULT in 1003.1b functions and EINVAL in 1003.1c functions. Individual man pages contain information about the error codes returned by each routine.
The EFAULT error code will be returned where possible. However the library implementation of the POSIX interface accesses pointer arguments. Hence bad virtual addresses can cause a segmentation fault, instead of returning EFAULT error code.
Attempted to perform a restricted operation for which the caller does not have the privilege.
A pthread call designated a non-existent target thread, or a thread which is not a pthread.
The thread was aborted while blocked or executing in the function.
Some object or resource was unavailable, but the call may succeed if retried.
Memory was unavailable, but the call may succeed if retried.
A pointer argument contained an unmapped or inaccessible virtual address (user mode only).
Some object or resource was in use by another thread.
An argument was invalid, or a virtual address was unmapped or inaccessible (user mode only).
A thread attempted to join (pthread_join) with itself.
The function is not provided in the mode of the current actor.
The specified interval expired before the function completed.
The requested option is not supported.
See attributes(5) for descriptions of the following attributes:
|ATTRIBUTE TYPE||ATTRIBUTE VALUE|
btree database access method
get or set clock to specified value, or get clock resolution
database access methods
formatted error messages
get working directory pathname
get generic disk description by its name
get information about mounted file systems
get network entry
netgroup database operations
get protocol entry
get service entry
generate pathnames matching a pattern
hash database access method
elementary address specification routines for link level access
shared memory buffer pool
delay the current thread with high resolution
Xerox NS address conversion routines
Initialize a thread attribute object; Destroy a thread attribute object; Set the stacksize attribute; Get the stacksize attribute; Set the stackaddr attribute; Get the stackaddr attribute; Set the detachstate attribute; Get the detachstate attribute
Set the contention scope attribute; Get the contention scope attribute; Set the scheduling inheritance attribute; Get the scheduling inheritance attribute; Set the scheduling policy attribute; Get the scheduling policy attribute; Set the scheduling parameter attribute; Get the scheduling parameter attribute
initialize and use a condition variable
initialize or destroy a condition variable attribute object
create a thread
compare thread identifiers
terminate the calling thread
wait for thread termination
create or delete a thread-specific data key
send a deletion signal to a thread
initialize and use a mutex
initialize or destroy a mutex attribute object
initialize a library dynamically
get the identifier of the calling thread
set or get current scheduling policy and parameters of a thread
set or get the thread-specific value associated with a key
yield processor to another thread
record number database access method
get priority and time quantum information for scheduling policy
initialize and use a semaphore
get configurable system variables
get or set system information
manipulating the termios structure
create or delete a timer
set and arm or disarm a timer, obtain remaining interval for an active timer, or obtain current overrun count for a timer