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.st...@acm.org) (jo...@cs.umr.edu) + * and Christoph Poliwoda (poliw...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev