1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "ThreadInfo.h"
17 #include "cutils/threads.h"
18 
19 #ifdef __BIONIC__
20 #include <bionic/tls.h>
21 #endif
22 
23 #ifdef __ANDROID__
24 // Are we missing an actual set of TLS defs?
25 #ifdef GOLDFISH_OPENGL_NO_PLATFORM_BIONIC_INCLUDES
26 #include <bionic_tls.h>
27 #endif
28 #endif
29 
30 #include <pthread.h>
31 
32 thread_store_t s_tls = THREAD_STORE_INITIALIZER;
33 
sDefaultTlsDestructorCallback(void * ptr)34 static bool sDefaultTlsDestructorCallback(__attribute__((__unused__)) void* ptr) {
35   return true;
36 }
37 static bool (*sTlsDestructorCallback)(void*) = sDefaultTlsDestructorCallback;
38 
tlsDestruct(void * ptr)39 static void tlsDestruct(void *ptr)
40 {
41     sTlsDestructorCallback(ptr);
42     if (ptr
43 #ifdef __ANDROID__
44          && ((void **)__get_tls())[TLS_SLOT_OPENGL]
45 #endif
46         ) {
47         EGLThreadInfo *ti = (EGLThreadInfo *)ptr;
48         delete ti;
49 #ifdef __ANDROID__
50         ((void **)__get_tls())[TLS_SLOT_OPENGL] = NULL;
51 #endif
52     }
53 }
54 
setTlsDestructor(tlsDtorCallback func)55 void setTlsDestructor(tlsDtorCallback func) {
56     sTlsDestructorCallback = func;
57 }
58 
goldfish_get_egl_tls()59 EGLThreadInfo *goldfish_get_egl_tls()
60 {
61     EGLThreadInfo* ti = (EGLThreadInfo*)thread_store_get(&s_tls);
62 
63     if (ti) return ti;
64 
65     ti = new EGLThreadInfo();
66     thread_store_set(&s_tls, ti, tlsDestruct);
67 
68     return ti;
69 }
70 
getEGLThreadInfo()71 EGLThreadInfo* getEGLThreadInfo() {
72 #ifdef __ANDROID__
73     EGLThreadInfo *tInfo =
74         (EGLThreadInfo *)(((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL]);
75     if (!tInfo) {
76         tInfo = goldfish_get_egl_tls();
77         ((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL] = (uintptr_t)tInfo;
78     }
79     return tInfo;
80 #else
81     return goldfish_get_egl_tls();
82 #endif
83 }
84 
getCurrentThreadId()85 int32_t getCurrentThreadId() {
86     return (int32_t)gettid();
87 }
88