OLD | NEW |
1 | |
2 /* | 1 /* |
3 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
4 * | 3 * |
5 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 5 * found in the LICENSE file. |
7 */ | 6 */ |
8 | 7 |
9 | |
10 #include <windows.h> | 8 #include <windows.h> |
11 #include <intrin.h> | 9 #include <intrin.h> |
12 #include "SkThread.h" | 10 #include "SkThread.h" |
13 #include "SkTLS.h" | |
14 | 11 |
15 //MSDN says in order to declare an interlocked function for use as an | 12 //MSDN says in order to declare an interlocked function for use as an |
16 //intrinsic, include intrin.h and put the function in a #pragma intrinsic | 13 //intrinsic, include intrin.h and put the function in a #pragma intrinsic |
17 //directive. | 14 //directive. |
18 //The pragma appears to be unnecessary, but doesn't hurt. | 15 //The pragma appears to be unnecessary, but doesn't hurt. |
19 #pragma intrinsic(_InterlockedIncrement, _InterlockedExchangeAdd, _InterlockedDe
crement) | 16 #pragma intrinsic(_InterlockedIncrement, _InterlockedExchangeAdd, _InterlockedDe
crement) |
20 #pragma intrinsic(_InterlockedCompareExchange) | 17 #pragma intrinsic(_InterlockedCompareExchange) |
21 | 18 |
22 int32_t sk_atomic_inc(int32_t* addr) { | 19 int32_t sk_atomic_inc(int32_t* addr) { |
23 // InterlockedIncrement returns the new value, we want to return the old. | 20 // InterlockedIncrement returns the new value, we want to return the old. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); | 56 DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); |
60 } | 57 } |
61 | 58 |
62 void SkMutex::acquire() { | 59 void SkMutex::acquire() { |
63 EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); | 60 EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); |
64 } | 61 } |
65 | 62 |
66 void SkMutex::release() { | 63 void SkMutex::release() { |
67 LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); | 64 LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage)); |
68 } | 65 } |
69 | |
70 /////////////////////////////////////////////////////////////////////////// | |
71 | |
72 static bool gOnce; | |
73 static DWORD gTlsIndex; | |
74 SK_DECLARE_STATIC_MUTEX(gMutex); | |
75 | |
76 void* SkTLS::PlatformGetSpecific(bool forceCreateTheSlot) { | |
77 if (!forceCreateTheSlot && !gOnce) { | |
78 return NULL; | |
79 } | |
80 | |
81 if (!gOnce) { | |
82 SkAutoMutexAcquire tmp(gMutex); | |
83 if (!gOnce) { | |
84 gTlsIndex = TlsAlloc(); | |
85 gOnce = true; | |
86 } | |
87 } | |
88 return TlsGetValue(gTlsIndex); | |
89 } | |
90 | |
91 void SkTLS::PlatformSetSpecific(void* ptr) { | |
92 SkASSERT(gOnce); | |
93 (void)TlsSetValue(gTlsIndex, ptr); | |
94 } | |
95 | |
96 // Call TLS destructors on thread exit. Code based on Chromium's | |
97 // base/threading/thread_local_storage_win.cc | |
98 #ifdef _WIN64 | |
99 | |
100 #pragma comment(linker, "/INCLUDE:_tls_used") | |
101 #pragma comment(linker, "/INCLUDE:skia_tls_callback") | |
102 | |
103 #else | |
104 | |
105 #pragma comment(linker, "/INCLUDE:__tls_used") | |
106 #pragma comment(linker, "/INCLUDE:_skia_tls_callback") | |
107 | |
108 #endif | |
109 | |
110 void NTAPI onTLSCallback(PVOID unused, DWORD reason, PVOID unused2) { | |
111 if ((DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason) && gOnce)
{ | |
112 void* ptr = TlsGetValue(gTlsIndex); | |
113 if (ptr != NULL) { | |
114 SkTLS::Destructor(ptr); | |
115 TlsSetValue(gTlsIndex, NULL); | |
116 } | |
117 } | |
118 } | |
119 | |
120 extern "C" { | |
121 | |
122 #ifdef _WIN64 | |
123 | |
124 #pragma const_seg(".CRT$XLB") | |
125 extern const PIMAGE_TLS_CALLBACK skia_tls_callback; | |
126 const PIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback; | |
127 #pragma const_seg() | |
128 | |
129 #else | |
130 | |
131 #pragma data_seg(".CRT$XLB") | |
132 PIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback; | |
133 #pragma data_seg() | |
134 | |
135 #endif | |
136 } | |
OLD | NEW |