From 48ca7e37ef684dea5271b8d779c1ccc66b9bf275 Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Mon, 7 May 2012 20:23:27 +0000 Subject: 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 --- src/ports/SkThread_none.cpp | 11 +++++ src/ports/SkThread_pthread.cpp | 102 ++--------------------------------------- src/ports/SkThread_win.cpp | 21 +++++++++ 3 files changed, 37 insertions(+), 97 deletions(-) (limited to 'src/ports') 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 #include #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(&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); +} + -- cgit v1.2.3