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.
This commit is contained in:
parent
296adbd545
commit
a73c6540d9
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -44,15 +44,11 @@
|
|||
#ifndef _GLAPI_H
|
||||
#define _GLAPI_H
|
||||
|
||||
#include "glthread.h"
|
||||
#ifndef MAPI_GLAPI_CURRENT
|
||||
#define MAPI_GLAPI_CURRENT
|
||||
#endif
|
||||
|
||||
|
||||
struct _glapi_table;
|
||||
|
||||
typedef void (*_glapi_proc)(void); /* generic function pointer */
|
||||
|
||||
|
||||
#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
|
||||
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()
|
||||
|
||||
/**
|
||||
** 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);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <dix-config.h>
|
||||
#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 <errno.h>
|
||||
|
||||
/*
|
||||
* 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
|
||||
unsigned long
|
||||
_glthread_GetID(void)
|
||||
{
|
||||
return (unsigned long) pthread_self();
|
||||
return u_thread_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
|
||||
_glthread_GetID(void)
|
||||
{
|
||||
return (unsigned long) find_thread(NULL);
|
||||
}
|
||||
|
||||
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 */
|
||||
|
|
|
@ -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
|
||||
#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)
|
||||
|
||||
#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);
|
||||
|
||||
/*
|
||||
* 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 <pthread.h> /* POSIX threads headers */
|
||||
typedef struct u_tsd _glthread_TSD;
|
||||
typedef u_mutex _glthread_Mutex;
|
||||
|
||||
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 <windows.h>
|
||||
|
||||
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 <kernel/OS.h>
|
||||
#endif
|
||||
|
||||
#include <support/TLS.h>
|
||||
|
||||
/* 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
|
||||
|
||||
typedef struct {
|
||||
int32 key;
|
||||
int initMagic;
|
||||
} _glthread_TSD;
|
||||
|
||||
typedef thread_id _glthread_Thread;
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# src/mapi/mapi/sources.mak
|
||||
|
||||
MAPI_GLAPI_SOURCES = \
|
||||
u_current.c \
|
||||
u_execmem.c \
|
||||
u_thread.c
|
|
@ -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_ */
|
|
@ -48,22 +48,24 @@
|
|||
* 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 <dix-config.h>
|
||||
#include "glapi/mesa.h"
|
||||
#else
|
||||
#include "main/glheader.h"
|
||||
#include "main/compiler.h"
|
||||
|
||||
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
|
||||
|
||||
#include "glapi/glapi.h"
|
||||
#include "glapi/glapi_priv.h"
|
||||
|
||||
extern _glapi_proc __glapi_noop_table[];
|
||||
|
||||
|
||||
/**
|
||||
* \name Current dispatch and current context control variables
|
||||
*
|
||||
|
@ -97,56 +99,51 @@ 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)
|
||||
struct _glapi_table *_glapi_Dispatch =
|
||||
(struct _glapi_table *) table_noop_array;
|
||||
void *_glapi_Context;
|
||||
|
||||
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;
|
||||
#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)
|
||||
{
|
||||
_glthread_InitTSD(&_gl_DispatchTSD);
|
||||
_glthread_InitTSD(&ContextTSD);
|
||||
}
|
||||
|
||||
void
|
||||
_glapi_destroy_multithread(void)
|
||||
{
|
||||
#ifdef WIN32_THREADS
|
||||
_glthread_DestroyTSD(&_gl_DispatchTSD);
|
||||
_glthread_DestroyTSD(&ContextTSD);
|
||||
#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.
|
||||
*/
|
||||
|
@ -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
|
|
@ -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 */
|
|
@ -32,15 +32,9 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#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);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _U_EXECMEM_H_
|
||||
#define _U_EXECMEM_H_
|
||||
|
||||
void *
|
||||
u_execmem_alloc(unsigned int size);
|
||||
|
||||
#endif /* _U_EXECMEM_H_ */
|
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#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 <errno.h>
|
||||
|
||||
/*
|
||||
* 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 */
|
|
@ -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 <pthread.h> /* 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 <windows.h>
|
||||
|
||||
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 <kernel/OS.h>
|
||||
#endif
|
||||
|
||||
#include <support/TLS.h>
|
||||
|
||||
/* 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_ */
|
Loading…
Reference in New Issue