aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-07 20:23:27 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-07 20:23:27 +0000
commit48ca7e37ef684dea5271b8d779c1ccc66b9bf275 (patch)
tree07a773345b52afd038bc3f6ae51aeafb2358919c /src/ports
parent82d447d4f193f10a5ea77a0bcb5737fc35fb340d (diff)
impl SkTLS for windows, refactoring to share code with pthread impl
git-svn-id: http://skia.googlecode.com/svn/trunk@3859 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/ports')
-rw-r--r--src/ports/SkThread_none.cpp11
-rw-r--r--src/ports/SkThread_pthread.cpp102
-rw-r--r--src/ports/SkThread_win.cpp21
3 files changed, 37 insertions, 97 deletions
diff --git a/src/ports/SkThread_none.cpp b/src/ports/SkThread_none.cpp
index 8361021059..8341d0bfe5 100644
--- a/src/ports/SkThread_none.cpp
+++ b/src/ports/SkThread_none.cpp
@@ -29,3 +29,14 @@ void SkMutex::acquire() {}
void SkMutex::release() {}
+//////////////////////////////////////////////////////////////////////////
+
+static void* gSpecific;
+
+void* SkTLS::PlatformGetSpecific() {
+ return gSpecific;
+}
+
+void SkTLS::PlatformSetSpecific(void* ptr) {
+ gSpecific = ptr;
+}
diff --git a/src/ports/SkThread_pthread.cpp b/src/ports/SkThread_pthread.cpp
index c743d6ea82..b724c5126b 100644
--- a/src/ports/SkThread_pthread.cpp
+++ b/src/ports/SkThread_pthread.cpp
@@ -152,111 +152,19 @@ void SkMutex::release() {
///////////////////////////////////////////////////////////////////////////////
-#include "SkTLS.h"
-
-struct SkTLSRec {
- SkTLSRec* fNext;
- void* fData;
- SkTLS::CreateProc fCreateProc;
- SkTLS::DeleteProc fDeleteProc;
-
- ~SkTLSRec() {
- if (fDeleteProc) {
- fDeleteProc(fData);
- }
- // else we leak fData, or it will be managed by the caller
- }
-};
-
-static void sk_tls_destructor(void* ptr) {
- SkTLSRec* rec = (SkTLSRec*)ptr;
- do {
- SkTLSRec* next = rec->fNext;
- SkDELETE(rec);
- rec = next;
- } while (NULL != rec);
-}
-
static pthread_key_t gSkTLSKey;
static pthread_once_t gSkTLSKey_Once = PTHREAD_ONCE_INIT;
static void sk_tls_make_key() {
- (void)pthread_key_create(&gSkTLSKey, sk_tls_destructor);
-}
-
-void* SkTLS::Get(CreateProc createProc, DeleteProc deleteProc) {
- if (NULL == createProc) {
- return NULL;
- }
-
- (void)pthread_once(&gSkTLSKey_Once, sk_tls_make_key);
- void* ptr = pthread_getspecific(gSkTLSKey);
-
- if (ptr) {
- const SkTLSRec* rec = (const SkTLSRec*)ptr;
- do {
- if (rec->fCreateProc == createProc) {
- SkASSERT(rec->fDeleteProc == deleteProc);
- return rec->fData;
- }
- } while ((rec = rec->fNext) != NULL);
- // not found, so create a new one
- }
-
- // add a new head of our change
- SkTLSRec* rec = new SkTLSRec;
- rec->fNext = (SkTLSRec*)ptr;
- (void)pthread_setspecific(gSkTLSKey, rec);
-
- rec->fData = createProc();
- rec->fCreateProc = createProc;
- rec->fDeleteProc = deleteProc;
- return rec->fData;
+ (void)pthread_key_create(&gSkTLSKey, SkTLS::Destructor);
}
-void* SkTLS::Find(CreateProc createProc) {
- if (NULL == createProc) {
- return NULL;
- }
-
+void* SkTLS::PlatformGetSpecific() {
(void)pthread_once(&gSkTLSKey_Once, sk_tls_make_key);
- void* ptr = pthread_getspecific(gSkTLSKey);
-
- if (ptr) {
- const SkTLSRec* rec = (const SkTLSRec*)ptr;
- do {
- if (rec->fCreateProc == createProc) {
- return rec->fData;
- }
- } while ((rec = rec->fNext) != NULL);
- }
- return NULL;
+ return pthread_getspecific(gSkTLSKey);
}
-void SkTLS::Delete(CreateProc createProc) {
- if (NULL == createProc) {
- return;
- }
-
- (void)pthread_once(&gSkTLSKey_Once, sk_tls_make_key);
- void* ptr = pthread_getspecific(gSkTLSKey);
-
- SkTLSRec* curr = (SkTLSRec*)ptr;
- SkTLSRec* prev = NULL;
- while (curr) {
- SkTLSRec* next = curr->fNext;
- if (curr->fCreateProc == createProc) {
- if (prev) {
- prev->fNext = next;
- } else {
- // we have a new head of our chain
- (void)pthread_setspecific(gSkTLSKey, next);
- }
- SkDELETE(curr);
- break;
- }
- prev = curr;
- curr = next;
- }
+void SkTLS::PlatformSetSpecific(void* ptr) {
+ (void)pthread_setspecific(gSkTLSKey, ptr);
}
diff --git a/src/ports/SkThread_win.cpp b/src/ports/SkThread_win.cpp
index 70b8e11122..0d9ecab4bd 100644
--- a/src/ports/SkThread_win.cpp
+++ b/src/ports/SkThread_win.cpp
@@ -10,6 +10,7 @@
#include <windows.h>
#include <intrin.h>
#include "SkThread.h"
+#include "SkTLS.h"
//MSDN says in order to declare an interlocked function for use as an
//intrinsic, include intrin.h and put the function in a #pragma intrinsic
@@ -44,3 +45,23 @@ void SkMutex::release() {
LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&fStorage));
}
+///////////////////////////////////////////////////////////////////////////
+
+static bool gOnce;
+static DWORD gTlsIndex;
+SK_DECLARE_STATIC_MUTEX(gMutex);
+
+void* SkTLS::PlatformGetSpecific() {
+ if (!gOnce) {
+ SkAutoMutexAcquire tmp(gMutex);
+ gTlsIndex = TlsAlloc();
+ gOnce = true;
+ }
+ return TlsGetValue(gTlsIndex);
+}
+
+void SkTLS::PlatformSetSpecific(void* ptr) {
+ SkASSERT(gOnce);
+ (void)TlsSetValue(gTlsIndex, ptr);
+}
+