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