diff options
Diffstat (limited to 'src/mesa/glapi')
-rw-r--r-- | src/mesa/glapi/glthread.c | 102 | ||||
-rw-r--r-- | src/mesa/glapi/glthread.h | 92 |
2 files changed, 151 insertions, 43 deletions
diff --git a/src/mesa/glapi/glthread.c b/src/mesa/glapi/glthread.c index e7cc8d8d48..ad6380328d 100644 --- a/src/mesa/glapi/glthread.c +++ b/src/mesa/glapi/glthread.c @@ -1,4 +1,4 @@ -/* $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 @@ -26,14 +26,6 @@ /* - * 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. */ @@ -65,10 +57,11 @@ /* - * 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 @@ -95,20 +88,26 @@ _glthread_InitTSD(_glthread_TSD *tsd) 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); @@ -145,6 +144,7 @@ _glthread_InitTSD(_glthread_TSD *tsd) perror(INIT_TSD_ERROR); exit(-1); } + tsd->initMagic = INIT_MAGIC; } @@ -152,6 +152,9 @@ 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); @@ -167,14 +170,10 @@ _glthread_GetTSD(_glthread_TSD *tsd) 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); @@ -212,24 +211,27 @@ _glthread_InitTSD(_glthread_TSD *tsd) /* 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 @@ -241,6 +243,56 @@ _glthread_SetTSD(_glthread_TSD *tsd, void *ptr, void (*initfunc)(void)) #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 */ diff --git a/src/mesa/glapi/glthread.h b/src/mesa/glapi/glthread.h index 600a761682..72fe08ff7f 100644 --- a/src/mesa/glapi/glthread.h +++ b/src/mesa/glapi/glthread.h @@ -1,10 +1,10 @@ -/* $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"), @@ -32,8 +32,31 @@ * 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 @@ -47,8 +70,8 @@ /* * 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 @@ -67,7 +90,7 @@ typedef struct { pthread_key_t key; - pthread_once_t once; + int initMagic; } _glthread_TSD; typedef pthread_t _glthread_Thread; @@ -103,7 +126,7 @@ typedef pthread_mutex_t _glthread_Mutex; typedef struct { thread_key_t key; mutex_t keylock; - int initfuncCalled; + int initMagic; } _glthread_TSD; typedef thread_t _glthread_Thread; @@ -126,13 +149,12 @@ typedef mutex_t _glthread_Mutex; * 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; @@ -150,25 +172,35 @@ typedef CRITICAL_SECTION _glthread_Mutex; - /* - * 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 */ @@ -196,5 +228,29 @@ typedef GLuint _glthread_Mutex; #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 */ |