/*
 * Mesa 3-D graphics library
 * Version:  6.5.1
 *
 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


/*
 * XXX There's probably some work to do in order to make this file
 * truly reusable outside of Mesa.
 */


#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include "glthread.h"


/*
 * This file should still compile even when THREADS is not defined.
 * This is to make things easier to deal with on the makefile scene..
 */
#ifdef THREADS
#include <errno.h>

/*
 * Error messages
 */
#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"


/*
 * Magic number to determine if a TSD object has been initialized.
 * Kind of a hack but there doesn't appear to be a better cross-platform
 * solution.
 */
#define INIT_MAGIC 0xff8adc98



/*
 * POSIX Threads -- The best way to go if your platform supports them.
 *                  Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
 *                  has them, and many of the free Unixes now have them.
 *                  Be sure to use appropriate -mt or -D_REENTRANT type
 *                  compile flags when building.
 */
#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/*free*/) != 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 /* PTHREADS */



/*
 * Solaris/Unix International Threads -- Use only if POSIX threads
 *   aren't available on your Unix platform.  Solaris 2.[34] are examples
 *   of platforms where this is the case.  Be sure to use -mt and/or
 *   -D_REENTRANT when compiling.
 */
#ifdef SOLARIS_THREADS
#define USE_LOCK_FOR_KEY	/* undef this to try a version without
				   lock for the global key... */

unsigned long
_glthread_GetID(void)
{
   abort();   /* XXX not implemented yet */
   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 /* SOLARIS_THREADS */



/*
 * Win32 Threads.  The only available option for Windows 95/NT.
 * Be sure that you compile using the Multithreaded runtime, otherwise
 * bad things will happen.
 */
#ifdef WIN32_THREADS

void FreeTSD(_glthread_TSD *p)
{
   if (p->initMagic==INIT_MAGIC) {
      TlsFree(p->key);
      p->initMagic=0;
   }
}

void InsteadOf_exit(int nCode)
{
   DWORD dwErr=GetLastError();
}

unsigned long
_glthread_GetID(void)
{
   return GetCurrentThreadId();
}


void
_glthread_InitTSD(_glthread_TSD *tsd)
{
   tsd->key = TlsAlloc();
   if (tsd->key == TLS_OUT_OF_INDEXES) {
      perror("Mesa:_glthread_InitTSD");
      InsteadOf_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)
{
   /* the following code assumes that the _glthread_TSD has been initialized
      to zero at creation */
   if (tsd->initMagic != INIT_MAGIC) {
      _glthread_InitTSD(tsd);
   }
   if (TlsSetValue(tsd->key, ptr) == 0) {
	  perror("Mesa:_glthread_SetTSD");
	  InsteadOf_exit(-1);
   }
}

#endif /* WIN32_THREADS */



/*
 * XFree86 has its own thread wrapper, Xthreads.h
 * We wrap it again for GL.
 */
#ifdef USE_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 /* XTHREAD */



/*
 * BeOS threads
 */
#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 /* BEOS_THREADS */



#else  /* THREADS */


/*
 * no-op functions
 */

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 /* THREADS */
