Defines | |
#define | CU_THREADLOCAL_DECL(name, private_name) |
#define | CU_THREADLOCAL_DEF(name, private_name, static_name) ... |
#define | CU_THREADLOCAL_INIT(name, private_name, static_name) ... |
These boilerplates allows the client application or library to define thread-local storage using an available mechanism. Currently, the __thread keyword is used if detected, otherwise the POSIX threads functons are used. Initialisation is assured either by creating threads with cu_pthread_create or by calling cu_thread_init before any local storage is used.
#define CU_THREADLOCAL_DECL | ( | name, | |||
private_name | ) |
\
name##_t name(void)
Emits declarations for the header file. Assuming that the struct NAME and an associated pointer NAME_t have been defined, this provides a function NAME_t NAME(void)
which returns the thread-local storage. PRIVATE_NAME is a prefix for for identifiers which are to be considered private.
#define CU_THREADLOCAL_DEF | ( | name, | |||
private_name, | |||||
static_name | ) | ... |
Emits definitions associated with CU_THREADLOCAL_DECL(NAME, PRIVATE_NAME). STATIC_NAME is a prefix for file local definitions including the following two functions which must be defined:
void STATIC_NAME_init(NAME_t tls);
void STATIC_NAME_destruct(NAME_t tls);
Returns thread-local state.
#define CU_THREADLOCAL_INIT | ( | name, | |||
private_name, | |||||
static_name | ) | ... |
Emits initialisation code for definitions in CU_THREADLOCAL_DEF(NAME, PRIVATE_NAME, STATIC_NAME). This code must be run in the main thread before other threads are created, typically during a global initialisation phase.
For example, in libfoo/tls.h
put
typedef struct libfoo_tls *libfoo_tls_t; struct libfoo_tls { // Thread-local variables goes here. }; // Provide "libfoo_tls_t libfoo_tls(void)" CU_THREADLOCAL_DECL(libfoo_tls, libfoopriv_tls);
and in libfoo/init.c
,
... CU_THREADLOCAL_DEF(libfoo_tls, libfoopriv_tls, _tls); ... void libfoo_init(void) { ... CU_THREADLOCAL_INIT(libfoo_tls, libfoopriv_tls, _tls); ... }