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