• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include "ThreadInfo.h"
18 
19 #ifdef HOST_BUILD
20 #include "android/base/threads/AndroidThread.h"
21 #else
22 #include "cutils/threads.h"
23 #endif
24 
25 #include <pthread.h>
26 
27 #if defined(HOST_BUILD) || defined(GFXSTREAM)
28 
29 static thread_local EGLThreadInfo sEglThreadInfoThreadLocal;
30 
goldfish_get_egl_tls()31 EGLThreadInfo *goldfish_get_egl_tls()
32 {
33     return &sEglThreadInfoThreadLocal;
34 }
35 
getEGLThreadInfo()36 EGLThreadInfo* getEGLThreadInfo() {
37     return goldfish_get_egl_tls();
38 }
39 
getCurrentThreadId()40 int32_t getCurrentThreadId() {
41 #ifdef HOST_BUILD
42     return (int32_t)android::base::guest::getCurrentThreadId();
43 #else
44     return (int32_t)gettid();
45 #endif
46 }
47 
setTlsDestructor(tlsDtorCallback func)48 void setTlsDestructor(tlsDtorCallback func) {
49     getEGLThreadInfo()->dtor = func;
50 }
51 
52 #else // GFXSTREAM
53 
54 #ifdef __BIONIC__
55 #include <bionic/tls.h>
56 #endif
57 
58 #ifdef __ANDROID__
59 // Are we missing an actual set of TLS defs?
60 #ifdef GOLDFISH_OPENGL_NO_PLATFORM_BIONIC_INCLUDES
61 #include <bionic_tls.h>
62 #endif
63 #endif
64 
sDefaultTlsDestructorCallback(void * ptr)65 static bool sDefaultTlsDestructorCallback(__attribute__((__unused__)) void* ptr) {
66   return true;
67 }
68 static bool (*sTlsDestructorCallback)(void*) = sDefaultTlsDestructorCallback;
69 
tlsDestruct(void * ptr)70 static void tlsDestruct(void *ptr)
71 {
72     sTlsDestructorCallback(ptr);
73     if (ptr
74 #ifdef __ANDROID__
75          && ((void **)__get_tls())[TLS_SLOT_OPENGL]
76 #endif
77         ) {
78         EGLThreadInfo *ti = (EGLThreadInfo *)ptr;
79         delete ti;
80 #ifdef __ANDROID__
81         ((void **)__get_tls())[TLS_SLOT_OPENGL] = NULL;
82 #endif
83     }
84 }
85 
setTlsDestructor(tlsDtorCallback func)86 void setTlsDestructor(tlsDtorCallback func) {
87     sTlsDestructorCallback = func;
88 }
89 
90 static pthread_key_t s_tls;
91 
init_key()92 static void init_key()
93 {
94     pthread_key_create(&s_tls, tlsDestruct);
95     pthread_setspecific(s_tls, new EGLThreadInfo);
96 }
97 
goldfish_get_egl_tls()98 EGLThreadInfo *goldfish_get_egl_tls()
99 {
100    static pthread_once_t once = PTHREAD_ONCE_INIT;
101    pthread_once(&once, init_key);
102 
103    return (EGLThreadInfo *) pthread_getspecific(s_tls);
104 }
105 
getEGLThreadInfo()106 EGLThreadInfo* getEGLThreadInfo() {
107 #ifdef __ANDROID__
108     EGLThreadInfo *tInfo =
109         (EGLThreadInfo *)(((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL]);
110     if (!tInfo) {
111         tInfo = goldfish_get_egl_tls();
112         ((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL] = (uintptr_t)tInfo;
113     }
114     return tInfo;
115 #else
116     return goldfish_get_egl_tls();
117 #endif
118 }
119 
getCurrentThreadId()120 int32_t getCurrentThreadId() {
121     return (int32_t)gettid();
122 }
123 
124 #endif // !GFXSTREAM
125