-/* $Id: glthread.c,v 1.3 2000/01/28 18:57:56 brianp Exp $ */
+/* $Id: glthread.c,v 1.4 2000/02/10 21:27:25 brianp Exp $ */
/*
* Mesa 3-D graphics library
/*
- * Thread support for gl dispatch.
- *
- * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu)
- * and Christoph Poliwoda (poliwoda@volumegraphics.com)
- *
- * Revised by Keith Whitwell
- * Adapted for new gl dispatcher by Brian Paul
- *
* XXX There's probably some work to do in order to make this file
* truly reusable outside of Mesa. First, the glheader.h include must go.
*/
/*
- * magic number for win32 and solaris threads equivalents of pthread_once
- * This could probably be done better, but we haven't figured out how yet.
+ * 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 INITFUNC_CALLED_MAGIC 0xff8adc98
+#define INIT_MAGIC 0xff8adc98
perror(INIT_TSD_ERROR);
exit(-1);
}
+ tsd->initMagic = INIT_MAGIC;
}
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
+ if (tsd->initMagic != INIT_MAGIC) {
+ _glthread_InitTSD(tsd);
+ }
return pthread_getspecific(tsd->key);
}
void
-_glthread_SetTSD(_glthread_TSD *tsd, void *ptr, void (*initfunc)(void))
+_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
- pthread_once(&tsd->once, initfunc);
+ if (tsd->initMagic != INIT_MAGIC) {
+ _glthread_InitTSD(tsd);
+ }
if (pthread_setspecific(tsd->key, ptr) != 0) {
perror(SET_TSD_ERROR);
exit(-1);
perror(INIT_TSD_ERROR);
exit(-1);
}
+ tsd->initMagic = INIT_MAGIC;
}
_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);
void
-_glthread_SetTSD(_glthread_TSD *tsd, void *ptr, void (*initfunc)(void))
+_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
- /* the following code assumes that the _glthread_TSD has been initialized
- to zero at creation */
- fprintf(stderr, "initfuncCalled = %d\n", tsd->initfuncCalled);
- if (tsd->initfuncCalled != INITFUNC_CALLED_MAGIC) {
- initfunc();
- tsd->initfuncCalled = INITFUNC_CALLED_MAGIC;
+ if (tsd->initMagic != INIT_MAGIC) {
+ _glthread_InitTSD(tsd);
}
if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
perror(SET_TSD_ERROR);
/* perror(SET_INIT_ERROR);*/
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, void (*initfunc)(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->initfuncCalled != INITFUNC_CALLED_MAGIC) {
- initfunc();
- tsd->initfuncCalled = INITFUNC_CALLED_MAGIC;
+ if (tsd->initMagic != INIT_MAGIC) {
+ _glthread_InitTSD(tsd);
}
if (TlsSetValue(tsd->key, ptr) == 0) {
/* Can Windows handle stderr messages for non-console
#endif /* WIN32 */
+
+
+/*
+ * XFree86 has its own thread wrapper, Xthreads.h
+ * We wrap it again for GL.
+ */
+#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 /* XTHREAD */
+
+
#endif /* THREADS */
-/* $Id: glthread.h,v 1.2 2000/01/31 23:10:47 brianp Exp $ */
+/* $Id: glthread.h,v 1.3 2000/02/10 21:27:25 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
*
- * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2000 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"),
* and Christoph Poliwoda (poliwoda@volumegraphics.com)
* Revised by Keith Whitwell
* Adapted for new gl dispatcher by Brian Paul
+ *
+ *
+ *
+ * DOCUMENTATION
+ *
+ * This thread module exports the following types:
+ * _glthread_TSD Thread-specific data area
+ * _glthread_Thread Thread datatype
+ * _glthread_Mutex Mutual exclusion lock
+ *
+ * Macros:
+ * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex
+ * _glthread_INIT_MUTEX(name) Initialize a mutex
+ * _glthread_LOCK_MUTEX(name) Lock a mutex
+ * _glthread_UNLOCK_MUTEX(name) Unlock a mutex
+ *
+ * Functions:
+ * _glthread_GetID(v) Get integer thread ID
+ * _glthread_InitTSD() Initialize thread-specific data
+ * _glthread_GetTSD() Get thread-specific data
+ * _glthread_SetTSD() Set thread-specific data
+ *
*/
+
#ifndef GLTHREAD_H
#define GLTHREAD_H
/*
* It is an error not to select a specific threads API when compiling.
*/
-#if !defined(PTHREADS) && !defined(SOLARIS_THREADS) && !defined(WIN32)
-#error One of PTHREADS, SOLARIS_THREADS or WIN32 must be defined.
+#if !defined(PTHREADS) && !defined(SOLARIS_THREADS) && !defined(WIN32) && !defined(XTHREADS)
+#error One of PTHREADS, SOLARIS_THREADS, WIN32 or XTHREADS must be defined.
#endif
typedef struct {
pthread_key_t key;
- pthread_once_t once;
+ int initMagic;
} _glthread_TSD;
typedef pthread_t _glthread_Thread;
typedef struct {
thread_key_t key;
mutex_t keylock;
- int initfuncCalled;
+ int initMagic;
} _glthread_TSD;
typedef thread_t _glthread_Thread;
* IMPORTANT: Link with multithreaded runtime library when THREADS are
* used!
*/
-
#ifdef WIN32
#include <windows.h>
typedef struct {
DWORD key;
- int initfuncCalled;
+ int initMagic;
} _glthread_TSD;
typedef HANDLE _glthread_Thread;
-
/*
- * Platform independent thread specific data API.
+ * XFree86 has its own thread wrapper, Xthreads.h
+ * We wrap it again for GL.
*/
+#ifdef XTHREADS
+#include "Xthreads.h"
-extern unsigned long
-_glthread_GetID(void);
+typedef struct {
+ xthread_key_t key;
+ int initMagic;
+} _glthread_TSD;
+typedef xthread_t _glthread_Thread;
-extern void
-_glthread_InitTSD(_glthread_TSD *);
+typedef xmutex_rec _glthread_Mutex;
+#define _glthread_DECLARE_STATIC_MUTEX(name) \
+ static _glthread_Mutex name = XMUTEX_INITIALIZER
-extern void *
-_glthread_GetTSD(_glthread_TSD *);
+#define _glthread_INIT_MUTEX(name) \
+ xmutex_init(&(name))
+#define _glthread_LOCK_MUTEX(name) \
+ (void) xmutex_lock(&(name))
-extern void
-_glthread_SetTSD(_glthread_TSD *, void *, void (*initfunc)(void));
+#define _glthread_UNLOCK_MUTEX(name) \
+ (void) xmutex_unlock(&(name))
+
+#endif /* XTHREADS */
#endif /* THREADS */
+
+
+/*
+ * Platform independent thread specific data API.
+ */
+
+extern unsigned long
+_glthread_GetID(void);
+
+
+extern void
+_glthread_InitTSD(_glthread_TSD *);
+
+
+extern void *
+_glthread_GetTSD(_glthread_TSD *);
+
+
+extern void
+_glthread_SetTSD(_glthread_TSD *, void *);
+
+
+
+
#endif /* THREADS_H */