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