[Mesa-dev] [RFC 1/2] Revert "mapi: rewrite u_current_init() function without u_thread_self()"

Timothy Arceri tarceri at itsqueeze.com
Wed Apr 19 07:45:49 UTC 2017


This reverts commit 458c7490c29ef2960a33a089f65490e044da5d27.

The commit did not revert cleanly so this was fixed up by hand.

u_thread_self() will be used by the following patch.
---
 src/mapi/u_current.c |  44 +--------------
 src/mapi/u_current.h |  18 ++++++
 src/mapi/u_thread.h  | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 177 insertions(+), 41 deletions(-)
 create mode 100644 src/mapi/u_thread.h

diff --git a/src/mapi/u_current.c b/src/mapi/u_current.c
index 7e7e275..cac44e4 100644
--- a/src/mapi/u_current.c
+++ b/src/mapi/u_current.c
@@ -41,21 +41,20 @@
  *   2000/02/23  - original version for Mesa 3.3 and XFree86 4.0
  *   2001/01/16  - added dispatch override feature for Mesa 3.5
  *   2002/06/28  - added _glapi_set_warning_func(), Mesa 4.1.
  *   2002/10/01  - _glapi_get_proc_address() will now generate new entrypoints
  *                 itself (using offset ~0).  _glapi_add_entrypoint() can be
  *                 called afterward and it'll fill in the correct dispatch
  *                 offset.  This allows DRI libGL to avoid probing for DRI
  *                 drivers!  No changes to the public glapi interface.
  */
 
-#include "c11/threads.h"
 #include "u_current.h"
 
 #ifndef MAPI_MODE_UTIL
 
 #include "table.h"
 #include "stub.h"
 
 #else
 
 extern void init_glapi_relocs_once(void);
@@ -137,78 +136,41 @@ u_current_init_tsd(void)
 {
    tss_create(&u_current_table_tsd, NULL);
    tss_create(&u_current_context_tsd, NULL);
 }
 
 /**
  * Mutex for multithread check.
  */
 static mtx_t ThreadCheckMutex = _MTX_INITIALIZER_NP;
 
-
-#ifdef _WIN32
-typedef DWORD thread_id;
-#else
-typedef thrd_t thread_id;
-#endif
-
-
-static inline thread_id
-get_thread_id(void)
-{
-   /*
-    * XXX: Callers of of this function assume it is a lightweight function.
-    * But unfortunately C11's thrd_current() gives no such guarantees.  In
-    * fact, it's pretty hard to have a compliant implementation of
-    * thrd_current() on Windows with such characteristics.  So for now, we
-    * side-step this mess and use Windows thread primitives directly here.
-    */
-#ifdef _WIN32
-   return GetCurrentThreadId();
-#else
-   return thrd_current();
-#endif
-}
-
-
-static inline int
-thread_id_equal(thread_id t1, thread_id t2)
-{
-#ifdef _WIN32
-   return t1 == t2;
-#else
-   return thrd_equal(t1, t2);
-#endif
-}
-
-
 /**
  * We should call this periodically from a function such as glXMakeCurrent
  * in order to test if multiple threads are being used.
  */
 void
 u_current_init(void)
 {
-   static thread_id knownID;
+   static unsigned long knownID;
    static int firstCall = 1;
 
    if (ThreadSafe)
       return;
 
    mtx_lock(&ThreadCheckMutex);
    if (firstCall) {
       u_current_init_tsd();
 
-      knownID = get_thread_id();
+      knownID = u_thread_self();
       firstCall = 0;
    }
-   else if (!thread_id_equal(knownID, get_thread_id())) {
+   else if (knownID != u_thread_self()) {
       ThreadSafe = 1;
       u_current_set_table(NULL);
       u_current_set_context(NULL);
    }
    mtx_unlock(&ThreadCheckMutex);
 }
 
 #else
 
 void
diff --git a/src/mapi/u_current.h b/src/mapi/u_current.h
index ea4f817..ce1d9a6 100644
--- a/src/mapi/u_current.h
+++ b/src/mapi/u_current.h
@@ -1,13 +1,14 @@
 #ifndef _U_CURRENT_H_
 #define _U_CURRENT_H_
 
+#include "c11/threads.h"
 #include "c99_compat.h"
 #include "util/macros.h"
 
 
 #if defined(MAPI_MODE_UTIL) || defined(MAPI_MODE_GLAPI) || \
     defined(MAPI_MODE_BRIDGE)
 
 #include "glapi/glapi.h"
 
 /* ugly renames to match glapi.h */
@@ -46,20 +47,37 @@ extern void *u_current_context;
 #endif /* GLX_USE_TLS */
 
 #endif /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */
 
 void
 u_current_init(void);
 
 void
 u_current_destroy(void);
 
+static inline unsigned long
+u_thread_self(void)
+{
+   /*
+    * XXX: Callers of of this function assume it is a lightweight function.
+    * But unfortunately C11's thrd_current() gives no such guarantees.  In
+    * fact, it's pretty hard to have a compliant implementation of
+    * thrd_current() on Windows with such characteristics.  So for now, we
+    * side-step this mess and use Windows thread primitives directly here.
+    */
+#ifdef _WIN32
+   return GetCurrentThreadId();
+#else
+   return (unsigned long) (uintptr_t) thrd_current();
+#endif
+}
+
 void
 u_current_set_table(const struct mapi_table *tbl);
 
 struct mapi_table *
 u_current_get_table_internal(void);
 
 void
 u_current_set_context(const void *ptr);
 
 void *
diff --git a/src/mapi/u_thread.h b/src/mapi/u_thread.h
new file mode 100644
index 0000000..4dd9515
--- /dev/null
+++ b/src/mapi/u_thread.h
@@ -0,0 +1,156 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 at acm.org) (johns at cs.umr.edu)
+ *                and Christoph Poliwoda (poliwoda at 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 <stdio.h>
+#include <stdlib.h>
+#include "c99_compat.h"
+
+#include "c11/threads.h"
+
+#if defined(HAVE_PTHREAD) || defined(_WIN32)
+#ifndef THREADS
+#define THREADS
+#endif
+#endif
+
+/*
+ * Error messages
+ */
+#define INIT_TSD_ERROR "Mesa: failed to allocate key for thread specific data"
+#define GET_TSD_ERROR "Mesa: failed to get thread specific data"
+#define SET_TSD_ERROR "Mesa: 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
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct u_tsd {
+   tss_t key;
+   unsigned initMagic;
+};
+
+
+static inline unsigned long
+u_thread_self(void)
+{
+   /*
+    * XXX: Callers of u_thread_self assume it is a lightweight function,
+    * returning a numeric value.  But unfortunately C11's thrd_current() gives
+    * no such guarantees.  In fact, it's pretty hard to have a compliant
+    * implementation of thrd_current() on Windows with such characteristics.
+    * So for now, we side-step this mess and use Windows thread primitives
+    * directly here.
+    *
+    * FIXME: On the other hand, u_thread_self() is a bad
+    * abstraction.  Even with pthreads, there is no guarantee that
+    * pthread_self() will return numeric IDs -- we should be using
+    * pthread_equal() instead of assuming we can compare thread ids...
+    */
+#ifdef _WIN32
+   return GetCurrentThreadId();
+#else
+   return (unsigned long) (uintptr_t) thrd_current();
+#endif
+}
+
+
+static inline void
+u_tsd_init(struct u_tsd *tsd)
+{
+   if (tss_create(&tsd->key, NULL/*free*/) != 0) {
+      perror(INIT_TSD_ERROR);
+      exit(-1);
+   }
+   tsd->initMagic = INIT_MAGIC;
+}
+
+
+static inline void *
+u_tsd_get(struct u_tsd *tsd)
+{
+   if (tsd->initMagic != INIT_MAGIC) {
+      u_tsd_init(tsd);
+   }
+   return tss_get(tsd->key);
+}
+
+
+static inline void
+u_tsd_set(struct u_tsd *tsd, void *ptr)
+{
+   if (tsd->initMagic != INIT_MAGIC) {
+      u_tsd_init(tsd);
+   }
+   if (tss_set(tsd->key, ptr) != 0) {
+      perror(SET_TSD_ERROR);
+      exit(-1);
+   }
+}
+
+
+static inline void
+u_tsd_destroy(struct u_tsd *tsd)
+{
+   if (tsd->initMagic != INIT_MAGIC) {
+      return;
+   }
+   tss_delete(tsd->key);
+   tsd->initMagic = 0x0;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _U_THREAD_H_ */
-- 
2.9.3



More information about the mesa-dev mailing list