[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