added support for XFree86 threads. misc clean-up
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 10 Feb 2000 21:27:25 +0000 (21:27 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 10 Feb 2000 21:27:25 +0000 (21:27 +0000)
src/mesa/glapi/glthread.c
src/mesa/glapi/glthread.h

index e7cc8d8d4892b9d698d7b2f6f9afc74e6d58430f..ad6380328df97c91eabe4a5cf1cdd1eca1476690 100644 (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
 
 
 /*
- * 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.
  */
 
 
 /*
- * 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 */
 
 
index 600a7616823cd930376b8ca08c290e6086aaeca2..72fe08ff7f9c0db72b06bdffc7643f7706b887e2 100644 (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"),
  *                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 */