NAME | DESCRIPTION | INTERFACE TYPE DEFINITIONS | ERROR CODES | ATTRIBUTES
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. This environment is complemented by the POSIX timers, which add POSIX real-time clock and timer features. POSIX-THREADS are 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 the 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
For POSIX-TIMERS:
_POSIX_TIMERS
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 ChorusOS 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 features (if included) triggers initialization of both features. (Calls that create or manipulate threads, thread attribute objects, or timers are considered substantive for this purpose.) When initialization is triggered, 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 pthread_create() in the state PTHREAD_CREATE_DETACHED (see pthread_create(3POSIX) and 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, 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 theirpr iority (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 ChorusOS threads. Certain POSIX functions have limitations regarding invocation from pure ChorusOS 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 ChorusOS 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 man 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 the 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 is 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 the 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 |
---|---|
Interface Stability | Evolving |
NAME | DESCRIPTION | INTERFACE TYPE DEFINITIONS | ERROR CODES | ATTRIBUTES