X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmapi%2Fmapi%2Fu_thread.h;h=a5e5043701f638341ad31eacab43e6ecb4d613a3;hb=3c690524e2ec0fdd6bef6d50897d6879fdb8b53b;hp=b4487a3400f86a8f2aa8ed9dbf692db16482c076;hpb=bcc13b74443137043e8a34f8cb64a5add0d8af93;p=mesa.git diff --git a/src/mapi/mapi/u_thread.h b/src/mapi/mapi/u_thread.h index b4487a3400f..a5e5043701f 100644 --- a/src/mapi/mapi/u_thread.h +++ b/src/mapi/mapi/u_thread.h @@ -42,14 +42,43 @@ #ifndef _U_THREAD_H_ #define _U_THREAD_H_ +#include +#include #include "u_compiler.h" -#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS) +#if defined(HAVE_PTHREAD) +#include /* POSIX threads headers */ +#endif +#ifdef _WIN32 +#include +#endif + +#if defined(HAVE_PTHREAD) || defined(_WIN32) #ifndef THREADS #define THREADS #endif #endif +/* + * 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 + +#ifdef __cplusplus +extern "C" { +#endif + + /* * POSIX threads. This should be your choice in the Unix world * whenever possible. When building with POSIX threads, be sure @@ -59,12 +88,11 @@ * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable * proper compiling for MT-safe libc etc. */ -#if defined(PTHREADS) -#include /* POSIX threads headers */ +#if defined(HAVE_PTHREAD) struct u_tsd { pthread_key_t key; - int initMagic; + unsigned initMagic; }; typedef pthread_mutex_t u_mutex; @@ -77,7 +105,47 @@ typedef pthread_mutex_t u_mutex; #define u_mutex_lock(name) (void) pthread_mutex_lock(&(name)) #define u_mutex_unlock(name) (void) pthread_mutex_unlock(&(name)) -#endif /* PTHREADS */ +static INLINE unsigned long +u_thread_self(void) +{ + return (unsigned long) pthread_self(); +} + + +static INLINE void +u_tsd_init(struct u_tsd *tsd) +{ + if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { + perror(INIT_TSD_ERROR); + exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +static INLINE void * +u_tsd_get(struct u_tsd *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + u_tsd_init(tsd); + } + return pthread_getspecific(tsd->key); +} + + +static INLINE void +u_tsd_set(struct u_tsd *tsd, void *ptr) +{ + if (tsd->initMagic != INIT_MAGIC) { + u_tsd_init(tsd); + } + if (pthread_setspecific(tsd->key, ptr) != 0) { + perror(SET_TSD_ERROR); + exit(-1); + } +} + +#endif /* HAVE_PTHREAD */ /* @@ -85,82 +153,79 @@ typedef pthread_mutex_t u_mutex; * IMPORTANT: Link with multithreaded runtime library when THREADS are * used! */ -#ifdef WIN32_THREADS -#include +#ifdef _WIN32 struct u_tsd { DWORD key; - int initMagic; + unsigned initMagic; }; typedef CRITICAL_SECTION u_mutex; /* http://locklessinc.com/articles/pthreads_on_windows/ */ #define u_mutex_declare_static(name) \ - /* static */ u_mutex name = {(void*)-1, -1, 0, 0, 0, 0} + static u_mutex name = {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0} #define u_mutex_init(name) InitializeCriticalSection(&name) #define u_mutex_destroy(name) DeleteCriticalSection(&name) #define u_mutex_lock(name) EnterCriticalSection(&name) #define u_mutex_unlock(name) LeaveCriticalSection(&name) -#endif /* WIN32_THREADS */ - - -/* - * BeOS threads. R5.x required. - */ -#ifdef BEOS_THREADS - -/* Problem with OS.h and this file on haiku */ -#ifndef __HAIKU__ -#include -#endif - -#include - -/* The only two typedefs required here - * this is cause of the OS.h problem - */ -#ifdef __HAIKU__ -typedef int32 thread_id; -typedef int32 sem_id; -#endif - -struct u_tsd { - int32 key; - int initMagic; -}; - -/* Use Benaphore, aka speeder semaphore */ -typedef struct { - int32 lock; - sem_id sem; -} benaphore; -typedef benaphore u_mutex; - -#define u_mutex_declare_static(name) \ - static u_mutex name = { 0, 0 } - -#define u_mutex_init(name) \ - name.sem = create_sem(0, #name"_benaphore"), \ - name.lock = 0 - -#define u_mutex_destroy(name) \ - delete_sem(name.sem), \ - name.lock = 0 - -#define u_mutex_lock(name) \ - if (name.sem == 0) \ - u_mutex_init(name); \ - if (atomic_add(&(name.lock), 1) >= 1) \ - acquire_sem(name.sem) - -#define u_mutex_unlock(name) \ - if (atomic_add(&(name.lock), -1) > 1) \ - release_sem(name.sem) - -#endif /* BEOS_THREADS */ +static INLINE unsigned long +u_thread_self(void) +{ + return GetCurrentThreadId(); +} + + +static INLINE void +u_tsd_init(struct u_tsd *tsd) +{ + tsd->key = TlsAlloc(); + if (tsd->key == TLS_OUT_OF_INDEXES) { + perror(INIT_TSD_ERROR); + exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +static INLINE void +u_tsd_destroy(struct u_tsd *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + return; + } + TlsFree(tsd->key); + tsd->initMagic = 0x0; +} + + +static INLINE void * +u_tsd_get(struct u_tsd *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + u_tsd_init(tsd); + } + return TlsGetValue(tsd->key); +} + + +static INLINE void +u_tsd_set(struct u_tsd *tsd, void *ptr) +{ + /* the following code assumes that the struct u_tsd has been initialized + to zero at creation */ + if (tsd->initMagic != INIT_MAGIC) { + u_tsd_init(tsd); + } + if (TlsSetValue(tsd->key, ptr) == 0) { + perror(SET_TSD_ERROR); + exit(-1); + } +} + +#endif /* _WIN32 */ /* @@ -169,7 +234,7 @@ typedef benaphore u_mutex; #ifndef THREADS struct u_tsd { - int initMagic; + unsigned initMagic; }; typedef unsigned u_mutex; @@ -180,22 +245,43 @@ typedef unsigned u_mutex; #define u_mutex_lock(name) (void) name #define u_mutex_unlock(name) (void) name -#endif /* THREADS */ +/* + * no-op functions + */ +static INLINE unsigned long +u_thread_self(void) +{ + return 0; +} -unsigned long -u_thread_self(void); -void -u_tsd_init(struct u_tsd *tsd); +static INLINE void +u_tsd_init(struct u_tsd *tsd) +{ + (void) tsd; +} -void -u_tsd_destroy(struct u_tsd *tsd); /* WIN32 only */ -void * -u_tsd_get(struct u_tsd *tsd); +static INLINE void * +u_tsd_get(struct u_tsd *tsd) +{ + (void) tsd; + return NULL; +} -void -u_tsd_set(struct u_tsd *tsd, void *ptr); + +static INLINE void +u_tsd_set(struct u_tsd *tsd, void *ptr) +{ + (void) tsd; + (void) ptr; +} +#endif /* THREADS */ + + +#ifdef __cplusplus +} +#endif #endif /* _U_THREAD_H_ */