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@gmail.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10389>
This commit is contained in:
Emma Anholt
2021-05-21 13:23:07 -07:00
committed by Marge Bot
parent 4a68b16a52
commit 75a9cb1033
7 changed files with 28 additions and 25 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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;

View File

@@ -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

View File

@@ -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 */

View File

@@ -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)
{