From a73c6540d9a7f6e26d8568ba2fc522cb865f0a6c Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 23 Apr 2010 16:06:26 +0800 Subject: [PATCH] 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.h | 112 +------- src/mapi/glapi/glapi_entrypoint.c | 5 +- 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/{glapi/glapi.c => mapi/u_current.c} | 143 +++++----- src/mapi/mapi/u_current.h | 93 +++++++ .../glapi_execmem.c => mapi/u_execmem.c} | 22 +- src/mapi/mapi/u_execmem.h | 7 + src/mapi/mapi/u_thread.c | 254 +++++++++++++++++ src/mapi/mapi/u_thread.h | 200 +++++++++++++ 19 files changed, 794 insertions(+), 743 deletions(-) create mode 100644 src/mapi/mapi/sources.mak create mode 100644 src/mapi/mapi/u_compiler.h rename src/mapi/{glapi/glapi.c => mapi/u_current.c} (74%) create mode 100644 src/mapi/mapi/u_current.h rename src/mapi/{glapi/glapi_execmem.c => mapi/u_execmem.c} (87%) 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 5e5fc127b3f..1af3f52f942 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 9130d0b01c4..203cc36deab 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 13c8c54de21..ca9381d4253 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 1ace2e6b2cd..15c08255c39 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.h b/src/mapi/glapi/glapi.h index 7dcf2e8910b..a74884d595a 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 239780e7539..82c68c27c8b 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_getproc.c b/src/mapi/glapi/glapi_getproc.c index c73e8dd3b04..3c134f929d6 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 da6fee63fe7..1c2a7042113 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 f365d17bdda..9dbc0e9a56f 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 4fe99284a8c..54292706acf 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 8e1e82f359a..cdcfa36e51f 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 00000000000..9e27f45e2a9 --- /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 00000000000..cc9e2cd1e81 --- /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/glapi/glapi.c b/src/mapi/mapi/u_current.c similarity index 74% rename from src/mapi/glapi/glapi.c rename to src/mapi/mapi/u_current.c index ce85cf6a87b..91547c48301 100644 --- a/src/mapi/glapi/glapi.c +++ b/src/mapi/mapi/u_current.c @@ -48,21 +48,23 @@ * 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" -#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 void init_glapi_relocs_once(void); +extern void (*__glapi_noop_table[])(void); -extern _glapi_proc __glapi_noop_table[]; +#define table_noop_array __glapi_noop_table +#define stub_init_once() init_glapi_relocs_once() +#endif /** * \name Current dispatch and current context control variables @@ -97,54 +99,49 @@ extern _glapi_proc __glapi_noop_table[]; /*@{*/ #if defined(GLX_USE_TLS) -PUBLIC __thread struct _glapi_table * _glapi_tls_Dispatch +__thread struct _glapi_table *_glapi_tls_Dispatch __attribute__((tls_model("initial-exec"))) - = (struct _glapi_table *) __glapi_noop_table; + = (struct _glapi_table *) table_noop_array; -PUBLIC __thread void * _glapi_tls_Context +__thread void * _glapi_tls_Context __attribute__((tls_model("initial-exec"))); -PUBLIC const struct _glapi_table *_glapi_Dispatch = NULL; - -PUBLIC const void *_glapi_Context = NULL; +const struct _glapi_table *_glapi_Dispatch; +const void *_glapi_Context; #else -#if defined(THREADS) - -static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */ - -_glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */ +struct _glapi_table *_glapi_Dispatch = + (struct _glapi_table *) table_noop_array; +void *_glapi_Context; -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; +#ifdef THREADS +struct u_tsd _gl_DispatchTSD; +static struct u_tsd ContextTSD; +static int ThreadSafe; +#endif /* THREADS */ #endif /* defined(GLX_USE_TLS) */ /*@}*/ - -#if defined(THREADS) && !defined(GLX_USE_TLS) - void -_glapi_init_multithread(void) +_glapi_destroy_multithread(void) { - _glthread_InitTSD(&_gl_DispatchTSD); - _glthread_InitTSD(&ContextTSD); +#if defined(THREADS) && defined(WIN32_THREADS) + u_tsd_destroy(&_gl_DispatchTSD); + u_tsd_destroy(&ContextTSD); +#endif } -void -_glapi_destroy_multithread(void) + +#if defined(THREADS) && !defined(GLX_USE_TLS) + +static void +_glapi_init_multithread(void) { -#ifdef WIN32_THREADS - _glthread_DestroyTSD(&_gl_DispatchTSD); - _glthread_DestroyTSD(&ContextTSD); -#endif + u_tsd_init(&_gl_DispatchTSD); + u_tsd_init(&ContextTSD); } /** @@ -155,20 +152,20 @@ _glapi_destroy_multithread(void) #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) +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. */ -PUBLIC void +void _glapi_check_multithread(void) { static unsigned long knownID; - static GLboolean firstCall = GL_TRUE; + static int firstCall = 1; if (ThreadSafe) return; @@ -177,11 +174,11 @@ _glapi_check_multithread(void) if (firstCall) { _glapi_init_multithread(); - knownID = _glthread_GetID(); - firstCall = GL_FALSE; + knownID = u_thread_self(); + firstCall = 0; } - else if (knownID != _glthread_GetID()) { - ThreadSafe = GL_TRUE; + else if (knownID != u_thread_self()) { + ThreadSafe = 1; _glapi_set_dispatch(NULL); _glapi_set_context(NULL); } @@ -191,13 +188,9 @@ _glapi_check_multithread(void) #else void -_glapi_init_multithread(void) { } - -void -_glapi_destroy_multithread(void) { } - -PUBLIC void -_glapi_check_multithread(void) { } +_glapi_check_multithread(void) +{ +} #endif @@ -208,85 +201,73 @@ _glapi_check_multithread(void) { } * The context pointer is an opaque type which should be cast to * void from the real context pointer type. */ -PUBLIC void +void _glapi_set_context(void *context) { #if defined(GLX_USE_TLS) _glapi_tls_Context = context; #elif defined(THREADS) - _glthread_SetTSD(&ContextTSD, context); + 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. */ -PUBLIC void * +void * _glapi_get_context(void) { #if defined(GLX_USE_TLS) return _glapi_tls_Context; #elif defined(THREADS) - return (ThreadSafe) ? _glthread_GetTSD(&ContextTSD) : _glapi_Context; + 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). */ -PUBLIC void +void _glapi_set_dispatch(struct _glapi_table *dispatch) { - init_glapi_relocs_once(); + stub_init_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 (!dispatch) + dispatch = (struct _glapi_table *) table_noop_array; #if defined(GLX_USE_TLS) _glapi_tls_Dispatch = dispatch; #elif defined(THREADS) - _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch); + 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. */ -PUBLIC struct _glapi_table * +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; + ? (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 00000000000..a6256f5b512 --- /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/glapi/glapi_execmem.c b/src/mapi/mapi/u_execmem.c similarity index 87% rename from src/mapi/glapi/glapi_execmem.c rename to src/mapi/mapi/u_execmem.c index 57f00be8dcc..0e0f8aa316f 100644 --- a/src/mapi/glapi/glapi_execmem.c +++ b/src/mapi/mapi/u_execmem.c @@ -32,15 +32,9 @@ */ -#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" +#include "u_compiler.h" +#include "u_thread.h" +#include "u_execmem.h" #if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun) @@ -60,7 +54,7 @@ #define EXEC_MAP_SIZE (4*1024) -_glthread_DECLARE_STATIC_MUTEX(exec_mutex); +u_mutex_declare_static(exec_mutex); static unsigned int head = 0; @@ -92,11 +86,11 @@ init_map(void) void * -_glapi_exec_malloc(unsigned int size) +u_execmem_alloc(unsigned int size) { void *addr = NULL; - _glthread_LOCK_MUTEX(exec_mutex); + u_mutex_lock(exec_mutex); if (!init_map()) goto bail; @@ -110,7 +104,7 @@ _glapi_exec_malloc(unsigned int size) head += size; bail: - _glthread_UNLOCK_MUTEX(exec_mutex); + u_mutex_unlock(exec_mutex); return addr; } @@ -119,7 +113,7 @@ bail: #else void * -_glapi_exec_malloc(unsigned int size) +u_execmem_alloc(unsigned int size) { return malloc(size); } diff --git a/src/mapi/mapi/u_execmem.h b/src/mapi/mapi/u_execmem.h new file mode 100644 index 00000000000..13fff8df225 --- /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 00000000000..e0fa64ae034 --- /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 00000000000..992dbaace96 --- /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_ */ -- 2.30.2