#include <cyg/kernel/kapi.h> |
cyg_ucount32 cyg_thread_new_data_index
(void);
void cyg_thread_free_data_index
(cyg_ucount32 index);
cyg_addrword_t cyg_thread_get_data
(cyg_ucount32 index);
cyg_addrword_t* cyg_thread_get_data_ptr
(cyg_ucount32 index);
void cyg_thread_set_data
(cyg_ucount32 index, cyg_addrword_t data);
In some applications and libraries it is useful to have some data that
is specific to each thread. For example, many of the functions in the
POSIX compatibility package return -1 to indicate an error and store
additional information in what appears to be a global variable
errno
. However, if multiple threads make concurrent
calls into the POSIX library and if errno
were
really a global variable then a thread would have no way of knowing
whether the current errno
value really corresponded
to the last POSIX call it made, or whether some other thread had run
in the meantime and made a different POSIX call which updated the
variable. To avoid such confusion errno
is instead
implemented as a per-thread variable, and each thread has its own
instance.
The support for per-thread data can be disabled via the configuration
option CYGVAR_KERNEL_THREADS_DATA
. If enabled, each
cyg_thread
data structure holds a small array
of words. The size of this array is determined by the configuration
option CYGNUM_KERNEL_THREADS_DATA_MAX
. When a
thread is created the array is filled with zeroes.
If an application needs to use per-thread data then it needs an index
into this array which has not yet been allocated to other code. This
index can be obtained by calling
cyg_thread_new_data_index
, and then used in
subsequent calls to cyg_thread_get_data
.
Typically indices are allocated during system initialization and
stored in static variables. If for some reason a slot in the array is
no longer required and can be re-used then it can be released by calling
cyg_thread_free_data_index
,
The current per-thread data in a given slot can be obtained using
cyg_thread_get_data
. This implicitly operates on
the current thread, and its single argument should be an index as
returned by cyg_thread_new_data_index
. The
per-thread data can be updated using
cyg_thread_set_data
. If a particular item of
per-thread data is needed repeatedly then
cyg_thread_get_data_ptr
can be used to obtain the
address of the data, and indirecting through this pointer allows the
data to be examined and updated efficiently.
Some packages, for example the error and POSIX packages, have
pre-allocated slots in the array of per-thread data. These slots
should not normally be used by application code, and instead slots
should be allocated during initialization by a call to
cyg_thread_new_data_index
. If it is known that,
for example, the configuration will never include the POSIX
compatibility package then application code may instead decide to
re-use the slot allocated to that package,
CYGNUM_KERNEL_THREADS_DATA_POSIX
, but obviously
this does involve a risk of strange and subtle bugs if the
application's requirements ever change.
Typically cyg_thread_new_data_index
is only
called during initialization, but may also be called at any time in
thread context. cyg_thread_free_data_index
, if
used at all, can also be called during initialization or from thread
context. cyg_thread_get_data
,
cyg_thread_get_data_ptr
, and
cyg_thread_set_data
may only be called from
thread context because they implicitly operate on the current thread.