#include "glheader.h"
#include "glthread.h"
#ifdef THREADS
#include <errno.h>
#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
#define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
#define INIT_MAGIC 0xff8adc98
#ifdef PTHREADS
unsigned long
_glthread_GetID(void)
{
return (unsigned long) pthread_self();
}
void
_glthread_InitTSD(_glthread_TSD *tsd)
{
if (pthread_key_create(&tsd->key, NULL) != 0) {
perror(INIT_TSD_ERROR);
exit(-1);
}
tsd->initMagic = INIT_MAGIC;
}
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
if (tsd->initMagic != (int) INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
return pthread_getspecific(tsd->key);
}
void
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
if (tsd->initMagic != (int) INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
if (pthread_setspecific(tsd->key, ptr) != 0) {
perror(SET_TSD_ERROR);
exit(-1);
}
}
#endif
#ifdef SOLARIS_THREADS
#define USE_LOCK_FOR_KEY
unsigned long
_glthread_GetID(void)
{
abort();
return (unsigned long) 0;
}
void
_glthread_InitTSD(_glthread_TSD *tsd)
{
if ((errno = mutex_init(&tsd->keylock, 0, NULL)) != 0 ||
(errno = thr_keycreate(&(tsd->key), free)) != 0) {
perror(INIT_TSD_ERROR);
exit(-1);
}
tsd->initMagic = INIT_MAGIC;
}
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
void* ret;
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
#ifdef USE_LOCK_FOR_KEY
mutex_lock(&tsd->keylock);
thr_getspecific(tsd->key, &ret);
mutex_unlock(&tsd->keylock);
#else
if ((errno = thr_getspecific(tsd->key, &ret)) != 0) {
perror(GET_TSD_ERROR);
exit(-1);
}
#endif
return ret;
}
void
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
perror(SET_TSD_ERROR);
exit(-1);
}
}
#undef USE_LOCK_FOR_KEY
#endif
#ifdef WIN32_THREADS
unsigned long
_glthread_GetID(void)
{
abort();
return (unsigned long) 0;
}
void
_glthread_InitTSD(_glthread_TSD *tsd)
{
tsd->key = TlsAlloc();
if (tsd->key == 0xffffffff) {
exit(-1);
}
tsd->initMagic = INIT_MAGIC;
}
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
return TlsGetValue(tsd->key);
}
void
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
if (TlsSetValue(tsd->key, ptr) == 0) {
exit(-1);
}
}
#endif
#ifdef XTHREADS
unsigned long
_glthread_GetID(void)
{
return (unsigned long) xthread_self();
}
void
_glthread_InitTSD(_glthread_TSD *tsd)
{
if (xthread_key_create(&tsd->key, NULL) != 0) {
perror(INIT_TSD_ERROR);
exit(-1);
}
tsd->initMagic = INIT_MAGIC;
}
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
void *ptr;
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
xthread_get_specific(tsd->key, &ptr);
return ptr;
}
void
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
xthread_set_specific(tsd->key, ptr);
}
#endif
#ifdef BEOS_THREADS
unsigned long
_glthread_GetID(void)
{
return (unsigned long) find_thread(NULL);
}
void
_glthread_InitTSD(_glthread_TSD *tsd)
{
tsd->key = tls_allocate();
tsd->initMagic = INIT_MAGIC;
}
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
if (tsd->initMagic != (int) INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
return tls_get(tsd->key);
}
void
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
if (tsd->initMagic != (int) INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
tls_set(tsd->key, ptr);
}
#endif
#else
unsigned long
_glthread_GetID(void)
{
return 0;
}
void
_glthread_InitTSD(_glthread_TSD *tsd)
{
(void) tsd;
}
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
(void) tsd;
return NULL;
}
void
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
(void) tsd;
(void) ptr;
}
#endif