summaryrefslogtreecommitdiff
path: root/src/mesa/glapi
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/glapi')
-rw-r--r--src/mesa/glapi/gen/gl_x86-64_asm.py2
-rw-r--r--src/mesa/glapi/gen/gl_x86_asm.py2
-rw-r--r--src/mesa/glapi/glapi.c348
-rw-r--r--src/mesa/glapi/glapi.h86
-rw-r--r--src/mesa/glapi/glapi_getproc.c286
-rw-r--r--src/mesa/glapi/glthread.c91
-rw-r--r--src/mesa/glapi/glthread.h122
7 files changed, 441 insertions, 496 deletions
diff --git a/src/mesa/glapi/gen/gl_x86-64_asm.py b/src/mesa/glapi/gen/gl_x86-64_asm.py
index 31c1a2b93a..8ac57ab7eb 100644
--- a/src/mesa/glapi/gen/gl_x86-64_asm.py
+++ b/src/mesa/glapi/gen/gl_x86-64_asm.py
@@ -138,7 +138,7 @@ class PrintGenericStubs(gl_XML.gl_print_base):
print '# define GL_PREFIX(n) GLNAME(CONCAT(gl,n))'
print '# endif'
print ''
- print '#if defined(PTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
+ print '#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
print '# define THREADS'
print '#endif'
print ''
diff --git a/src/mesa/glapi/gen/gl_x86_asm.py b/src/mesa/glapi/gen/gl_x86_asm.py
index d210f3a248..a48724ee61 100644
--- a/src/mesa/glapi/gen/gl_x86_asm.py
+++ b/src/mesa/glapi/gen/gl_x86_asm.py
@@ -79,7 +79,7 @@ class PrintGenericStubs(gl_XML.gl_print_base):
print '#define GLOBL_FN(x) GLOBL x'
print '#endif'
print ''
- print '#if defined(PTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
+ print '#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
print '# define THREADS'
print '#endif'
print ''
diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c
index 2fa673d307..13de594aaf 100644
--- a/src/mesa/glapi/glapi.c
+++ b/src/mesa/glapi/glapi.c
@@ -59,7 +59,6 @@
#endif
#include "glapi/glapi.h"
-#include "glapi/glapioffsets.h"
#include "glapi/glapitable.h"
extern _glapi_proc __glapi_noop_table[];
@@ -106,39 +105,23 @@ PUBLIC __thread void * _glapi_tls_Context
__attribute__((tls_model("initial-exec")));
PUBLIC const struct _glapi_table *_glapi_Dispatch = NULL;
+
PUBLIC const void *_glapi_Context = NULL;
#else
#if defined(THREADS)
-#ifdef WIN32_THREADS
-/* _glthread_DECLARE_STATIC_MUTEX is broken on windows. There will be race! */
-#define CHECK_MULTITHREAD_LOCK()
-#define CHECK_MULTITHREAD_UNLOCK()
-#else
-_glthread_DECLARE_STATIC_MUTEX(ThreadCheckMutex);
-#define CHECK_MULTITHREAD_LOCK() _glthread_LOCK_MUTEX(ThreadCheckMutex)
-#define CHECK_MULTITHREAD_UNLOCK() _glthread_UNLOCK_MUTEX(ThreadCheckMutex)
-#endif
-
static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */
+
_glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */
-static _glthread_TSD ContextTSD; /**< Per-thread context pointer */
-#if defined(WIN32_THREADS)
-void FreeTSD(_glthread_TSD *p);
-void FreeAllTSD(void)
-{
- FreeTSD(&_gl_DispatchTSD);
- FreeTSD(&ContextTSD);
-}
-#endif /* defined(WIN32_THREADS) */
+static _glthread_TSD ContextTSD; /**< Per-thread context pointer */
#endif /* defined(THREADS) */
-PUBLIC struct _glapi_table *_glapi_Dispatch =
- (struct _glapi_table *) __glapi_noop_table;
+PUBLIC struct _glapi_table *_glapi_Dispatch = (struct _glapi_table *) __glapi_noop_table;
+
PUBLIC void *_glapi_Context = NULL;
#endif /* defined(GLX_USE_TLS) */
@@ -146,6 +129,36 @@ PUBLIC void *_glapi_Context = NULL;
+#if defined(THREADS) && !defined(GLX_USE_TLS)
+
+void
+_glapi_init_multithread(void)
+{
+ _glthread_InitTSD(&_gl_DispatchTSD);
+ _glthread_InitTSD(&ContextTSD);
+}
+
+void
+_glapi_destroy_multithread(void)
+{
+#ifdef WIN32_THREADS
+ _glthread_DestroyTSD(&_gl_DispatchTSD);
+ _glthread_DestroyTSD(&ContextTSD);
+#endif
+}
+
+/**
+ * Mutex for multithread check.
+ */
+#ifdef WIN32_THREADS
+/* _glthread_DECLARE_STATIC_MUTEX is broken on windows. There will be race! */
+#define CHECK_MULTITHREAD_LOCK()
+#define CHECK_MULTITHREAD_UNLOCK()
+#else
+_glthread_DECLARE_STATIC_MUTEX(ThreadCheckMutex);
+#define CHECK_MULTITHREAD_LOCK() _glthread_LOCK_MUTEX(ThreadCheckMutex)
+#define CHECK_MULTITHREAD_UNLOCK() _glthread_UNLOCK_MUTEX(ThreadCheckMutex)
+#endif
/**
* We should call this periodically from a function such as glXMakeCurrent
@@ -154,7 +167,6 @@ PUBLIC void *_glapi_Context = NULL;
PUBLIC void
_glapi_check_multithread(void)
{
-#if defined(THREADS) && !defined(GLX_USE_TLS)
static unsigned long knownID;
static GLboolean firstCall = GL_TRUE;
@@ -163,9 +175,7 @@ _glapi_check_multithread(void)
CHECK_MULTITHREAD_LOCK();
if (firstCall) {
- /* initialize TSDs */
- (void) _glthread_GetTSD(&ContextTSD);
- (void) _glthread_GetTSD(&_gl_DispatchTSD);
+ _glapi_init_multithread();
knownID = _glthread_GetID();
firstCall = GL_FALSE;
@@ -176,9 +186,21 @@ _glapi_check_multithread(void)
_glapi_set_context(NULL);
}
CHECK_MULTITHREAD_UNLOCK();
-#endif
}
+#else
+
+void
+_glapi_init_multithread(void) { }
+
+void
+_glapi_destroy_multithread(void) { }
+
+PUBLIC void
+_glapi_check_multithread(void) { }
+
+#endif
+
/**
@@ -212,198 +234,12 @@ _glapi_get_context(void)
#if defined(GLX_USE_TLS)
return _glapi_tls_Context;
#elif defined(THREADS)
- if (ThreadSafe) {
- return _glthread_GetTSD(&ContextTSD);
- }
- else {
- return _glapi_Context;
- }
+ return (ThreadSafe) ? _glthread_GetTSD(&ContextTSD) : _glapi_Context;
#else
return _glapi_Context;
#endif
}
-#ifdef USE_X86_ASM
-
-#if defined( GLX_USE_TLS )
-extern GLubyte gl_dispatch_functions_start[];
-extern GLubyte gl_dispatch_functions_end[];
-#else
-extern const GLubyte gl_dispatch_functions_start[];
-#endif
-
-#endif /* USE_X86_ASM */
-
-
-#if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS)
-# define DISPATCH_FUNCTION_SIZE 16
-#elif defined(USE_X86_ASM)
-# if defined(THREADS) && !defined(GLX_USE_TLS)
-# define DISPATCH_FUNCTION_SIZE 32
-# else
-# define DISPATCH_FUNCTION_SIZE 16
-# endif
-#endif
-
-#ifdef USE_SPARC_ASM
-#ifdef GLX_USE_TLS
-extern unsigned int __glapi_sparc_tls_stub;
-#else
-extern unsigned int __glapi_sparc_pthread_stub;
-#endif
-#endif
-
-#if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) && !defined(XGLServer)
-# define NEED_FUNCTION_POINTER
-#endif
-
-#if defined(PTHREADS) || defined(GLX_USE_TLS)
-/**
- * Perform platform-specific GL API entry-point fixups.
- */
-static void
-init_glapi_relocs( void )
-{
-#if defined(USE_X86_ASM) && defined(GLX_USE_TLS) && !defined(GLX_X86_READONLY_TEXT)
- extern unsigned long _x86_get_dispatch(void);
- char run_time_patch[] = {
- 0x65, 0xa1, 0, 0, 0, 0 /* movl %gs:0,%eax */
- };
- GLuint *offset = (GLuint *) &run_time_patch[2]; /* 32-bits for x86/32 */
- const GLubyte * const get_disp = (const GLubyte *) run_time_patch;
- GLubyte * curr_func = (GLubyte *) gl_dispatch_functions_start;
-
- *offset = _x86_get_dispatch();
- while ( curr_func != (GLubyte *) gl_dispatch_functions_end ) {
- (void) memcpy( curr_func, get_disp, sizeof(run_time_patch));
- curr_func += DISPATCH_FUNCTION_SIZE;
- }
-#endif
-#ifdef USE_SPARC_ASM
- extern void __glapi_sparc_icache_flush(unsigned int *);
- static const unsigned int template[] = {
-#ifdef GLX_USE_TLS
- 0x05000000, /* sethi %hi(_glapi_tls_Dispatch), %g2 */
- 0x8730e00a, /* srl %g3, 10, %g3 */
- 0x8410a000, /* or %g2, %lo(_glapi_tls_Dispatch), %g2 */
-#ifdef __arch64__
- 0xc259c002, /* ldx [%g7 + %g2], %g1 */
- 0xc2584003, /* ldx [%g1 + %g3], %g1 */
-#else
- 0xc201c002, /* ld [%g7 + %g2], %g1 */
- 0xc2004003, /* ld [%g1 + %g3], %g1 */
-#endif
- 0x81c04000, /* jmp %g1 */
- 0x01000000, /* nop */
-#else
-#ifdef __arch64__
- 0x03000000, /* 64-bit 0x00 --> sethi %hh(_glapi_Dispatch), %g1 */
- 0x05000000, /* 64-bit 0x04 --> sethi %lm(_glapi_Dispatch), %g2 */
- 0x82106000, /* 64-bit 0x08 --> or %g1, %hm(_glapi_Dispatch), %g1 */
- 0x8730e00a, /* 64-bit 0x0c --> srl %g3, 10, %g3 */
- 0x83287020, /* 64-bit 0x10 --> sllx %g1, 32, %g1 */
- 0x82004002, /* 64-bit 0x14 --> add %g1, %g2, %g1 */
- 0xc2586000, /* 64-bit 0x18 --> ldx [%g1 + %lo(_glapi_Dispatch)], %g1 */
-#else
- 0x03000000, /* 32-bit 0x00 --> sethi %hi(_glapi_Dispatch), %g1 */
- 0x8730e00a, /* 32-bit 0x04 --> srl %g3, 10, %g3 */
- 0xc2006000, /* 32-bit 0x08 --> ld [%g1 + %lo(_glapi_Dispatch)], %g1 */
-#endif
- 0x80a06000, /* --> cmp %g1, 0 */
- 0x02800005, /* --> be +4*5 */
- 0x01000000, /* --> nop */
-#ifdef __arch64__
- 0xc2584003, /* 64-bit --> ldx [%g1 + %g3], %g1 */
-#else
- 0xc2004003, /* 32-bit --> ld [%g1 + %g3], %g1 */
-#endif
- 0x81c04000, /* --> jmp %g1 */
- 0x01000000, /* --> nop */
-#ifdef __arch64__
- 0x9de3bf80, /* 64-bit --> save %sp, -128, %sp */
-#else
- 0x9de3bfc0, /* 32-bit --> save %sp, -64, %sp */
-#endif
- 0xa0100003, /* --> mov %g3, %l0 */
- 0x40000000, /* --> call _glapi_get_dispatch */
- 0x01000000, /* --> nop */
- 0x82100008, /* --> mov %o0, %g1 */
- 0x86100010, /* --> mov %l0, %g3 */
- 0x10bffff7, /* --> ba -4*9 */
- 0x81e80000, /* --> restore */
-#endif
- };
-#ifdef GLX_USE_TLS
- extern unsigned long __glapi_sparc_get_dispatch(void);
- unsigned int *code = &__glapi_sparc_tls_stub;
- unsigned long dispatch = __glapi_sparc_get_dispatch();
-#else
- unsigned int *code = &__glapi_sparc_pthread_stub;
- unsigned long dispatch = (unsigned long) &_glapi_Dispatch;
- unsigned long call_dest = (unsigned long ) &_glapi_get_dispatch;
- int idx;
-#endif
-
-#if defined(GLX_USE_TLS)
- code[0] = template[0] | (dispatch >> 10);
- code[1] = template[1];
- __glapi_sparc_icache_flush(&code[0]);
- code[2] = template[2] | (dispatch & 0x3ff);
- code[3] = template[3];
- __glapi_sparc_icache_flush(&code[2]);
- code[4] = template[4];
- code[5] = template[5];
- __glapi_sparc_icache_flush(&code[4]);
- code[6] = template[6];
- __glapi_sparc_icache_flush(&code[6]);
-#else
-#if defined(__arch64__)
- code[0] = template[0] | (dispatch >> (32 + 10));
- code[1] = template[1] | ((dispatch & 0xffffffff) >> 10);
- __glapi_sparc_icache_flush(&code[0]);
- code[2] = template[2] | ((dispatch >> 32) & 0x3ff);
- code[3] = template[3];
- __glapi_sparc_icache_flush(&code[2]);
- code[4] = template[4];
- code[5] = template[5];
- __glapi_sparc_icache_flush(&code[4]);
- code[6] = template[6] | (dispatch & 0x3ff);
- idx = 7;
-#else
- code[0] = template[0] | (dispatch >> 10);
- code[1] = template[1];
- __glapi_sparc_icache_flush(&code[0]);
- code[2] = template[2] | (dispatch & 0x3ff);
- idx = 3;
-#endif
- code[idx + 0] = template[idx + 0];
- __glapi_sparc_icache_flush(&code[idx - 1]);
- code[idx + 1] = template[idx + 1];
- code[idx + 2] = template[idx + 2];
- __glapi_sparc_icache_flush(&code[idx + 1]);
- code[idx + 3] = template[idx + 3];
- code[idx + 4] = template[idx + 4];
- __glapi_sparc_icache_flush(&code[idx + 3]);
- code[idx + 5] = template[idx + 5];
- code[idx + 6] = template[idx + 6];
- __glapi_sparc_icache_flush(&code[idx + 5]);
- code[idx + 7] = template[idx + 7];
- code[idx + 8] = template[idx + 8] |
- (((call_dest - ((unsigned long) &code[idx + 8]))
- >> 2) & 0x3fffffff);
- __glapi_sparc_icache_flush(&code[idx + 7]);
- code[idx + 9] = template[idx + 9];
- code[idx + 10] = template[idx + 10];
- __glapi_sparc_icache_flush(&code[idx + 9]);
- code[idx + 11] = template[idx + 11];
- code[idx + 12] = template[idx + 12];
- __glapi_sparc_icache_flush(&code[idx + 11]);
- code[idx + 13] = template[idx + 13];
- __glapi_sparc_icache_flush(&code[idx + 13]);
-#endif
-#endif
-}
-#endif /* defined(PTHREADS) || defined(GLX_USE_TLS) */
/**
@@ -414,17 +250,15 @@ init_glapi_relocs( void )
PUBLIC void
_glapi_set_dispatch(struct _glapi_table *dispatch)
{
-#if defined(PTHREADS) || defined(GLX_USE_TLS)
- static pthread_once_t once_control = PTHREAD_ONCE_INIT;
- pthread_once( & once_control, init_glapi_relocs );
-#endif
+ init_glapi_relocs_once();
- if (!dispatch) {
+ if (dispatch == NULL) {
/* use the no-op functions */
dispatch = (struct _glapi_table *) __glapi_noop_table;
}
#ifdef DEBUG
else {
+ _glapi_check_table_not_null(dispatch);
_glapi_check_table(dispatch);
}
#endif
@@ -434,9 +268,9 @@ _glapi_set_dispatch(struct _glapi_table *dispatch)
#elif defined(THREADS)
_glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch);
_glapi_Dispatch = (ThreadSafe) ? NULL : dispatch;
-#else /*THREADS*/
+#else
_glapi_Dispatch = dispatch;
-#endif /*THREADS*/
+#endif
}
@@ -447,17 +281,15 @@ _glapi_set_dispatch(struct _glapi_table *dispatch)
PUBLIC struct _glapi_table *
_glapi_get_dispatch(void)
{
- struct _glapi_table * api;
#if defined(GLX_USE_TLS)
- api = _glapi_tls_Dispatch;
+ return _glapi_tls_Dispatch;
#elif defined(THREADS)
- api = (ThreadSafe)
+ return (ThreadSafe)
? (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD)
: _glapi_Dispatch;
#else
- api = _glapi_Dispatch;
+ return _glapi_Dispatch;
#endif
- return api;
}
@@ -488,75 +320,15 @@ _glapi_get_dispatch_table_size(void)
* Intended for debugging purposes.
*/
void
-_glapi_check_table(const struct _glapi_table *table)
+_glapi_check_table_not_null(const struct _glapi_table *table)
{
-#if 0 /* Enable this for extra DEBUG */
+#if 0 /* enable this for extra DEBUG */
const GLuint entries = _glapi_get_dispatch_table_size();
const void **tab = (const void **) table;
GLuint i;
for (i = 1; i < entries; i++) {
assert(tab[i]);
}
-
- /* Do some spot checks to be sure that the dispatch table
- * slots are assigned correctly.
- */
- {
- GLuint BeginOffset = _glapi_get_proc_offset("glBegin");
- char *BeginFunc = (char*) &table->Begin;
- GLuint offset = (BeginFunc - (char *) table) / sizeof(void *);
- assert(BeginOffset == _gloffset_Begin);
- assert(BeginOffset == offset);
- }
- {
- GLuint viewportOffset = _glapi_get_proc_offset("glViewport");
- char *viewportFunc = (char*) &table->Viewport;
- GLuint offset = (viewportFunc - (char *) table) / sizeof(void *);
- assert(viewportOffset == _gloffset_Viewport);
- assert(viewportOffset == offset);
- }
- {
- GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer");
- char *VertexPointerFunc = (char*) &table->VertexPointer;
- GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *);
- assert(VertexPointerOffset == _gloffset_VertexPointer);
- assert(VertexPointerOffset == offset);
- }
- {
- GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax");
- char *ResetMinMaxFunc = (char*) &table->ResetMinmax;
- GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *);
- assert(ResetMinMaxOffset == _gloffset_ResetMinmax);
- assert(ResetMinMaxOffset == offset);
- }
- {
- GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor");
- char *blendColorFunc = (char*) &table->BlendColor;
- GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *);
- assert(blendColorOffset == _gloffset_BlendColor);
- assert(blendColorOffset == offset);
- }
- {
- GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT");
- char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT;
- GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *);
- assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT);
- assert(secondaryColor3fOffset == offset);
- }
- {
- GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV");
- char *pointParameterivFunc = (char*) &table->PointParameterivNV;
- GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *);
- assert(pointParameterivOffset == _gloffset_PointParameterivNV);
- assert(pointParameterivOffset == offset);
- }
- {
- GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV");
- char *setFenceFunc = (char*) &table->SetFenceNV;
- GLuint offset = (setFenceFunc - (char *) table) / sizeof(void *);
- assert(setFenceOffset == _gloffset_SetFenceNV);
- assert(setFenceOffset == offset);
- }
#else
(void) table;
#endif
diff --git a/src/mesa/glapi/glapi.h b/src/mesa/glapi/glapi.h
index f802a61d3b..2eae6d5c43 100644
--- a/src/mesa/glapi/glapi.h
+++ b/src/mesa/glapi/glapi.h
@@ -44,8 +44,6 @@
#ifndef _GLAPI_H
#define _GLAPI_H
-#define GL_GLEXT_PROTOTYPES
-
#include "glthread.h"
@@ -59,40 +57,61 @@ typedef void (*_glapi_proc)(void); /* generic function pointer */
#define _glapi_get_dispatch _mglapi_get_dispatch
#define _glapi_set_context _mglapi_set_context
#define _glapi_get_context _mglapi_get_context
-#define _glapi_Context _mglapi_Context
#define _glapi_Dispatch _mglapi_Dispatch
+#define _glapi_Context _mglapi_Context
#endif
-/*
- * Number of extension functions which we can dynamically add at runtime.
- */
-#define MAX_EXTENSION_FUNCS 300
+#if defined(__GNUC__) && (__GNUC__ >= 3)
+# define likely(x) __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#else
+# define likely(x) (x)
+# define unlikely(x) (x)
+#endif
/**
- ** Define the GET_CURRENT_CONTEXT() macro.
+ ** Define the GET_DISPATCH() and GET_CURRENT_CONTEXT() macros.
+ **
** \param C local variable which will hold the current context.
**/
#if defined (GLX_USE_TLS)
-extern const void *_glapi_Context;
extern const struct _glapi_table *_glapi_Dispatch;
+extern const void *_glapi_Context;
+
+extern __thread struct _glapi_table * _glapi_tls_Dispatch
+ __attribute__((tls_model("initial-exec")));
+
extern __thread void * _glapi_tls_Context
__attribute__((tls_model("initial-exec")));
+# define GET_DISPATCH() _glapi_tls_Dispatch
+
# define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) _glapi_tls_Context
#else
-extern void *_glapi_Context;
extern struct _glapi_table *_glapi_Dispatch;
+extern void *_glapi_Context;
+
# ifdef THREADS
-# define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context())
+
+# define GET_DISPATCH() \
+ (likely(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch())
+
+# define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) \
+ (likely(_glapi_Context) ? _glapi_Context : _glapi_get_context())
+
# else
+
+# define GET_DISPATCH() _glapi_Dispatch
+
# define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) _glapi_Context
+
# endif
#endif /* defined (GLX_USE_TLS) */
@@ -103,6 +122,14 @@ extern struct _glapi_table *_glapi_Dispatch;
**/
extern void
+_glapi_init_multithread(void);
+
+
+extern void
+_glapi_destroy_multithread(void);
+
+
+extern void
_glapi_check_multithread(void);
@@ -122,26 +149,10 @@ extern struct _glapi_table *
_glapi_get_dispatch(void);
-extern int
-_glapi_begin_dispatch_override(struct _glapi_table *override);
-
-
-extern void
-_glapi_end_dispatch_override(int layer);
-
-
-struct _glapi_table *
-_glapi_get_override_dispatch(int layer);
-
-
extern unsigned int
_glapi_get_dispatch_table_size(void);
-extern void
-_glapi_check_table(const struct _glapi_table *table);
-
-
extern int
_glapi_add_dispatch( const char * const * function_names,
const char * parameter_signature );
@@ -154,8 +165,29 @@ extern _glapi_proc
_glapi_get_proc_address(const char *funcName);
+/**
+ * GL API local functions and defines
+ */
+
+extern void
+init_glapi_relocs_once(void);
+
+extern void
+_glapi_check_table_not_null(const struct _glapi_table *table);
+
+
+extern void
+_glapi_check_table(const struct _glapi_table *table);
+
+
extern const char *
_glapi_get_proc_name(unsigned int offset);
+/*
+ * Number of extension functions which we can dynamically add at runtime.
+ */
+#define MAX_EXTENSION_FUNCS 300
+
+
#endif
diff --git a/src/mesa/glapi/glapi_getproc.c b/src/mesa/glapi/glapi_getproc.c
index 69eb42c79e..a6dbf173e8 100644
--- a/src/mesa/glapi/glapi_getproc.c
+++ b/src/mesa/glapi/glapi_getproc.c
@@ -43,27 +43,6 @@
#include "glapi/glapitable.h"
-static void
-fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset);
-
-
-/**
- * strdup() is actually not a standard ANSI C or POSIX routine.
- * Irix will not define it if ANSI mode is in effect.
- */
-static char *
-str_dup(const char *str)
-{
- char *copy;
- copy = (char*) malloc(strlen(str) + 1);
- if (!copy)
- return NULL;
- strcpy(copy, str);
- return copy;
-}
-
-
-
#if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS)
# define DISPATCH_FUNCTION_SIZE 16
#elif defined(USE_X86_ASM)
@@ -121,7 +100,6 @@ get_static_proc_offset(const char *funcName)
}
-#if !defined(XFree86Server) && !defined(XGLServer)
#ifdef USE_X86_ASM
#if defined( GLX_USE_TLS )
@@ -134,6 +112,8 @@ extern const GLubyte gl_dispatch_functions_start[];
#endif /* USE_X86_ASM */
+#if !defined(XFree86Server) && !defined(XGLServer)
+
/**
* Return dispatch function address for the named static (built-in) function.
* Return NULL if function not found.
@@ -182,6 +162,172 @@ get_static_proc_name( GLuint offset )
+#if defined(PTHREADS) || defined(GLX_USE_TLS)
+
+/**
+ * Perform platform-specific GL API entry-point fixups.
+ */
+static void
+init_glapi_relocs( void )
+{
+#if defined(USE_X86_ASM) && defined(GLX_USE_TLS) && !defined(GLX_X86_READONLY_TEXT)
+ extern unsigned long _x86_get_dispatch(void);
+ char run_time_patch[] = {
+ 0x65, 0xa1, 0, 0, 0, 0 /* movl %gs:0,%eax */
+ };
+ GLuint *offset = (GLuint *) &run_time_patch[2]; /* 32-bits for x86/32 */
+ const GLubyte * const get_disp = (const GLubyte *) run_time_patch;
+ GLubyte * curr_func = (GLubyte *) gl_dispatch_functions_start;
+
+ *offset = _x86_get_dispatch();
+ while ( curr_func != (GLubyte *) gl_dispatch_functions_end ) {
+ (void) memcpy( curr_func, get_disp, sizeof(run_time_patch));
+ curr_func += DISPATCH_FUNCTION_SIZE;
+ }
+#endif
+#ifdef USE_SPARC_ASM
+ extern void __glapi_sparc_icache_flush(unsigned int *);
+ static const unsigned int template[] = {
+#ifdef GLX_USE_TLS
+ 0x05000000, /* sethi %hi(_glapi_tls_Dispatch), %g2 */
+ 0x8730e00a, /* srl %g3, 10, %g3 */
+ 0x8410a000, /* or %g2, %lo(_glapi_tls_Dispatch), %g2 */
+#ifdef __arch64__
+ 0xc259c002, /* ldx [%g7 + %g2], %g1 */
+ 0xc2584003, /* ldx [%g1 + %g3], %g1 */
+#else
+ 0xc201c002, /* ld [%g7 + %g2], %g1 */
+ 0xc2004003, /* ld [%g1 + %g3], %g1 */
+#endif
+ 0x81c04000, /* jmp %g1 */
+ 0x01000000, /* nop */
+#else
+#ifdef __arch64__
+ 0x03000000, /* 64-bit 0x00 --> sethi %hh(_glapi_Dispatch), %g1 */
+ 0x05000000, /* 64-bit 0x04 --> sethi %lm(_glapi_Dispatch), %g2 */
+ 0x82106000, /* 64-bit 0x08 --> or %g1, %hm(_glapi_Dispatch), %g1 */
+ 0x8730e00a, /* 64-bit 0x0c --> srl %g3, 10, %g3 */
+ 0x83287020, /* 64-bit 0x10 --> sllx %g1, 32, %g1 */
+ 0x82004002, /* 64-bit 0x14 --> add %g1, %g2, %g1 */
+ 0xc2586000, /* 64-bit 0x18 --> ldx [%g1 + %lo(_glapi_Dispatch)], %g1 */
+#else
+ 0x03000000, /* 32-bit 0x00 --> sethi %hi(_glapi_Dispatch), %g1 */
+ 0x8730e00a, /* 32-bit 0x04 --> srl %g3, 10, %g3 */
+ 0xc2006000, /* 32-bit 0x08 --> ld [%g1 + %lo(_glapi_Dispatch)], %g1 */
+#endif
+ 0x80a06000, /* --> cmp %g1, 0 */
+ 0x02800005, /* --> be +4*5 */
+ 0x01000000, /* --> nop */
+#ifdef __arch64__
+ 0xc2584003, /* 64-bit --> ldx [%g1 + %g3], %g1 */
+#else
+ 0xc2004003, /* 32-bit --> ld [%g1 + %g3], %g1 */
+#endif
+ 0x81c04000, /* --> jmp %g1 */
+ 0x01000000, /* --> nop */
+#ifdef __arch64__
+ 0x9de3bf80, /* 64-bit --> save %sp, -128, %sp */
+#else
+ 0x9de3bfc0, /* 32-bit --> save %sp, -64, %sp */
+#endif
+ 0xa0100003, /* --> mov %g3, %l0 */
+ 0x40000000, /* --> call _glapi_get_dispatch */
+ 0x01000000, /* --> nop */
+ 0x82100008, /* --> mov %o0, %g1 */
+ 0x86100010, /* --> mov %l0, %g3 */
+ 0x10bffff7, /* --> ba -4*9 */
+ 0x81e80000, /* --> restore */
+#endif
+ };
+#ifdef GLX_USE_TLS
+ extern unsigned int __glapi_sparc_tls_stub;
+ extern unsigned long __glapi_sparc_get_dispatch(void);
+ unsigned int *code = &__glapi_sparc_tls_stub;
+ unsigned long dispatch = __glapi_sparc_get_dispatch();
+#else
+ extern unsigned int __glapi_sparc_pthread_stub;
+ unsigned int *code = &__glapi_sparc_pthread_stub;
+ unsigned long dispatch = (unsigned long) &_glapi_Dispatch;
+ unsigned long call_dest = (unsigned long ) &_glapi_get_dispatch;
+ int idx;
+#endif
+
+#if defined(GLX_USE_TLS)
+ code[0] = template[0] | (dispatch >> 10);
+ code[1] = template[1];
+ __glapi_sparc_icache_flush(&code[0]);
+ code[2] = template[2] | (dispatch & 0x3ff);
+ code[3] = template[3];
+ __glapi_sparc_icache_flush(&code[2]);
+ code[4] = template[4];
+ code[5] = template[5];
+ __glapi_sparc_icache_flush(&code[4]);
+ code[6] = template[6];
+ __glapi_sparc_icache_flush(&code[6]);
+#else
+#if defined(__arch64__)
+ code[0] = template[0] | (dispatch >> (32 + 10));
+ code[1] = template[1] | ((dispatch & 0xffffffff) >> 10);
+ __glapi_sparc_icache_flush(&code[0]);
+ code[2] = template[2] | ((dispatch >> 32) & 0x3ff);
+ code[3] = template[3];
+ __glapi_sparc_icache_flush(&code[2]);
+ code[4] = template[4];
+ code[5] = template[5];
+ __glapi_sparc_icache_flush(&code[4]);
+ code[6] = template[6] | (dispatch & 0x3ff);
+ idx = 7;
+#else
+ code[0] = template[0] | (dispatch >> 10);
+ code[1] = template[1];
+ __glapi_sparc_icache_flush(&code[0]);
+ code[2] = template[2] | (dispatch & 0x3ff);
+ idx = 3;
+#endif
+ code[idx + 0] = template[idx + 0];
+ __glapi_sparc_icache_flush(&code[idx - 1]);
+ code[idx + 1] = template[idx + 1];
+ code[idx + 2] = template[idx + 2];
+ __glapi_sparc_icache_flush(&code[idx + 1]);
+ code[idx + 3] = template[idx + 3];
+ code[idx + 4] = template[idx + 4];
+ __glapi_sparc_icache_flush(&code[idx + 3]);
+ code[idx + 5] = template[idx + 5];
+ code[idx + 6] = template[idx + 6];
+ __glapi_sparc_icache_flush(&code[idx + 5]);
+ code[idx + 7] = template[idx + 7];
+ code[idx + 8] = template[idx + 8] |
+ (((call_dest - ((unsigned long) &code[idx + 8]))
+ >> 2) & 0x3fffffff);
+ __glapi_sparc_icache_flush(&code[idx + 7]);
+ code[idx + 9] = template[idx + 9];
+ code[idx + 10] = template[idx + 10];
+ __glapi_sparc_icache_flush(&code[idx + 9]);
+ code[idx + 11] = template[idx + 11];
+ code[idx + 12] = template[idx + 12];
+ __glapi_sparc_icache_flush(&code[idx + 11]);
+ code[idx + 13] = template[idx + 13];
+ __glapi_sparc_icache_flush(&code[idx + 13]);
+#endif
+#endif
+}
+
+void
+init_glapi_relocs_once( void )
+{
+ static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+ pthread_once( & once_control, init_glapi_relocs );
+}
+
+#else
+
+void
+init_glapi_relocs_once( void ) { }
+
+#endif /* defined(PTHREADS) || defined(GLX_USE_TLS) */
+
+
+
/**********************************************************************
* Extension function management.
*/
@@ -239,6 +385,9 @@ static GLuint NumExtEntryPoints = 0;
extern void __glapi_sparc_icache_flush(unsigned int *);
#endif
+static void
+fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset);
+
/**
* Generate a dispatch function (entrypoint) which jumps through
* the given slot number (offset) in the current dispatch table.
@@ -263,7 +412,9 @@ generate_entrypoint(GLuint functionOffset)
}
return (_glapi_proc) code;
-#elif defined(USE_SPARC_ASM) && (defined(PTHREADS) || defined(GLX_USE_TLS))
+#elif defined(USE_SPARC_ASM)
+
+#if defined(PTHREADS) || defined(GLX_USE_TLS)
static const unsigned int template[] = {
0x07000000, /* sethi %hi(0), %g3 */
0x8210000f, /* mov %o7, %g1 */
@@ -289,6 +440,8 @@ generate_entrypoint(GLuint functionOffset)
__glapi_sparc_icache_flush(&code[2]);
}
return (_glapi_proc) code;
+#endif
+
#else
(void) functionOffset;
return NULL;
@@ -333,6 +486,22 @@ fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset)
/**
+ * strdup() is actually not a standard ANSI C or POSIX routine.
+ * Irix will not define it if ANSI mode is in effect.
+ */
+static char *
+str_dup(const char *str)
+{
+ char *copy;
+ copy = (char*) malloc(strlen(str) + 1);
+ if (!copy)
+ return NULL;
+ strcpy(copy, str);
+ return copy;
+}
+
+
+/**
* Generate new entrypoint
*
* Use a temporary dispatch offset of ~0 (i.e. -1). Later, when the driver
@@ -594,3 +763,74 @@ _glapi_get_proc_name(GLuint offset)
}
return NULL;
}
+
+
+
+/**
+ * Do some spot checks to be sure that the dispatch table
+ * slots are assigned correctly. For debugging only.
+ */
+void
+_glapi_check_table(const struct _glapi_table *table)
+{
+#if 0 /* enable this for extra DEBUG */
+ {
+ GLuint BeginOffset = _glapi_get_proc_offset("glBegin");
+ char *BeginFunc = (char*) &table->Begin;
+ GLuint offset = (BeginFunc - (char *) table) / sizeof(void *);
+ assert(BeginOffset == _gloffset_Begin);
+ assert(BeginOffset == offset);
+ }
+ {
+ GLuint viewportOffset = _glapi_get_proc_offset("glViewport");
+ char *viewportFunc = (char*) &table->Viewport;
+ GLuint offset = (viewportFunc - (char *) table) / sizeof(void *);
+ assert(viewportOffset == _gloffset_Viewport);
+ assert(viewportOffset == offset);
+ }
+ {
+ GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer");
+ char *VertexPointerFunc = (char*) &table->VertexPointer;
+ GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *);
+ assert(VertexPointerOffset == _gloffset_VertexPointer);
+ assert(VertexPointerOffset == offset);
+ }
+ {
+ GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax");
+ char *ResetMinMaxFunc = (char*) &table->ResetMinmax;
+ GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *);
+ assert(ResetMinMaxOffset == _gloffset_ResetMinmax);
+ assert(ResetMinMaxOffset == offset);
+ }
+ {
+ GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor");
+ char *blendColorFunc = (char*) &table->BlendColor;
+ GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *);
+ assert(blendColorOffset == _gloffset_BlendColor);
+ assert(blendColorOffset == offset);
+ }
+ {
+ GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT");
+ char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT;
+ GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *);
+ assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT);
+ assert(secondaryColor3fOffset == offset);
+ }
+ {
+ GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV");
+ char *pointParameterivFunc = (char*) &table->PointParameterivNV;
+ GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *);
+ assert(pointParameterivOffset == _gloffset_PointParameterivNV);
+ assert(pointParameterivOffset == offset);
+ }
+ {
+ GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV");
+ char *setFenceFunc = (char*) &table->SetFenceNV;
+ GLuint offset = (setFenceFunc - (char *) table) / sizeof(void *);
+ assert(setFenceOffset == _gloffset_SetFenceNV);
+ assert(setFenceOffset == offset);
+ }
+#else
+ (void) table;
+#endif
+}
diff --git a/src/mesa/glapi/glthread.c b/src/mesa/glapi/glthread.c
index be4e2f754d..17b6bb2b6a 100644
--- a/src/mesa/glapi/glthread.c
+++ b/src/mesa/glapi/glthread.c
@@ -116,91 +116,15 @@ _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
/*
- * 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... */
-
-PUBLIC 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)
+static void InsteadOf_exit(int nCode)
{
- DWORD dwErr=GetLastError();
+ DWORD dwErr = GetLastError();
}
PUBLIC unsigned long
@@ -222,6 +146,17 @@ _glthread_InitTSD(_glthread_TSD *tsd)
}
+void
+_glthread_DestroyTSD(_glthread_TSD *tsd)
+{
+ if (tsd->initMagic != INIT_MAGIC) {
+ return;
+ }
+ TlsFree(tsd->key);
+ tsd->initMagic = 0x0;
+}
+
+
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
diff --git a/src/mesa/glapi/glthread.h b/src/mesa/glapi/glthread.h
index 8ec933a851..e5193aaf98 100644
--- a/src/mesa/glapi/glthread.h
+++ b/src/mesa/glapi/glthread.h
@@ -64,21 +64,12 @@
#define GLTHREAD_H
-#if defined(USE_MGL_NAMESPACE)
-#define _glapi_Dispatch _mglapi_Dispatch
+#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)
+#ifndef THREADS
+#define THREADS
#endif
-
-
-
-#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\
- defined(WIN32_THREADS) || defined(BEOS_THREADS)) \
- && !defined(THREADS)
-# define THREADS
#endif
-#ifdef VMS
-#include <GL/vms_x_fix.h>
-#endif
/*
* POSIX threads. This should be your choice in the Unix world
@@ -121,7 +112,7 @@ typedef pthread_cond_t _glthread_Cond;
#define _glthread_DECLARE_STATIC_COND(name) \
static _glthread_Cond name = PTHREAD_COND_INITIALIZER
-#define _glthread_INIT_COND(cond) \
+#define _glthread_INIT_COND(cond) \
pthread_cond_init(&(cond), NULL)
#define _glthread_DESTROY_COND(name) \
@@ -143,7 +134,7 @@ typedef unsigned int _glthread_Cond;
#define _glthread_DECLARE_STATIC_COND(name) \
// #warning Condition variables not implemented.
-#define _glthread_INIT_COND(cond) \
+#define _glthread_INIT_COND(cond) \
ASSERT(0);
#define _glthread_DESTROY_COND(name) \
@@ -158,38 +149,7 @@ typedef unsigned int _glthread_Cond;
#define _glthread_COND_BROADCAST(cond) \
ASSERT(0);
-#endif
-
-
-/*
- * Solaris threads. Use only up to Solaris 2.4.
- * Solaris 2.5 and higher provide POSIX threads.
- * Be sure to compile with -mt on the Solaris compilers, or
- * use -D_REENTRANT if using gcc.
- */
-#ifdef SOLARIS_THREADS
-#include <thread.h>
-
-typedef struct {
- thread_key_t key;
- mutex_t keylock;
- int initMagic;
-} _glthread_TSD;
-
-typedef thread_t _glthread_Thread;
-
-typedef mutex_t _glthread_Mutex;
-
-/* XXX need to really implement mutex-related macros */
-#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0
-#define _glthread_INIT_MUTEX(name) (void) name
-#define _glthread_DESTROY_MUTEX(name) (void) name
-#define _glthread_LOCK_MUTEX(name) (void) name
-#define _glthread_UNLOCK_MUTEX(name) (void) name
-
-#endif /* SOLARIS_THREADS */
-
-
+#endif /* PTHREADS */
/*
@@ -209,11 +169,20 @@ typedef HANDLE _glthread_Thread;
typedef CRITICAL_SECTION _glthread_Mutex;
-#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0}
-#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name)
-#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name)
-#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name)
-#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name)
+#define _glthread_DECLARE_STATIC_MUTEX(name) \
+ /* static */ _glthread_Mutex name = { 0, 0, 0, 0, 0, 0 }
+
+#define _glthread_INIT_MUTEX(name) \
+ InitializeCriticalSection(&name)
+
+#define _glthread_DESTROY_MUTEX(name) \
+ DeleteCriticalSection(&name)
+
+#define _glthread_LOCK_MUTEX(name) \
+ EnterCriticalSection(&name)
+
+#define _glthread_UNLOCK_MUTEX(name) \
+ LeaveCriticalSection(&name)
#endif /* WIN32_THREADS */
@@ -252,12 +221,26 @@ typedef struct {
} benaphore;
typedef benaphore _glthread_Mutex;
-#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 }
-#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0
-#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0
-#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \
- if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem)
-#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem)
+#define _glthread_DECLARE_STATIC_MUTEX(name) \
+ static _glthread_Mutex name = { 0, 0 }
+
+#define _glthread_INIT_MUTEX(name) \
+ name.sem = create_sem(0, #name"_benaphore"), \
+ name.lock = 0
+
+#define _glthread_DESTROY_MUTEX(name) \
+ delete_sem(name.sem), \
+ name.lock = 0
+
+#define _glthread_LOCK_MUTEX(name) \
+ if (name.sem == 0) \
+ _glthread_INIT_MUTEX(name); \
+ if (atomic_add(&(name.lock), 1) >= 1) \
+ acquire_sem(name.sem)
+
+#define _glthread_UNLOCK_MUTEX(name) \
+ if (atomic_add(&(name.lock), -1) > 1) \
+ release_sem(name.sem)
#endif /* BEOS_THREADS */
@@ -301,6 +284,10 @@ extern void
_glthread_InitTSD(_glthread_TSD *);
+extern void
+_glthread_DestroyTSD(_glthread_TSD *); /* WIN32 only */
+
+
extern void *
_glthread_GetTSD(_glthread_TSD *);
@@ -308,26 +295,5 @@ _glthread_GetTSD(_glthread_TSD *);
extern void
_glthread_SetTSD(_glthread_TSD *, void *);
-#if !defined __GNUC__ || __GNUC__ < 3
-# define __builtin_expect(x, y) x
-#endif
-
-#if defined(GLX_USE_TLS)
-
-extern __thread struct _glapi_table * _glapi_tls_Dispatch
- __attribute__((tls_model("initial-exec")));
-
-#define GET_DISPATCH() _glapi_tls_Dispatch
-
-#elif !defined(GL_CALL)
-# if defined(THREADS)
-# define GET_DISPATCH() \
- ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \
- ? _glapi_Dispatch : _glapi_get_dispatch())
-# else
-# define GET_DISPATCH() _glapi_Dispatch
-# endif /* defined(THREADS) */
-#endif /* ndef GL_CALL */
-
#endif /* THREADS_H */