diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-07 20:23:27 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-07 20:23:27 +0000 |
commit | 48ca7e37ef684dea5271b8d779c1ccc66b9bf275 (patch) | |
tree | 07a773345b52afd038bc3f6ae51aeafb2358919c /src/ports | |
parent | 82d447d4f193f10a5ea77a0bcb5737fc35fb340d (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.cpp | 11 | ||||
-rw-r--r-- | src/ports/SkThread_pthread.cpp | 102 | ||||
-rw-r--r-- | src/ports/SkThread_win.cpp | 21 |
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); +} + |