eCos Reference Manual
Prev |  | Next

# Per-thread data

## Name

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

## Synopsis

    #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);`

## Description

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.

## 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.

Prev | Home | Next
Thread priorities | Up | Thread destructors