NAME | SYNOPSIS | API RESTRICTIONS | DESCRIPTION | RETURN VALUE | EXAMPLES | ATTRIBUTES | SEE ALSO
#include <exec/chSoftCtx.h>long threadLoadR(void);
The function or functions documented here may not be used safely in all application contexts with all APIs provided in the ChorusOS 5.0 product.
See API(5FEA) for details.
The execution context of a thread (its various machine registers) is extended by two software registers, one for each of the possible privilege levels of the thread ( USER or SUPERVISOR ). Like hardware registers, these two registers are saved and restored at each thread switch. These registers provide the means for maintaining per-thread data efficiently.
The threadLoadR() system call returns the value of the current thread's software register corresponding to the current privilege level of the thread.
The threadStoreR() system call sets the current thread's software register corresponding to the current privilege level of the thread to the value specified by reg and returns its new value.
The values of these registers may also be affected using threadContext(2K) .
The threadLoadR() call returns the current register value. The threadStoreR() call returns the new register value.
The software register facility can be used to store the thread's local identifier in its software register. However, this impacts on performance only, as threadLoadR() does not imply a microkernel call on most architectures. This is fully resolved in libraries which access a globally shared system context. However, threadSelf(2K) always implies a microkernel call. In order to do this, call:
threadStoreR (threadSelf()); |
at the beginning of the thread's code, then invoke:
threadLoadR ; |
instead of:
threadSelfC ; |
A more common way to use this facility is to associate a per-thread structure with each thread of an actor, and to store the address of this structure in the software register. This will avoid systematically transferring this address as a parameter across the layers of the actor's code (the use of a global variable is not possible, especially on multiprocessor implementations). In this case, each actor's thread will perform a
threadStoreR (myArea); |
at the beginning of the thread's code, where myArea is the address of the per thread's structure. Note that there are several ways for the thread to acquire the (myArea); value. This value may be provided to the thread's routine as an argument (by initializing its stack correctly before creation). It may also be computed by the created thread as the result of a hash function, the hash function taking the thread's local identifier as input, and returning an entry in the array of per-thread records. An alternative to this initialization process is for the creator to call threadContext(2K) before resuming the thread. In each case, the per-thread record is subsequently accessed by threadLoadR() .
Note that the software register may be used differently by different code layers. The sequence S in:
oldVal = threadLoadR (); threadStoreR (newVal); /* S */ threadStoreR (oldVal); |
may make private use of the software register value.
See attributes(5) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
---|---|
Interface Stability | Evolving |
NAME | SYNOPSIS | API RESTRICTIONS | DESCRIPTION | RETURN VALUE | EXAMPLES | ATTRIBUTES | SEE ALSO