xref: /aosp_15_r20/external/angle/src/common/tls.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // tls.h: Simple cross-platform interface for thread local storage.
8 
9 #ifndef COMMON_TLS_H_
10 #define COMMON_TLS_H_
11 
12 #include "common/angleutils.h"
13 #include "common/platform.h"
14 
15 #if defined(ANGLE_PLATFORM_POSIX)
16 #    include <errno.h>
17 #    include <pthread.h>
18 #    include <semaphore.h>
19 #elif defined(ANGLE_PLATFORM_WINDOWS)
20 #    include <windows.h>
21 #endif
22 
23 namespace gl
24 {
25 class Context;
26 }
27 
28 namespace angle
29 {
30 
31 #ifdef ANGLE_PLATFORM_WINDOWS
32 // TLS does not exist for Windows Store and needs to be emulated
33 #    ifdef ANGLE_ENABLE_WINDOWS_UWP
34 #        ifndef TLS_OUT_OF_INDEXES
35 #            define TLS_OUT_OF_INDEXES static_cast<DWORD>(0xFFFFFFFF)
36 #        endif
37 #        ifndef CREATE_SUSPENDED
38 #            define CREATE_SUSPENDED 0x00000004
39 #        endif
40 #    endif
41 typedef DWORD TLSIndex;
42 #    define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
43 #elif defined(ANGLE_PLATFORM_POSIX)
44 typedef pthread_key_t TLSIndex;
45 #    define TLS_INVALID_INDEX (static_cast<angle::TLSIndex>(-1))
46 #else
47 #    error Unsupported platform.
48 #endif
49 
50 #if defined(ANGLE_USE_ANDROID_TLS_SLOT)
51 
52 // TLS_SLOT_OPENGL and TLS_SLOT_OPENGL_API aren't used by bionic itself, but allow the graphics code
53 // to access TLS directly rather than using the pthread API.
54 //
55 // Choose the TLS_SLOT_OPENGL TLS slot with the value that matches value in the header file in
56 // bionic(tls_defines.h).  Note that this slot cannot be used when the GLES backend of is in use.
57 #    if defined(__arm__) || defined(__aarch64__)
58 constexpr size_t kAndroidOpenGLTlsSlot = 3;
59 #    elif defined(__i386__) || defined(__x86_64__)
60 constexpr size_t kAndroidOpenGLTlsSlot = 3;
61 #    elif defined(__riscv)
62 constexpr int kAndroidOpenGLTlsSlot = -5;
63 #    else
64 #        error Unsupported platform.
65 #    endif
66 
67 // The following ASM variant provides a much more performant store/retrieve interface
68 // compared to those provided by the pthread library. These have been derived from code
69 // in the bionic module of Android ->
70 // https://cs.android.com/android/platform/superproject/+/master:bionic/libc/platform/bionic/tls.h;l=30
71 
72 #    if defined(__aarch64__)
73 #        define ANGLE_ANDROID_GET_GL_TLS()                  \
74             ({                                              \
75                 void **__val;                               \
76                 __asm__("mrs %0, tpidr_el0" : "=r"(__val)); \
77                 __val;                                      \
78             })
79 #    elif defined(__arm__)
80 #        define ANGLE_ANDROID_GET_GL_TLS()                           \
81             ({                                                       \
82                 void **__val;                                        \
83                 __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__val)); \
84                 __val;                                               \
85             })
86 #    elif defined(__mips__)
87 // On mips32r1, this goes via a kernel illegal instruction trap that's
88 // optimized for v1
89 #        define ANGLE_ANDROID_GET_GL_TLS()       \
90             ({                                   \
91                 register void **__val asm("v1"); \
92                 __asm__(                         \
93                     ".set    push\n"             \
94                     ".set    mips32r2\n"         \
95                     "rdhwr   %0,$29\n"           \
96                     ".set    pop\n"              \
97                     : "=r"(__val));              \
98                 __val;                           \
99             })
100 #    elif defined(__i386__)
101 #        define ANGLE_ANDROID_GET_GL_TLS()                \
102             ({                                            \
103                 void **__val;                             \
104                 __asm__("movl %%gs:0, %0" : "=r"(__val)); \
105                 __val;                                    \
106             })
107 #    elif defined(__x86_64__)
108 #        define ANGLE_ANDROID_GET_GL_TLS()               \
109             ({                                           \
110                 void **__val;                            \
111                 __asm__("mov %%fs:0, %0" : "=r"(__val)); \
112                 __val;                                   \
113             })
114 #    elif defined(__riscv)
115 #        define ANGLE_ANDROID_GET_GL_TLS()          \
116             ({                                      \
117                 void **__val;                       \
118                 __asm__("mv %0, tp" : "=r"(__val)); \
119                 __val;                              \
120             })
121 #    else
122 #        error unsupported architecture
123 #    endif
124 
125 #endif  // ANGLE_USE_ANDROID_TLS_SLOT
126 
127 using PthreadKeyDestructor = void (*)(void *);
128 TLSIndex CreateTLSIndex(PthreadKeyDestructor destructor);
129 bool DestroyTLSIndex(TLSIndex index);
130 
131 bool SetTLSValue(TLSIndex index, void *value);
132 void *GetTLSValue(TLSIndex index);
133 
134 }  // namespace angle
135 
136 #endif  // COMMON_TLS_H_
137