added support for XFree86 threads. misc clean-up

This commit is contained in:
Brian Paul
2000-02-10 21:27:25 +00:00
parent 577c67e860
commit a9601f1b4c
2 changed files with 151 additions and 43 deletions
+77 -25
View File
@@ -1,4 +1,4 @@
/* $Id: glthread.c,v 1.3 2000/01/28 18:57:56 brianp Exp $ */
/* $Id: glthread.c,v 1.4 2000/02/10 21:27:25 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -26,14 +26,6 @@
/*
* 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
*
* 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.
*/
@@ -65,10 +57,11 @@
/*
* magic number for win32 and solaris threads equivalents of pthread_once
* This could probably be done better, but we haven't figured out how yet.
* 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 INITFUNC_CALLED_MAGIC 0xff8adc98
#define INIT_MAGIC 0xff8adc98
@@ -95,20 +88,26 @@ _glthread_InitTSD(_glthread_TSD *tsd)
perror(INIT_TSD_ERROR);
exit(-1);
}
tsd->initMagic = INIT_MAGIC;
}
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
return pthread_getspecific(tsd->key);
}
void
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr, void (*initfunc)(void))
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
pthread_once(&tsd->once, initfunc);
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
if (pthread_setspecific(tsd->key, ptr) != 0) {
perror(SET_TSD_ERROR);
exit(-1);
@@ -145,6 +144,7 @@ _glthread_InitTSD(_glthread_TSD *tsd)
perror(INIT_TSD_ERROR);
exit(-1);
}
tsd->initMagic = INIT_MAGIC;
}
@@ -152,6 +152,9 @@ void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
void* ret;
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
#ifdef USE_LOCK_FOR_KEY
mutex_lock(&tsd->keylock);
thr_getspecific(tsd->key, &ret);
@@ -167,14 +170,10 @@ _glthread_GetTSD(_glthread_TSD *tsd)
void
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr, void (*initfunc)(void))
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
/* the following code assumes that the _glthread_TSD has been initialized
to zero at creation */
fprintf(stderr, "initfuncCalled = %d\n", tsd->initfuncCalled);
if (tsd->initfuncCalled != INITFUNC_CALLED_MAGIC) {
initfunc();
tsd->initfuncCalled = INITFUNC_CALLED_MAGIC;
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
perror(SET_TSD_ERROR);
@@ -212,24 +211,27 @@ _glthread_InitTSD(_glthread_TSD *tsd)
/* perror(SET_INIT_ERROR);*/
exit(-1);
}
tsd->initMagic = INIT_MAGIC;
}
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, void (*initfunc)(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->initfuncCalled != INITFUNC_CALLED_MAGIC) {
initfunc();
tsd->initfuncCalled = INITFUNC_CALLED_MAGIC;
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
if (TlsSetValue(tsd->key, ptr) == 0) {
/* Can Windows handle stderr messages for non-console
@@ -241,6 +243,56 @@ _glthread_SetTSD(_glthread_TSD *tsd, void *ptr, void (*initfunc)(void))
#endif /* WIN32 */
/*
* XFree86 has its own thread wrapper, Xthreads.h
* We wrap it again for GL.
*/
#ifdef XTHREADS
unsigned long
_glthread_GetID(void)
{
return (unsigned long) xthread_self();
}
void
_glthread_InitTSD(_glthread_TSD *tsd)
{
if (xthread_key_create(&tsd->key, NULL) != 0) {
perror(INIT_TSD_ERROR);
exit(-1);
}
tsd->initMagic = INIT_MAGIC;
}
void *
_glthread_GetTSD(_glthread_TSD *tsd)
{
void *ptr;
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
xthread_get_specific(tsd->key, &ptr);
return ptr;
}
void
_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
{
if (tsd->initMagic != INIT_MAGIC) {
_glthread_InitTSD(tsd);
}
xthread_set_specific(tsd->key, ptr);
}
#endif /* XTHREAD */
#endif /* THREADS */
+74 -18
View File
@@ -1,10 +1,10 @@
/* $Id: glthread.h,v 1.2 2000/01/31 23:10:47 brianp Exp $ */
/* $Id: glthread.h,v 1.3 2000/02/10 21:27:25 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2000 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"),
@@ -32,8 +32,31 @@
* 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
*
*/
#ifndef GLTHREAD_H
#define GLTHREAD_H
@@ -47,8 +70,8 @@
/*
* It is an error not to select a specific threads API when compiling.
*/
#if !defined(PTHREADS) && !defined(SOLARIS_THREADS) && !defined(WIN32)
#error One of PTHREADS, SOLARIS_THREADS or WIN32 must be defined.
#if !defined(PTHREADS) && !defined(SOLARIS_THREADS) && !defined(WIN32) && !defined(XTHREADS)
#error One of PTHREADS, SOLARIS_THREADS, WIN32 or XTHREADS must be defined.
#endif
@@ -67,7 +90,7 @@
typedef struct {
pthread_key_t key;
pthread_once_t once;
int initMagic;
} _glthread_TSD;
typedef pthread_t _glthread_Thread;
@@ -103,7 +126,7 @@ typedef pthread_mutex_t _glthread_Mutex;
typedef struct {
thread_key_t key;
mutex_t keylock;
int initfuncCalled;
int initMagic;
} _glthread_TSD;
typedef thread_t _glthread_Thread;
@@ -126,13 +149,12 @@ typedef mutex_t _glthread_Mutex;
* IMPORTANT: Link with multithreaded runtime library when THREADS are
* used!
*/
#ifdef WIN32
#include <windows.h>
typedef struct {
DWORD key;
int initfuncCalled;
int initMagic;
} _glthread_TSD;
typedef HANDLE _glthread_Thread;
@@ -150,25 +172,35 @@ typedef CRITICAL_SECTION _glthread_Mutex;
/*
* Platform independent thread specific data API.
* XFree86 has its own thread wrapper, Xthreads.h
* We wrap it again for GL.
*/
#ifdef XTHREADS
#include "Xthreads.h"
extern unsigned long
_glthread_GetID(void);
typedef struct {
xthread_key_t key;
int initMagic;
} _glthread_TSD;
typedef xthread_t _glthread_Thread;
extern void
_glthread_InitTSD(_glthread_TSD *);
typedef xmutex_rec _glthread_Mutex;
#define _glthread_DECLARE_STATIC_MUTEX(name) \
static _glthread_Mutex name = XMUTEX_INITIALIZER
extern void *
_glthread_GetTSD(_glthread_TSD *);
#define _glthread_INIT_MUTEX(name) \
xmutex_init(&(name))
#define _glthread_LOCK_MUTEX(name) \
(void) xmutex_lock(&(name))
extern void
_glthread_SetTSD(_glthread_TSD *, void *, void (*initfunc)(void));
#define _glthread_UNLOCK_MUTEX(name) \
(void) xmutex_unlock(&(name))
#endif /* XTHREADS */
@@ -196,5 +228,29 @@ typedef GLuint _glthread_Mutex;
#endif /* THREADS */
/*
* Platform independent thread specific data API.
*/
extern unsigned long
_glthread_GetID(void);
extern void
_glthread_InitTSD(_glthread_TSD *);
extern void *
_glthread_GetTSD(_glthread_TSD *);
extern void
_glthread_SetTSD(_glthread_TSD *, void *);
#endif /* THREADS_H */