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
23namespace gl
24{
25class Context;
26}
27
28namespace 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
41typedef DWORD TLSIndex;
42# define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
43#elif defined(ANGLE_PLATFORM_POSIX)
44typedef 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_PLATFORM_ANDROID)
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__)
58constexpr size_t kAndroidOpenGLTlsSlot = 3;
59# elif defined(__i386__) || defined(__x86_64__)
60constexpr size_t kAndroidOpenGLTlsSlot = 3;
61# elif defined(__riscv)
62constexpr 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_PLATFORM_ANDROID
126
127using PthreadKeyDestructor = void (*)(void *);
128TLSIndex CreateTLSIndex(PthreadKeyDestructor destructor);
129bool DestroyTLSIndex(TLSIndex index);
130
131bool SetTLSValue(TLSIndex index, void *value);
132void *GetTLSValue(TLSIndex index);
133
134} // namespace angle
135
136#endif // COMMON_TLS_H_
137

source code of flutter_engine/third_party/angle/src/common/tls.h