cyg_thread_new_data_index, cyg_thread_free_data_index, cyg_thread_get_data, cyg_thread_get_data_ptr, cyg_thread_set_data — Manipulate per-thread data


#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. When a slot index is allocated, then if the CYGVAR_KERNEL_THREADS_LIST option is enabled, the corresponding array entry for all threads will be reset back to zero in case that slot had been previously used.

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.

Valid contexts

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.