/* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* Thread local storage.
*
* See LICENSE.txt for copyright information.
*/
static pthread_key_t tls_key = 0;
static thread_local_state _tls;
static void tls_dtor(void *ptr)
{
al_free(ptr);
}
void _al_tls_init_once(void)
{
pthread_key_create(&tls_key, tls_dtor);
}
static thread_local_state *pthreads_thread_init(void)
{
/* Allocate and copy the 'template' object */
thread_local_state *ptr = (thread_local_state *)al_malloc(sizeof(thread_local_state));
memcpy(ptr, &_tls, sizeof(thread_local_state));
pthread_setspecific(tls_key, ptr);
return ptr;
}
/* This function is short so it can hopefully be inlined. */
static thread_local_state *tls_get(void)
{
thread_local_state *ptr = (thread_local_state*)pthread_getspecific(tls_key);
if (ptr == NULL) {
/* Must create object. */
ptr = pthreads_thread_init();
initialize_tls_values(ptr);
}
return ptr;
}
/* vim: set ft=c sts=3 sw=3: */