Mesa (main): util: Add a helper macro for defining initial-exec variables.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jun 2 03:46:02 UTC 2021
Module: Mesa
Branch: main
Commit: 75a9cb1033a954a5a160335405a7627ae7c4aa66
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=75a9cb1033a954a5a160335405a7627ae7c4aa66
Author: Emma Anholt <emma at anholt.net>
Date: Fri May 21 13:23:07 2021 -0700
util: Add a helper macro for defining initial-exec variables.
I'm going to add another case for Android shortly, and then we can keep
the logic all in one spot.
Reviewed-by: Roman Stratiienko <r.stratiienko at gmail.com>
Reviewed-by: Emil Velikov <emil.l.velikov at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10389>
---
src/egl/main/eglcurrent.c | 4 ++--
src/glx/glxclient.h | 4 ++--
src/glx/glxcurrent.c | 3 +--
src/mapi/glapi/glapi.h | 7 +++----
src/mapi/u_current.c | 12 ++----------
src/mapi/u_current.h | 7 ++-----
src/util/u_thread.h | 16 ++++++++++++++++
7 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
index 29be4268025..11277d3e4c0 100644
--- a/src/egl/main/eglcurrent.c
+++ b/src/egl/main/eglcurrent.c
@@ -32,6 +32,7 @@
#include <stdarg.h>
#include "c99_compat.h"
#include "c11/threads.h"
+#include "util/u_thread.h"
#include "egllog.h"
#include "eglcurrent.h"
@@ -45,8 +46,7 @@ static tss_t _egl_TSD;
static void _eglDestroyThreadInfo(_EGLThreadInfo *t);
#ifdef USE_ELF_TLS
-static __thread const _EGLThreadInfo *_egl_TLS
- __attribute__ ((tls_model("initial-exec")));
+static __THREAD_INITIAL_EXEC const _EGLThreadInfo *_egl_TLS;
#endif
static inline void _eglSetTSD(const _EGLThreadInfo *t)
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index e335571b918..68df42f53b0 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -53,6 +53,7 @@
#include "glxconfig.h"
#include "glxhash.h"
#include "util/macros.h"
+#include "util/u_thread.h"
#include "loader.h"
#include "glxextensions.h"
@@ -645,8 +646,7 @@ extern void __glXSetCurrentContext(struct glx_context * c);
# if defined( USE_ELF_TLS )
-extern __thread void *__glX_tls_Context
- __attribute__ ((tls_model("initial-exec")));
+extern __THREAD_INITIAL_EXEC void *__glX_tls_Context;
# define __glXGetCurrentContext() __glX_tls_Context
diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c
index ee93114161c..ffc7c3c7687 100644
--- a/src/glx/glxcurrent.c
+++ b/src/glx/glxcurrent.c
@@ -76,8 +76,7 @@ _X_HIDDEN pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;
* \b never be \c NULL. This is important! Because of this
* \c __glXGetCurrentContext can be implemented as trivial macro.
*/
-__thread void *__glX_tls_Context __attribute__ ((tls_model("initial-exec")))
- = &dummyContext;
+__THREAD_INITIAL_EXEC void *__glX_tls_Context = &dummyContext;
_X_HIDDEN void
__glXSetCurrentContext(struct glx_context * c)
diff --git a/src/mapi/glapi/glapi.h b/src/mapi/glapi/glapi.h
index d6a0ebfcf8a..275bc1f3ddc 100644
--- a/src/mapi/glapi/glapi.h
+++ b/src/mapi/glapi/glapi.h
@@ -45,6 +45,7 @@
#define _GLAPI_H
#include "util/macros.h"
+#include "util/u_thread.h"
#ifdef __cplusplus
@@ -82,11 +83,9 @@ struct _glapi_table;
extern __declspec(thread) struct _glapi_table * _glapi_tls_Dispatch;
extern __declspec(thread) void * _glapi_tls_Context;
#else
-_GLAPI_EXPORT extern __thread struct _glapi_table * _glapi_tls_Dispatch
- __attribute__((tls_model("initial-exec")));
+_GLAPI_EXPORT extern __THREAD_INITIAL_EXEC struct _glapi_table * _glapi_tls_Dispatch;
-_GLAPI_EXPORT extern __thread void * _glapi_tls_Context
- __attribute__((tls_model("initial-exec")));
+_GLAPI_EXPORT extern __THREAD_INITIAL_EXEC void * _glapi_tls_Context;
#endif
_GLAPI_EXPORT extern const struct _glapi_table *_glapi_Dispatch;
diff --git a/src/mapi/u_current.c b/src/mapi/u_current.c
index 7a95e96f509..cd09140592e 100644
--- a/src/mapi/u_current.c
+++ b/src/mapi/u_current.c
@@ -100,18 +100,10 @@ extern void (*__glapi_noop_table[])(void);
/*@{*/
#if defined(USE_ELF_TLS)
-#ifdef _MSC_VER
-__declspec(thread) struct _glapi_table *u_current_table
- = (struct _glapi_table *) table_noop_array;
-__declspec(thread) void *u_current_context;
-#else
-__thread struct _glapi_table *u_current_table
- __attribute__((tls_model("initial-exec")))
+__THREAD_INITIAL_EXEC struct _glapi_table *u_current_table
= (struct _glapi_table *) table_noop_array;
-__thread void *u_current_context
- __attribute__((tls_model("initial-exec")));
-#endif
+__THREAD_INITIAL_EXEC void *u_current_context;
#else
diff --git a/src/mapi/u_current.h b/src/mapi/u_current.h
index e7faa878ed1..52da534797a 100644
--- a/src/mapi/u_current.h
+++ b/src/mapi/u_current.h
@@ -29,11 +29,8 @@ struct _glapi_table;
#ifdef USE_ELF_TLS
-extern __thread struct _glapi_table *u_current_table
- __attribute__((tls_model("initial-exec")));
-
-extern __thread void *u_current_context
- __attribute__((tls_model("initial-exec")));
+extern __THREAD_INITIAL_EXEC struct _glapi_table *u_current_table;
+extern __THREAD_INITIAL_EXEC void *u_current_context;
#else /* USE_ELF_TLS */
diff --git a/src/util/u_thread.h b/src/util/u_thread.h
index 5fd2fe502ee..e79d91ddff8 100644
--- a/src/util/u_thread.h
+++ b/src/util/u_thread.h
@@ -65,6 +65,22 @@
#define UTIL_MAX_CPUS 1024 /* this should be enough */
#define UTIL_MAX_L3_CACHES UTIL_MAX_CPUS
+/* Some highly performance-sensitive thread-local variables like the current GL
+ * context are declared with the initial-exec model on Linux. glibc allocates a
+ * fixed number of extra slots for initial-exec TLS variables at startup, and
+ * Mesa relies on (even if it's dlopen()ed after init) being able to fit into
+ * those. This model saves the call to look up the address of the TLS variable.
+ *
+ * However, if we don't have this TLS model available on the platform, then we
+ * still want to use normal TLS (which involves a function call, but not the
+ * expensive pthread_getspecific() or its equivalent).
+ */
+#ifdef _MSC_VER
+#define __THREAD_INITIAL_EXEC __declspec(thread)
+#else
+#define __THREAD_INITIAL_EXEC __thread __attribute__((tls_model("initial-exec")))
+#endif
+
static inline int
util_get_current_cpu(void)
{
More information about the mesa-commit
mailing list