From a73c6540d9a7f6e26d8568ba2fc522cb865f0a6c Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 23 Apr 2010 16:06:26 +0800 Subject: mapi: Add mapi and share the code with glapi. Specifically, move all or most of glapi/glapi.c to mapi/u_current.c, glapi/glapi_execmem.c to mapi/u_execmem.c, glapi/glthread.[ch] to mapi/u_thread.[ch] and remove their dependencies on core Mesa headers. --- src/gles/Makefile | 14 +- src/mapi/es1api/Makefile | 54 ++++--- src/mapi/glapi/Makefile | 31 ++-- src/mapi/glapi/SConscript | 12 +- src/mapi/glapi/glapi.c | 293 -------------------------------------- src/mapi/glapi/glapi.h | 112 ++------------- src/mapi/glapi/glapi_entrypoint.c | 5 +- src/mapi/glapi/glapi_execmem.c | 128 ----------------- src/mapi/glapi/glapi_getproc.c | 8 +- src/mapi/glapi/glapi_priv.h | 6 - src/mapi/glapi/glthread.c | 262 +--------------------------------- src/mapi/glapi/glthread.h | 258 ++------------------------------- src/mapi/glapi/sources.mak | 2 - src/mapi/mapi/sources.mak | 6 + src/mapi/mapi/u_compiler.h | 48 +++++++ src/mapi/mapi/u_current.c | 274 +++++++++++++++++++++++++++++++++++ src/mapi/mapi/u_current.h | 93 ++++++++++++ src/mapi/mapi/u_execmem.c | 122 ++++++++++++++++ src/mapi/mapi/u_execmem.h | 7 + src/mapi/mapi/u_thread.c | 254 +++++++++++++++++++++++++++++++++ src/mapi/mapi/u_thread.h | 200 ++++++++++++++++++++++++++ 21 files changed, 1120 insertions(+), 1069 deletions(-) delete mode 100644 src/mapi/glapi/glapi.c delete mode 100644 src/mapi/glapi/glapi_execmem.c create mode 100644 src/mapi/mapi/sources.mak create mode 100644 src/mapi/mapi/u_compiler.h create mode 100644 src/mapi/mapi/u_current.c create mode 100644 src/mapi/mapi/u_current.h create mode 100644 src/mapi/mapi/u_execmem.c create mode 100644 src/mapi/mapi/u_execmem.h create mode 100644 src/mapi/mapi/u_thread.c create mode 100644 src/mapi/mapi/u_thread.h diff --git a/src/gles/Makefile b/src/gles/Makefile index 5e5fc127b3..1af3f52f94 100644 --- a/src/gles/Makefile +++ b/src/gles/Makefile @@ -7,6 +7,9 @@ GLESv1_CM_ASM := $(addprefix $(MAPI)/es1api/glapi/,$(GLAPI_ASM_SOURCES)) GLESv2_ASM := $(addprefix $(MAPI)/es2api/glapi/,$(GLAPI_ASM_SOURCES)) API_SOURCES := $(addprefix $(MAPI)/glapi/,$(GLAPI_SOURCES)) +include $(MAPI)/mapi/sources.mak +MAPI_GLAPI_SOURCES := $(addprefix $(MAPI)/mapi/,$(MAPI_GLAPI_SOURCES)) + $(TOP)/$(LIB_DIR)/$(GLESv1_CM_LIB_NAME) : PREFIX = es1 $(TOP)/$(LIB_DIR)/$(GLESv1_CM_LIB_NAME) : NAME = GLESv1_CM @@ -17,7 +20,8 @@ INCLUDES = -I$(TOP)/include -I$(MAPI)/$(PREFIX)api -I$(MAPI) -I$(TOP)/src/mesa OBJECTS = \ $(notdir $(GLAPI_ASM_SOURCES:%.S=%.o)) \ - $(notdir $(GLAPI_SOURCES:%.c=%.o)) + $(notdir $(GLAPI_SOURCES:%.c=%.o)) \ + $(notdir $(MAPI_GLAPI_SOURCES:%.c=%.o)) GLESv1_CM_OBJECTS = $(addprefix es1-,$(OBJECTS)) GLESv2_OBJECTS = $(addprefix es2-,$(OBJECTS)) @@ -26,11 +30,15 @@ es1-%.o: $(dir $(GLESv1_CM_ASM))%.S $(CC) -c $(CFLAGS) $(INCLUDES) -o $@ $< es1-%.o: $(MAPI)/glapi/%.c $(CC) -c $(CFLAGS) $(INCLUDES) -o $@ $< +es1-u_%.o: $(MAPI)/mapi/u_%.c + $(CC) -c $(CFLAGS) $(INCLUDES) -DMAPI_GLAPI_CURRENT -o $@ $< es2-%.o: $(dir $(GLESv2_ASM))%.S $(CC) -c $(CFLAGS) $(INCLUDES) -o $@ $< es2-%.o: $(MAPI)/glapi/%.c $(CC) -c $(CFLAGS) $(INCLUDES) -o $@ $< +es2-u_%.o: $(MAPI)/mapi/u_%.c + $(CC) -c $(CFLAGS) $(INCLUDES) -DMAPI_GLAPI_CURRENT -o $@ $< default: depend \ $(TOP)/$(LIB_DIR)/$(GLESv1_CM_LIB_NAME) \ @@ -50,8 +58,8 @@ $(TOP)/$(LIB_DIR)/$(GLESv2_LIB_NAME) : Makefile depend: Makefile rm -f depend touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(API_SOURCES) \ - $(ES1_API_ASM) $(ES2_API_ASM) + $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) -DMAPI_GLAPI_CURRENT \ + $(API_SOURCES) $(ES1_API_ASM) $(ES2_API_ASM) # Emacs tags tags: diff --git a/src/mapi/es1api/Makefile b/src/mapi/es1api/Makefile index 9130d0b01c..203cc36dea 100644 --- a/src/mapi/es1api/Makefile +++ b/src/mapi/es1api/Makefile @@ -8,53 +8,69 @@ ifeq ($(ES),) ES := es1 endif -ESAPI = $(ES)api +TARGET = $(ES)api + +GLAPI := $(TOP)/src/mapi/glapi +MAPI := $(TOP)/src/mapi/mapi +# directory for generated sources/headers +GEN := glapi -GLAPI := ../glapi include $(GLAPI)/sources.mak -ESAPI_SOURCES := $(addprefix $(GLAPI)/, $(GLAPI_SOURCES)) -ESAPI_OBJECTS := $(GLAPI_SOURCES:.c=.o) -ESAPI_ASM_SOURCES := $(addprefix glapi/, $(GLAPI_ASM_SOURCES)) -ESAPI_ASM_OBJECTS := $(GLAPI_ASM_SOURCES:.S=.o) +GLAPI_OBJECTS := $(GLAPI_SOURCES:.c=.o) +GLAPI_SOURCES := $(addprefix $(GLAPI)/, $(GLAPI_SOURCES)) +GLAPI_ASM_OBJECTS := $(GLAPI_ASM_SOURCES:.S=.o) +GLAPI_ASM_SOURCES := $(addprefix $(GEN)/, $(GLAPI_ASM_SOURCES)) + +include $(MAPI)/sources.mak +MAPI_GLAPI_OBJECTS := $(MAPI_GLAPI_SOURCES:.c=.o) +MAPI_GLAPI_SOURCES := $(addprefix $(MAPI)/, $(MAPI_GLAPI_SOURCES)) + +TARGET_OBJECTS = $(GLAPI_OBJECTS) $(GLAPI_ASM_OBJECTS) $(MAPI_GLAPI_OBJECTS) INCLUDE_DIRS = \ -I$(TOP)/include \ - -I$(TOP)/src/mapi/$(ESAPI) \ + -I$(TOP)/src/mapi/$(TARGET) \ -I$(TOP)/src/mapi \ -I$(TOP)/src/mesa .PHONY: default -default: depend lib$(ESAPI).a +default: depend lib$(TARGET).a -lib$(ESAPI).a: $(ESAPI_OBJECTS) $(ESAPI_ASM_OBJECTS) - @$(MKLIB) -o $(ESAPI) -static $(ESAPI_OBJECTS) $(ESAPI_ASM_OBJECTS) +lib$(TARGET).a: $(TARGET_OBJECTS) + @$(MKLIB) -o $(TARGET) -static $(TARGET_OBJECTS) -$(ESAPI_OBJECTS): %.o: $(GLAPI)/%.c +$(GLAPI_OBJECTS): %.o: $(GLAPI)/%.c $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ -$(ESAPI_ASM_OBJECTS): %.o: glapi/%.S +$(GLAPI_ASM_OBJECTS): %.o: $(GEN)/%.S $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ -$(ESAPI_SOURCES) $(ESAPI_ASM_SOURCES): | glapi-stamp +$(MAPI_GLAPI_OBJECTS): %.o: $(MAPI)/%.c + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) -DMAPI_GLAPI_CURRENT $< -o $@ + +$(GLAPI_SOURCES) $(GLAPI_ASM_SOURCES): | glapi-stamp glapi-stamp: + @# generate sources/headers @$(MAKE) -C $(GLAPI)/gen-es $(ES) @touch $@ .PHONY: clean clean: - -rm -f $(ESAPI_OBJECTS) $(ESAPI_ASM_OBJECTS) - -rm -f lib$(ESAPI).a + -rm -f lib$(TARGET).a + -rm -f $(TARGET_OBJECTS) -rm -f depend depend.bak - @$(MAKE) -C $(GLAPI)/gen-es clean-$(ES) -rm -f glapi-stamp + @# clean generated sources/headers + @$(MAKE) -C $(GLAPI)/gen-es clean-$(ES) # nothing to install install: -depend: $(ESAPI_SOURCES) +depend: $(GLAPI_SOURCES) $(MAPI_GLAPI_SOURCES) @echo "running $(MKDEP)" @touch depend @$(MKDEP) $(MKDEP_OPTIONS) -f- $(DEFINES) $(INCLUDE_DIRS) \ - $(ESAPI_SOURCES) 2>/dev/null | \ - sed -e 's,^$(GLAPI)/,,' > depend + -DMAPI_GLAPI_CURRENT $(GLAPI_SOURCES) $(MAPI_GLAPI_SOURCES) \ + 2>/dev/null | sed -e 's,^$(GLAPI)/,,' -e 's,^$(MAPI)/,,' \ + > depend diff --git a/src/mapi/glapi/Makefile b/src/mapi/glapi/Makefile index 13c8c54de2..ca9381d425 100644 --- a/src/mapi/glapi/Makefile +++ b/src/mapi/glapi/Makefile @@ -3,19 +3,29 @@ TOP = ../../.. include $(TOP)/configs/current +TARGET = glapi + +MAPI = $(TOP)/src/mapi/mapi + include sources.mak GLAPI_OBJECTS = $(GLAPI_SOURCES:.c=.o) GLAPI_ASM_OBJECTS = $(GLAPI_ASM_SOURCES:.S=.o) +include $(MAPI)/sources.mak +MAPI_GLAPI_OBJECTS := $(MAPI_GLAPI_SOURCES:.c=.o) +MAPI_GLAPI_SOURCES := $(addprefix $(MAPI)/, $(MAPI_GLAPI_SOURCES)) + +TARGET_OBJECTS = $(GLAPI_OBJECTS) $(GLAPI_ASM_OBJECTS) $(MAPI_GLAPI_OBJECTS) + INCLUDE_DIRS = \ -I$(TOP)/include \ -I$(TOP)/src/mapi \ -I$(TOP)/src/mesa -default: depend libglapi.a +default: depend lib$(TARGET).a -libglapi.a: $(GLAPI_OBJECTS) $(GLAPI_ASM_OBJECTS) - @ $(MKLIB) -o glapi -static $(GLAPI_OBJECTS) $(GLAPI_ASM_OBJECTS) +lib$(TARGET).a: $(TARGET_OBJECTS) + @$(MKLIB) -o $(TARGET) -static $(TARGET_OBJECTS) $(GLAPI_OBJECTS): %.o: %.c $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ @@ -23,16 +33,21 @@ $(GLAPI_OBJECTS): %.o: %.c $(GLAPI_ASM_OBJECTS): %.o: %.S $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ +$(MAPI_GLAPI_OBJECTS): %.o: $(MAPI)/%.c + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) -DMAPI_GLAPI_CURRENT $< -o $@ + install: clean: - -rm -f $(GLAPI_OBJECTS) $(GLAPI_ASM_OBJECTS) - -rm -f depend depend.bak libglapi.a + -rm -f $(TARGET_OBJECTS) + -rm -f lib$(TARGET).a + -rm -f depend depend.bak -depend: $(GLAPI_SOURCES) +depend: $(GLAPI_SOURCES) $(MAPI_GLAPI_SOURCES) @ echo "running $(MKDEP)" @ touch depend - @$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(GLAPI_SOURCES) \ - > /dev/null 2>/dev/null + @$(MKDEP) $(MKDEP_OPTIONS) -f- $(DEFINES) $(INCLUDE_DIRS) \ + -DMAPI_GLAPI_CURRENT $(GLAPI_SOURCES) $(MAPI_GLAPI_SOURCES) \ + 2>/dev/null | sed -e 's,^$(MAPI)/,,' > depend -include depend diff --git a/src/mapi/glapi/SConscript b/src/mapi/glapi/SConscript index 1ace2e6b2c..15c08255c3 100644 --- a/src/mapi/glapi/SConscript +++ b/src/mapi/glapi/SConscript @@ -8,21 +8,29 @@ if env['platform'] != 'winddk': env = env.Clone() + env.Append(CPPDEFINES = [ + 'MAPI_GLAPI_CURRENT', + ]) + env.Append(CPPPATH = [ '#/src/mapi', '#/src/mesa', ]) glapi_sources = [ - 'glapi.c', 'glapi_dispatch.c', 'glapi_entrypoint.c', - 'glapi_execmem.c', 'glapi_getproc.c', 'glapi_nop.c', 'glthread.c', ] + glapi_sources += [ + '../mapi/u_current.c', + '../mapi/u_execmem.c', + '../mapi/u_thread.c', + ] + # # Assembly sources # diff --git a/src/mapi/glapi/glapi.c b/src/mapi/glapi/glapi.c deleted file mode 100644 index ce85cf6a87..0000000000 --- a/src/mapi/glapi/glapi.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2008 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. - */ - - -/* - * This file manages the OpenGL API dispatch layer. - * The dispatch table (struct _glapi_table) is basically just a list - * of function pointers. - * There are functions to set/get the current dispatch table for the - * current thread and to manage registration/dispatch of dynamically - * added extension functions. - * - * It's intended that this file and the other glapi*.[ch] files are - * flexible enough to be reused in several places: XFree86, DRI- - * based libGL.so, and perhaps the SGI SI. - * - * NOTE: There are no dependencies on Mesa in this code. - * - * Versions (API changes): - * 2000/02/23 - original version for Mesa 3.3 and XFree86 4.0 - * 2001/01/16 - added dispatch override feature for Mesa 3.5 - * 2002/06/28 - added _glapi_set_warning_func(), Mesa 4.1. - * 2002/10/01 - _glapi_get_proc_address() will now generate new entrypoints - * itself (using offset ~0). _glapi_add_entrypoint() can be - * called afterward and it'll fill in the correct dispatch - * offset. This allows DRI libGL to avoid probing for DRI - * drivers! No changes to the public glapi interface. - */ - - - -#ifdef HAVE_DIX_CONFIG_H -#include -#include "glapi/mesa.h" -#else -#include "main/glheader.h" -#include "main/compiler.h" -#endif - -#include "glapi/glapi.h" -#include "glapi/glapi_priv.h" - -extern _glapi_proc __glapi_noop_table[]; - - -/** - * \name Current dispatch and current context control variables - * - * Depending on whether or not multithreading is support, and the type of - * support available, several variables are used to store the current context - * pointer and the current dispatch table pointer. In the non-threaded case, - * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this - * purpose. - * - * In the "normal" threaded case, the variables \c _glapi_Dispatch and - * \c _glapi_Context will be \c NULL if an application is detected as being - * multithreaded. Single-threaded applications will use \c _glapi_Dispatch - * and \c _glapi_Context just like the case without any threading support. - * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state - * data \c _gl_DispatchTSD and \c ContextTSD are used. Drivers and the - * static dispatch functions access these variables via \c _glapi_get_dispatch - * and \c _glapi_get_context. - * - * There is a race condition in setting \c _glapi_Dispatch to \c NULL. It is - * possible for the original thread to be setting it at the same instant a new - * thread, perhaps running on a different processor, is clearing it. Because - * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is - * used to determine whether or not the application is multithreaded. - * - * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are - * hardcoded to \c NULL. Instead the TLS variables \c _glapi_tls_Dispatch and - * \c _glapi_tls_Context are used. Having \c _glapi_Dispatch and - * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability - * between TLS enabled loaders and non-TLS DRI drivers. - */ -/*@{*/ -#if defined(GLX_USE_TLS) - -PUBLIC __thread struct _glapi_table * _glapi_tls_Dispatch - __attribute__((tls_model("initial-exec"))) - = (struct _glapi_table *) __glapi_noop_table; - -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) - -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 */ - -#endif /* defined(THREADS) */ - -PUBLIC struct _glapi_table *_glapi_Dispatch = (struct _glapi_table *) __glapi_noop_table; - -PUBLIC void *_glapi_Context = NULL; - -#endif /* defined(GLX_USE_TLS) */ -/*@}*/ - - - -#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 - * in order to test if multiple threads are being used. - */ -PUBLIC void -_glapi_check_multithread(void) -{ - static unsigned long knownID; - static GLboolean firstCall = GL_TRUE; - - if (ThreadSafe) - return; - - CHECK_MULTITHREAD_LOCK(); - if (firstCall) { - _glapi_init_multithread(); - - knownID = _glthread_GetID(); - firstCall = GL_FALSE; - } - else if (knownID != _glthread_GetID()) { - ThreadSafe = GL_TRUE; - _glapi_set_dispatch(NULL); - _glapi_set_context(NULL); - } - CHECK_MULTITHREAD_UNLOCK(); -} - -#else - -void -_glapi_init_multithread(void) { } - -void -_glapi_destroy_multithread(void) { } - -PUBLIC void -_glapi_check_multithread(void) { } - -#endif - - - -/** - * Set the current context pointer for this thread. - * The context pointer is an opaque type which should be cast to - * void from the real context pointer type. - */ -PUBLIC void -_glapi_set_context(void *context) -{ -#if defined(GLX_USE_TLS) - _glapi_tls_Context = context; -#elif defined(THREADS) - _glthread_SetTSD(&ContextTSD, context); - _glapi_Context = (ThreadSafe) ? NULL : context; -#else - _glapi_Context = context; -#endif -} - - - -/** - * Get the current context pointer for this thread. - * The context pointer is an opaque type which should be cast from - * void to the real context pointer type. - */ -PUBLIC void * -_glapi_get_context(void) -{ -#if defined(GLX_USE_TLS) - return _glapi_tls_Context; -#elif defined(THREADS) - return (ThreadSafe) ? _glthread_GetTSD(&ContextTSD) : _glapi_Context; -#else - return _glapi_Context; -#endif -} - - - -/** - * Set the global or per-thread dispatch table pointer. - * If the dispatch parameter is NULL we'll plug in the no-op dispatch - * table (__glapi_noop_table). - */ -PUBLIC void -_glapi_set_dispatch(struct _glapi_table *dispatch) -{ - init_glapi_relocs_once(); - - 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 - -#if defined(GLX_USE_TLS) - _glapi_tls_Dispatch = dispatch; -#elif defined(THREADS) - _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch); - _glapi_Dispatch = (ThreadSafe) ? NULL : dispatch; -#else - _glapi_Dispatch = dispatch; -#endif -} - - - -/** - * Return pointer to current dispatch table for calling thread. - */ -PUBLIC struct _glapi_table * -_glapi_get_dispatch(void) -{ -#if defined(GLX_USE_TLS) - return _glapi_tls_Dispatch; -#elif defined(THREADS) - return (ThreadSafe) - ? (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD) - : _glapi_Dispatch; -#else - return _glapi_Dispatch; -#endif -} diff --git a/src/mapi/glapi/glapi.h b/src/mapi/glapi/glapi.h index 7dcf2e8910..a74884d595 100644 --- a/src/mapi/glapi/glapi.h +++ b/src/mapi/glapi/glapi.h @@ -44,15 +44,11 @@ #ifndef _GLAPI_H #define _GLAPI_H -#include "glthread.h" - - -struct _glapi_table; - -typedef void (*_glapi_proc)(void); /* generic function pointer */ - +#ifndef MAPI_GLAPI_CURRENT +#define MAPI_GLAPI_CURRENT +#endif -#if defined(USE_MGL_NAMESPACE) +#ifdef USE_MGL_NAMESPACE #define _glapi_set_dispatch _mglapi_set_dispatch #define _glapi_get_dispatch _mglapi_get_dispatch #define _glapi_set_context _mglapi_set_context @@ -61,111 +57,31 @@ typedef void (*_glapi_proc)(void); /* generic function pointer */ #define _glapi_Context _mglapi_Context #endif +#include "mapi/u_current.h" +#include "glapi/glthread.h" -#if defined(__GNUC__) -# 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_DISPATCH() and GET_CURRENT_CONTEXT() macros. - ** - ** \param C local variable which will hold the current context. - **/ -#if defined (GLX_USE_TLS) - -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 struct _glapi_table *_glapi_Dispatch; - -extern void *_glapi_Context; - -# ifdef THREADS - -# 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) */ - - -/** - ** GL API public functions - **/ - -extern void -_glapi_init_multithread(void); - - -extern void -_glapi_destroy_multithread(void); - - -extern void -_glapi_check_multithread(void); - - -extern void -_glapi_set_context(void *context); - - -extern void * -_glapi_get_context(void); - - -extern void -_glapi_set_dispatch(struct _glapi_table *dispatch); - - -extern struct _glapi_table * -_glapi_get_dispatch(void); +typedef void (*_glapi_proc)(void); +#define GET_DISPATCH() ((struct _glapi_table *) u_current_get()) +#define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) u_current_get_user() -extern unsigned int +PUBLIC unsigned int _glapi_get_dispatch_table_size(void); -extern int +PUBLIC int _glapi_add_dispatch( const char * const * function_names, const char * parameter_signature ); -extern int +PUBLIC int _glapi_get_proc_offset(const char *funcName); -extern _glapi_proc +PUBLIC _glapi_proc _glapi_get_proc_address(const char *funcName); -extern const char * +PUBLIC const char * _glapi_get_proc_name(unsigned int offset); diff --git a/src/mapi/glapi/glapi_entrypoint.c b/src/mapi/glapi/glapi_entrypoint.c index 239780e753..82c68c27c8 100644 --- a/src/mapi/glapi/glapi_entrypoint.c +++ b/src/mapi/glapi/glapi_entrypoint.c @@ -39,6 +39,7 @@ #include "glapi/glapi.h" #include "glapi/glapi_priv.h" +#include "mapi/u_execmem.h" #ifdef USE_X86_ASM @@ -105,7 +106,7 @@ generate_entrypoint(unsigned int functionOffset) */ const GLubyte * const template_func = gl_dispatch_functions_start + (DISPATCH_FUNCTION_SIZE * 32); - GLubyte * const code = (GLubyte *) _glapi_exec_malloc(DISPATCH_FUNCTION_SIZE); + GLubyte * const code = (GLubyte *) u_execmem_alloc(DISPATCH_FUNCTION_SIZE); if ( code != NULL ) { @@ -288,7 +289,7 @@ generate_entrypoint(GLuint functionOffset) extern unsigned int __glapi_sparc_pthread_stub; unsigned long call_dest = (unsigned long ) &__glapi_sparc_pthread_stub; #endif - unsigned int *code = (unsigned int *) _glapi_exec_malloc(sizeof(template)); + unsigned int *code = (unsigned int *) u_execmem_alloc(sizeof(template)); if (code) { code[0] = template[0] | (functionOffset & 0x3fffff); code[1] = template[1]; diff --git a/src/mapi/glapi/glapi_execmem.c b/src/mapi/glapi/glapi_execmem.c deleted file mode 100644 index 57f00be8dc..0000000000 --- a/src/mapi/glapi/glapi_execmem.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 1999-2005 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. - */ - - -/** - * \file glapi_execmem.c - * - * Function for allocating executable memory for dispatch stubs. - * - * Copied from main/execmem.c and simplified for dispatch stubs. - */ - - -#ifdef HAVE_DIX_CONFIG_H -#include -#include "glapi/mesa.h" -#else -#include "main/compiler.h" -#endif - -#include "glapi/glthread.h" -#include "glapi/glapi_priv.h" - - -#if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun) - -#include -#include - -#ifdef MESA_SELINUX -#include -#endif - - -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif - - -#define EXEC_MAP_SIZE (4*1024) - -_glthread_DECLARE_STATIC_MUTEX(exec_mutex); - -static unsigned int head = 0; - -static unsigned char *exec_mem = NULL; - - -/* - * Dispatch stubs are of fixed size and never freed. Thus, we do not need to - * overlay a heap, we just mmap a page and manage through an index. - */ - -static int -init_map(void) -{ -#ifdef MESA_SELINUX - if (is_selinux_enabled()) { - if (!security_get_boolean_active("allow_execmem") || - !security_get_boolean_pending("allow_execmem")) - return 0; - } -#endif - - if (!exec_mem) - exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - return (exec_mem != MAP_FAILED); -} - - -void * -_glapi_exec_malloc(unsigned int size) -{ - void *addr = NULL; - - _glthread_LOCK_MUTEX(exec_mutex); - - if (!init_map()) - goto bail; - - /* free space check, assumes no integer overflow */ - if (head + size > EXEC_MAP_SIZE) - goto bail; - - /* allocation, assumes proper addr and size alignement */ - addr = exec_mem + head; - head += size; - -bail: - _glthread_UNLOCK_MUTEX(exec_mutex); - - return addr; -} - - -#else - -void * -_glapi_exec_malloc(unsigned int size) -{ - return malloc(size); -} - - -#endif diff --git a/src/mapi/glapi/glapi_getproc.c b/src/mapi/glapi/glapi_getproc.c index c73e8dd3b0..3c134f929d 100644 --- a/src/mapi/glapi/glapi_getproc.c +++ b/src/mapi/glapi/glapi_getproc.c @@ -387,7 +387,7 @@ set_entry_info( struct _glapi_function * entry, const char * signature, unsigned * the parameter signature of a static function. */ -PUBLIC int +int _glapi_add_dispatch( const char * const * function_names, const char * parameter_signature ) { @@ -501,7 +501,7 @@ _glapi_add_dispatch( const char * const * function_names, /** * Return offset of entrypoint for named function within dispatch table. */ -PUBLIC GLint +GLint _glapi_get_proc_offset(const char *funcName) { GLint offset; @@ -522,7 +522,7 @@ _glapi_get_proc_offset(const char *funcName) * in the name of static functions, try generating a new API entrypoint on * the fly with assembly language. */ -PUBLIC _glapi_proc +_glapi_proc _glapi_get_proc_address(const char *funcName) { _glapi_proc func; @@ -598,7 +598,7 @@ _glapi_get_proc_name(GLuint offset) * Return size of dispatch table struct as number of functions (or * slots). */ -PUBLIC GLuint +GLuint _glapi_get_dispatch_table_size(void) { return DISPATCH_TABLE_SIZE; diff --git a/src/mapi/glapi/glapi_priv.h b/src/mapi/glapi/glapi_priv.h index da6fee63fe..1c2a704211 100644 --- a/src/mapi/glapi/glapi_priv.h +++ b/src/mapi/glapi/glapi_priv.h @@ -41,12 +41,6 @@ extern void _glapi_check_table(const struct _glapi_table *table); -/* execmem */ - -extern void * -_glapi_exec_malloc(unsigned int size); - - /* entrypoint */ extern void diff --git a/src/mapi/glapi/glthread.c b/src/mapi/glapi/glthread.c index f365d17bdd..9dbc0e9a56 100644 --- a/src/mapi/glapi/glthread.c +++ b/src/mapi/glapi/glthread.c @@ -1,263 +1,7 @@ -/* - * 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. - */ +#include "glthread.h" - -/* - * 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. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#include "glapi/mesa.h" -#else -#include "main/compiler.h" -#endif - -#include "glapi/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 - -/* - * 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 - -PUBLIC 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 */ - - - -/* - * 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 - -static void InsteadOf_exit(int nCode) -{ - DWORD dwErr = GetLastError(); -} - -PUBLIC unsigned long -_glthread_GetID(void) -{ - return GetCurrentThreadId(); -} - - -void -_glthread_InitTSD(_glthread_TSD *tsd) -{ - tsd->key = TlsAlloc(); - if (tsd->key == TLS_OUT_OF_INDEXES) { - perror(INIT_TSD_ERROR); - InsteadOf_exit(-1); - } - tsd->initMagic = INIT_MAGIC; -} - - -void -_glthread_DestroyTSD(_glthread_TSD *tsd) -{ - if (tsd->initMagic != INIT_MAGIC) { - return; - } - TlsFree(tsd->key); - tsd->initMagic = 0x0; -} - - -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(SET_TSD_ERROR); - InsteadOf_exit(-1); - } -} - -#endif /* WIN32_THREADS */ - -/* - * BeOS threads - */ -#ifdef BEOS_THREADS - -PUBLIC unsigned long +unsigned long _glthread_GetID(void) { - return (unsigned long) find_thread(NULL); + return u_thread_self(); } - -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 - */ - -PUBLIC 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 */ diff --git a/src/mapi/glapi/glthread.h b/src/mapi/glapi/glthread.h index 4fe99284a8..54292706ac 100644 --- a/src/mapi/glapi/glthread.h +++ b/src/mapi/glapi/glthread.h @@ -1,255 +1,23 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * 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. - */ - - -/* - * 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 - * - * - * - * 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 - * - */ - -/* - * If this file is accidentally included by a non-threaded build, - * it should not cause the build to fail, or otherwise cause problems. - * In general, it should only be included when needed however. - */ - #ifndef GLTHREAD_H #define GLTHREAD_H +#include "mapi/u_thread.h" -#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS) -#ifndef THREADS -#define THREADS -#endif -#endif - - -/* - * POSIX threads. This should be your choice in the Unix world - * whenever possible. When building with POSIX threads, be sure - * to enable any compiler flags which will cause the MT-safe - * libc (if one exists) to be used when linking, as well as any - * header macros for MT-safe errno, etc. For Solaris, this is the -mt - * 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 */ - -typedef struct { - pthread_key_t key; - int initMagic; -} _glthread_TSD; - -typedef pthread_t _glthread_Thread; - -typedef pthread_mutex_t _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER - -#define _glthread_INIT_MUTEX(name) \ - pthread_mutex_init(&(name), NULL) - -#define _glthread_DESTROY_MUTEX(name) \ - pthread_mutex_destroy(&(name)) - -#define _glthread_LOCK_MUTEX(name) \ - (void) pthread_mutex_lock(&(name)) - -#define _glthread_UNLOCK_MUTEX(name) \ - (void) pthread_mutex_unlock(&(name)) - -#endif /* PTHREADS */ - - -/* - * Windows threads. Should work with Windows NT and 95. - * IMPORTANT: Link with multithreaded runtime library when THREADS are - * used! - */ -#ifdef WIN32_THREADS -#include - -typedef struct { - DWORD key; - int initMagic; -} _glthread_TSD; - -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) - -#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 +#define _glthread_DECLARE_STATIC_MUTEX(name) u_mutex_declare_static(name) +#define _glthread_INIT_MUTEX(name) u_mutex_init(name) +#define _glthread_DESTROY_MUTEX(name) u_mutex_destroy(name) +#define _glthread_LOCK_MUTEX(name) u_mutex_lock(name) +#define _glthread_UNLOCK_MUTEX(name) u_mutex_unlock(name) -typedef struct { - int32 key; - int initMagic; -} _glthread_TSD; +#define _glthread_InitTSD(tsd) u_tsd_init(tsd); +#define _glthread_DestroyTSD(tsd) u_tsd_destroy(tsd); +#define _glthread_GetTSD(tsd) u_tsd_get(tsd); +#define _glthread_SetTSD(tsd, ptr) u_tsd_set(tsd, ptr); -typedef thread_id _glthread_Thread; +typedef struct u_tsd _glthread_TSD; +typedef u_mutex _glthread_Mutex; -/* Use Benaphore, aka speeder semaphore */ -typedef struct { - int32 lock; - sem_id sem; -} 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) - -#endif /* BEOS_THREADS */ - - -/* - * THREADS not defined - */ -#ifndef THREADS - -typedef unsigned _glthread_TSD; - -typedef unsigned _glthread_Thread; - -typedef unsigned _glthread_Mutex; - -#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 /* THREADS */ - - - -/* - * Platform independent thread specific data API. - */ - -extern unsigned long +PUBLIC unsigned long _glthread_GetID(void); - -extern void -_glthread_InitTSD(_glthread_TSD *); - - -extern void -_glthread_DestroyTSD(_glthread_TSD *); /* WIN32 only */ - - -extern void * -_glthread_GetTSD(_glthread_TSD *); - - -extern void -_glthread_SetTSD(_glthread_TSD *, void *); - - #endif /* THREADS_H */ diff --git a/src/mapi/glapi/sources.mak b/src/mapi/glapi/sources.mak index 8e1e82f359..cdcfa36e51 100644 --- a/src/mapi/glapi/sources.mak +++ b/src/mapi/glapi/sources.mak @@ -1,10 +1,8 @@ # src/mapi/glapi/sources.mak GLAPI_SOURCES = \ - glapi.c \ glapi_dispatch.c \ glapi_entrypoint.c \ - glapi_execmem.c \ glapi_getproc.c \ glapi_nop.c \ glthread.c diff --git a/src/mapi/mapi/sources.mak b/src/mapi/mapi/sources.mak new file mode 100644 index 0000000000..9e27f45e2a --- /dev/null +++ b/src/mapi/mapi/sources.mak @@ -0,0 +1,6 @@ +# src/mapi/mapi/sources.mak + +MAPI_GLAPI_SOURCES = \ + u_current.c \ + u_execmem.c \ + u_thread.c diff --git a/src/mapi/mapi/u_compiler.h b/src/mapi/mapi/u_compiler.h new file mode 100644 index 0000000000..cc9e2cd1e8 --- /dev/null +++ b/src/mapi/mapi/u_compiler.h @@ -0,0 +1,48 @@ +#ifndef _U_COMPILER_H_ +#define _U_COMPILER_H_ + +/* Function inlining */ +#ifndef INLINE +# ifdef __cplusplus +# define INLINE inline +# elif defined(__GNUC__) +# define INLINE __inline__ +# elif defined(_MSC_VER) +# define INLINE __inline +# elif defined(__ICL) +# define INLINE __inline +# elif defined(__INTEL_COMPILER) +# define INLINE inline +# elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) +# define INLINE __inline +# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) +# define INLINE inline +# elif (__STDC_VERSION__ >= 199901L) /* C99 */ +# define INLINE inline +# else +# define INLINE +# endif +#endif + +/* Function visibility */ +#ifndef PUBLIC +# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# define PUBLIC __attribute__((visibility("default"))) +# define HIDDEN __attribute__((visibility("hidden"))) +# else +# define PUBLIC +# define HIDDEN +# endif +#endif + +#ifndef likely +# if defined(__GNUC__) +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +# else +# define likely(x) (x) +# define unlikely(x) (x) +# endif +#endif + +#endif /* _U_COMPILER_H_ */ diff --git a/src/mapi/mapi/u_current.c b/src/mapi/mapi/u_current.c new file mode 100644 index 0000000000..91547c4830 --- /dev/null +++ b/src/mapi/mapi/u_current.c @@ -0,0 +1,274 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2008 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. + */ + + +/* + * This file manages the OpenGL API dispatch layer. + * The dispatch table (struct _glapi_table) is basically just a list + * of function pointers. + * There are functions to set/get the current dispatch table for the + * current thread and to manage registration/dispatch of dynamically + * added extension functions. + * + * It's intended that this file and the other glapi*.[ch] files are + * flexible enough to be reused in several places: XFree86, DRI- + * based libGL.so, and perhaps the SGI SI. + * + * NOTE: There are no dependencies on Mesa in this code. + * + * Versions (API changes): + * 2000/02/23 - original version for Mesa 3.3 and XFree86 4.0 + * 2001/01/16 - added dispatch override feature for Mesa 3.5 + * 2002/06/28 - added _glapi_set_warning_func(), Mesa 4.1. + * 2002/10/01 - _glapi_get_proc_address() will now generate new entrypoints + * itself (using offset ~0). _glapi_add_entrypoint() can be + * called afterward and it'll fill in the correct dispatch + * offset. This allows DRI libGL to avoid probing for DRI + * drivers! No changes to the public glapi interface. + */ + +#include "u_current.h" +#include "u_thread.h" + +#ifndef MAPI_GLAPI_CURRENT + +#include "table.h" +#include "stub.h" + +#else + +extern void init_glapi_relocs_once(void); +extern void (*__glapi_noop_table[])(void); + +#define table_noop_array __glapi_noop_table +#define stub_init_once() init_glapi_relocs_once() + +#endif + +/** + * \name Current dispatch and current context control variables + * + * Depending on whether or not multithreading is support, and the type of + * support available, several variables are used to store the current context + * pointer and the current dispatch table pointer. In the non-threaded case, + * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this + * purpose. + * + * In the "normal" threaded case, the variables \c _glapi_Dispatch and + * \c _glapi_Context will be \c NULL if an application is detected as being + * multithreaded. Single-threaded applications will use \c _glapi_Dispatch + * and \c _glapi_Context just like the case without any threading support. + * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state + * data \c _gl_DispatchTSD and \c ContextTSD are used. Drivers and the + * static dispatch functions access these variables via \c _glapi_get_dispatch + * and \c _glapi_get_context. + * + * There is a race condition in setting \c _glapi_Dispatch to \c NULL. It is + * possible for the original thread to be setting it at the same instant a new + * thread, perhaps running on a different processor, is clearing it. Because + * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is + * used to determine whether or not the application is multithreaded. + * + * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are + * hardcoded to \c NULL. Instead the TLS variables \c _glapi_tls_Dispatch and + * \c _glapi_tls_Context are used. Having \c _glapi_Dispatch and + * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability + * between TLS enabled loaders and non-TLS DRI drivers. + */ +/*@{*/ +#if defined(GLX_USE_TLS) + +__thread struct _glapi_table *_glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))) + = (struct _glapi_table *) table_noop_array; + +__thread void * _glapi_tls_Context + __attribute__((tls_model("initial-exec"))); + +const struct _glapi_table *_glapi_Dispatch; +const void *_glapi_Context; + +#else + +struct _glapi_table *_glapi_Dispatch = + (struct _glapi_table *) table_noop_array; +void *_glapi_Context; + +#ifdef THREADS +struct u_tsd _gl_DispatchTSD; +static struct u_tsd ContextTSD; +static int ThreadSafe; +#endif /* THREADS */ + +#endif /* defined(GLX_USE_TLS) */ +/*@}*/ + + +void +_glapi_destroy_multithread(void) +{ +#if defined(THREADS) && defined(WIN32_THREADS) + u_tsd_destroy(&_gl_DispatchTSD); + u_tsd_destroy(&ContextTSD); +#endif +} + + +#if defined(THREADS) && !defined(GLX_USE_TLS) + +static void +_glapi_init_multithread(void) +{ + u_tsd_init(&_gl_DispatchTSD); + u_tsd_init(&ContextTSD); +} + +/** + * 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 +u_mutex_declare_static(ThreadCheckMutex); +#define CHECK_MULTITHREAD_LOCK() u_mutex_lock(ThreadCheckMutex) +#define CHECK_MULTITHREAD_UNLOCK() u_mutex_unlock(ThreadCheckMutex) +#endif + +/** + * We should call this periodically from a function such as glXMakeCurrent + * in order to test if multiple threads are being used. + */ +void +_glapi_check_multithread(void) +{ + static unsigned long knownID; + static int firstCall = 1; + + if (ThreadSafe) + return; + + CHECK_MULTITHREAD_LOCK(); + if (firstCall) { + _glapi_init_multithread(); + + knownID = u_thread_self(); + firstCall = 0; + } + else if (knownID != u_thread_self()) { + ThreadSafe = 1; + _glapi_set_dispatch(NULL); + _glapi_set_context(NULL); + } + CHECK_MULTITHREAD_UNLOCK(); +} + +#else + +void +_glapi_check_multithread(void) +{ +} + +#endif + + + +/** + * Set the current context pointer for this thread. + * The context pointer is an opaque type which should be cast to + * void from the real context pointer type. + */ +void +_glapi_set_context(void *context) +{ +#if defined(GLX_USE_TLS) + _glapi_tls_Context = context; +#elif defined(THREADS) + u_tsd_set(&ContextTSD, context); + _glapi_Context = (ThreadSafe) ? NULL : context; +#else + _glapi_Context = context; +#endif +} + +/** + * Get the current context pointer for this thread. + * The context pointer is an opaque type which should be cast from + * void to the real context pointer type. + */ +void * +_glapi_get_context(void) +{ +#if defined(GLX_USE_TLS) + return _glapi_tls_Context; +#elif defined(THREADS) + return (ThreadSafe) + ? u_tsd_get(&ContextTSD) + : _glapi_Context; +#else + return _glapi_Context; +#endif +} + +/** + * Set the global or per-thread dispatch table pointer. + * If the dispatch parameter is NULL we'll plug in the no-op dispatch + * table (__glapi_noop_table). + */ +void +_glapi_set_dispatch(struct _glapi_table *dispatch) +{ + stub_init_once(); + + if (!dispatch) + dispatch = (struct _glapi_table *) table_noop_array; + +#if defined(GLX_USE_TLS) + _glapi_tls_Dispatch = dispatch; +#elif defined(THREADS) + u_tsd_set(&_gl_DispatchTSD, (void *) dispatch); + _glapi_Dispatch = (ThreadSafe) ? NULL : dispatch; +#else + _glapi_Dispatch = dispatch; +#endif +} + +/** + * Return pointer to current dispatch table for calling thread. + */ +struct _glapi_table * +_glapi_get_dispatch(void) +{ +#if defined(GLX_USE_TLS) + return _glapi_tls_Dispatch; +#elif defined(THREADS) + return (ThreadSafe) + ? (struct _glapi_table *) u_tsd_get(&_gl_DispatchTSD) + : _glapi_Dispatch; +#else + return _glapi_Dispatch; +#endif +} diff --git a/src/mapi/mapi/u_current.h b/src/mapi/mapi/u_current.h new file mode 100644 index 0000000000..a6256f5b51 --- /dev/null +++ b/src/mapi/mapi/u_current.h @@ -0,0 +1,93 @@ +#ifndef _U_CURRENT_H_ +#define _U_CURRENT_H_ + +#include "u_compiler.h" + +#ifdef MAPI_GLAPI_CURRENT +#define GLAPI_EXPORT PUBLIC +#else +#define GLAPI_EXPORT +#endif + +/* + * Unlike other utility functions, we need to keep the old names (_glapi_*) for + * ABI compatibility. The desired functions are wrappers to the old ones. + */ + +struct _glapi_table; + +#ifdef GLX_USE_TLS + +GLAPI_EXPORT extern __thread struct _glapi_table *_glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); + +GLAPI_EXPORT extern __thread void *_glapi_tls_Context + __attribute__((tls_model("initial-exec"))); + +GLAPI_EXPORT extern const struct _glapi_table *_glapi_Dispatch; +GLAPI_EXPORT extern const void *_glapi_Context; + +#else /* GLX_USE_TLS */ + +GLAPI_EXPORT extern struct _glapi_table *_glapi_Dispatch; +GLAPI_EXPORT extern void *_glapi_Context; + +#endif /* GLX_USE_TLS */ + +GLAPI_EXPORT void +_glapi_check_multithread(void); + +GLAPI_EXPORT void +_glapi_set_context(void *context); + +GLAPI_EXPORT void * +_glapi_get_context(void); + +GLAPI_EXPORT void +_glapi_set_dispatch(struct _glapi_table *dispatch); + +GLAPI_EXPORT struct _glapi_table * +_glapi_get_dispatch(void); + +void +_glapi_destroy_multithread(void); + + +struct mapi_table; + +static INLINE void +u_current_set(const struct mapi_table *tbl) +{ + _glapi_check_multithread(); + _glapi_set_dispatch((struct _glapi_table *) tbl); +} + +static INLINE const struct mapi_table * +u_current_get(void) +{ +#ifdef GLX_USE_TLS + return (const struct mapi_table *) _glapi_tls_Dispatch; +#else + return (const struct mapi_table *) (likely(_glapi_Dispatch) ? + _glapi_Dispatch : _glapi_get_dispatch()); +#endif +} + +static INLINE void +u_current_set_user(void *ptr) +{ + _glapi_check_multithread(); + _glapi_set_context(ptr); +} + +static INLINE void * +u_current_get_user(void) +{ +#ifdef GLX_USE_TLS + return _glapi_tls_Context; +#else + return likely(_glapi_Context) ? _glapi_Context : _glapi_get_context(); +#endif +} + +#endif /* GLX_USE_TLS */ diff --git a/src/mapi/mapi/u_execmem.c b/src/mapi/mapi/u_execmem.c new file mode 100644 index 0000000000..0e0f8aa316 --- /dev/null +++ b/src/mapi/mapi/u_execmem.c @@ -0,0 +1,122 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2005 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. + */ + + +/** + * \file glapi_execmem.c + * + * Function for allocating executable memory for dispatch stubs. + * + * Copied from main/execmem.c and simplified for dispatch stubs. + */ + + +#include "u_compiler.h" +#include "u_thread.h" +#include "u_execmem.h" + + +#if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun) + +#include +#include + +#ifdef MESA_SELINUX +#include +#endif + + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + + +#define EXEC_MAP_SIZE (4*1024) + +u_mutex_declare_static(exec_mutex); + +static unsigned int head = 0; + +static unsigned char *exec_mem = NULL; + + +/* + * Dispatch stubs are of fixed size and never freed. Thus, we do not need to + * overlay a heap, we just mmap a page and manage through an index. + */ + +static int +init_map(void) +{ +#ifdef MESA_SELINUX + if (is_selinux_enabled()) { + if (!security_get_boolean_active("allow_execmem") || + !security_get_boolean_pending("allow_execmem")) + return 0; + } +#endif + + if (!exec_mem) + exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + return (exec_mem != MAP_FAILED); +} + + +void * +u_execmem_alloc(unsigned int size) +{ + void *addr = NULL; + + u_mutex_lock(exec_mutex); + + if (!init_map()) + goto bail; + + /* free space check, assumes no integer overflow */ + if (head + size > EXEC_MAP_SIZE) + goto bail; + + /* allocation, assumes proper addr and size alignement */ + addr = exec_mem + head; + head += size; + +bail: + u_mutex_unlock(exec_mutex); + + return addr; +} + + +#else + +void * +u_execmem_alloc(unsigned int size) +{ + return malloc(size); +} + + +#endif diff --git a/src/mapi/mapi/u_execmem.h b/src/mapi/mapi/u_execmem.h new file mode 100644 index 0000000000..13fff8df22 --- /dev/null +++ b/src/mapi/mapi/u_execmem.h @@ -0,0 +1,7 @@ +#ifndef _U_EXECMEM_H_ +#define _U_EXECMEM_H_ + +void * +u_execmem_alloc(unsigned int size); + +#endif /* _U_EXECMEM_H_ */ diff --git a/src/mapi/mapi/u_thread.c b/src/mapi/mapi/u_thread.c new file mode 100644 index 0000000000..e0fa64ae03 --- /dev/null +++ b/src/mapi/mapi/u_thread.c @@ -0,0 +1,254 @@ +/* + * 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. + */ + + +#include +#include +#include "u_compiler.h" +#include "u_thread.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 + +/* + * 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 +u_thread_self(void) +{ + return (unsigned long) pthread_self(); +} + + +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; +} + + +void * +u_tsd_get(struct u_tsd *tsd) +{ + if (tsd->initMagic != (int) INIT_MAGIC) { + u_tsd_init(tsd); + } + return pthread_getspecific(tsd->key); +} + + +void +u_tsd_set(struct u_tsd *tsd, void *ptr) +{ + if (tsd->initMagic != (int) INIT_MAGIC) { + u_tsd_init(tsd); + } + if (pthread_setspecific(tsd->key, ptr) != 0) { + perror(SET_TSD_ERROR); + exit(-1); + } +} + +#endif /* PTHREADS */ + + + +/* + * 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 + +static void InsteadOf_exit(int nCode) +{ + DWORD dwErr = GetLastError(); +} + +unsigned long +u_thread_self(void) +{ + return GetCurrentThreadId(); +} + + +void +u_tsd_init(struct u_tsd *tsd) +{ + tsd->key = TlsAlloc(); + if (tsd->key == TLS_OUT_OF_INDEXES) { + perror(INIT_TSD_ERROR); + InsteadOf_exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +void +u_tsd_destroy(struct u_tsd *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + return; + } + TlsFree(tsd->key); + tsd->initMagic = 0x0; +} + + +void * +u_tsd_get(struct u_tsd *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + u_tsd_init(tsd); + } + return TlsGetValue(tsd->key); +} + + +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); + InsteadOf_exit(-1); + } +} + +#endif /* WIN32_THREADS */ + +/* + * BeOS threads + */ +#ifdef BEOS_THREADS + +unsigned long +u_thread_self(void) +{ + return (unsigned long) find_thread(NULL); +} + +void +u_tsd_init(struct u_tsd *tsd) +{ + tsd->key = tls_allocate(); + tsd->initMagic = INIT_MAGIC; +} + +void * +u_tsd_get(struct u_tsd *tsd) +{ + if (tsd->initMagic != (int) INIT_MAGIC) { + u_tsd_init(tsd); + } + return tls_get(tsd->key); +} + +void +u_tsd_set(struct u_tsd *tsd, void *ptr) +{ + if (tsd->initMagic != (int) INIT_MAGIC) { + u_tsd_init(tsd); + } + tls_set(tsd->key, ptr); +} + +#endif /* BEOS_THREADS */ + + + +#else /* THREADS */ + + +/* + * no-op functions + */ + +unsigned long +_glthread_GetID(void) +{ + return 0; +} + + +void +u_tsd_init(struct u_tsd *tsd) +{ + (void) tsd; +} + + +void * +u_tsd_get(struct u_tsd *tsd) +{ + (void) tsd; + return NULL; +} + + +void +u_tsd_set(struct u_tsd *tsd, void *ptr) +{ + (void) tsd; + (void) ptr; +} + + +#endif /* THREADS */ diff --git a/src/mapi/mapi/u_thread.h b/src/mapi/mapi/u_thread.h new file mode 100644 index 0000000000..992dbaace9 --- /dev/null +++ b/src/mapi/mapi/u_thread.h @@ -0,0 +1,200 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * 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. + */ + + +/* + * 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 + * Modified for use in mapi by Chia-I Wu + */ + +/* + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef _U_THREAD_H_ +#define _U_THREAD_H_ + +#include "u_compiler.h" + +#if defined(PTHREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS) +#ifndef THREADS +#define THREADS +#endif +#endif + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * 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 */ + +struct u_tsd { + pthread_key_t key; + int initMagic; +}; + +typedef pthread_mutex_t u_mutex; + +#define u_mutex_declare_static(name) \ + static u_mutex name = PTHREAD_MUTEX_INITIALIZER + +#define u_mutex_init(name) pthread_mutex_init(&(name), NULL) +#define u_mutex_destroy(name) pthread_mutex_destroy(&(name)) +#define u_mutex_lock(name) (void) pthread_mutex_lock(&(name)) +#define u_mutex_unlock(name) (void) pthread_mutex_unlock(&(name)) + +#endif /* PTHREADS */ + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef WIN32_THREADS +#include + +struct u_tsd { + DWORD key; + int initMagic; +}; + +typedef CRITICAL_SECTION u_mutex; + +#define u_mutex_declare_static(name) \ + /* static */ u_mutex name = { 0, 0, 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 */ + + +/* + * THREADS not defined + */ +#ifndef THREADS + +struct u_tsd { + int initMagic; +}; + +typedef unsigned u_mutex; + +#define u_mutex_declare_static(name) static u_mutex name = 0 +#define u_mutex_init(name) (void) name +#define u_mutex_destroy(name) (void) name +#define u_mutex_lock(name) (void) name +#define u_mutex_unlock(name) (void) name + +#endif /* THREADS */ + + +unsigned long +u_thread_self(void); + +void +u_tsd_init(struct u_tsd *tsd); + +void +u_tsd_destroy(struct u_tsd *tsd); /* WIN32 only */ + +void * +u_tsd_get(struct u_tsd *tsd); + +void +u_tsd_set(struct u_tsd *tsd, void *ptr); + +#endif /* _U_THREAD_H_ */ -- cgit v1.2.3