1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkTLS.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,123 @@ 1.4 +#include "SkTLS.h" 1.5 + 1.6 +// enable to help debug TLS storage 1.7 +//#define SK_TRACE_TLS_LIFETIME 1.8 + 1.9 + 1.10 +#ifdef SK_TRACE_TLS_LIFETIME 1.11 + #include "SkThread.h" 1.12 + static int32_t gTLSRecCount; 1.13 +#endif 1.14 + 1.15 +struct SkTLSRec { 1.16 + SkTLSRec* fNext; 1.17 + void* fData; 1.18 + SkTLS::CreateProc fCreateProc; 1.19 + SkTLS::DeleteProc fDeleteProc; 1.20 + 1.21 +#ifdef SK_TRACE_TLS_LIFETIME 1.22 + SkTLSRec() { 1.23 + int n = sk_atomic_inc(&gTLSRecCount); 1.24 + SkDebugf(" SkTLSRec[%d]\n", n); 1.25 + } 1.26 +#endif 1.27 + 1.28 + ~SkTLSRec() { 1.29 + if (fDeleteProc) { 1.30 + fDeleteProc(fData); 1.31 + } 1.32 + // else we leak fData, or it will be managed by the caller 1.33 + 1.34 +#ifdef SK_TRACE_TLS_LIFETIME 1.35 + int n = sk_atomic_dec(&gTLSRecCount); 1.36 + SkDebugf("~SkTLSRec[%d]\n", n - 1); 1.37 +#endif 1.38 + } 1.39 +}; 1.40 + 1.41 +void SkTLS::Destructor(void* ptr) { 1.42 +#ifdef SK_TRACE_TLS_LIFETIME 1.43 + SkDebugf("SkTLS::Destructor(%p)\n", ptr); 1.44 +#endif 1.45 + 1.46 + SkTLSRec* rec = (SkTLSRec*)ptr; 1.47 + do { 1.48 + SkTLSRec* next = rec->fNext; 1.49 + SkDELETE(rec); 1.50 + rec = next; 1.51 + } while (NULL != rec); 1.52 +} 1.53 + 1.54 +void* SkTLS::Get(CreateProc createProc, DeleteProc deleteProc) { 1.55 + if (NULL == createProc) { 1.56 + return NULL; 1.57 + } 1.58 + 1.59 + void* ptr = SkTLS::PlatformGetSpecific(true); 1.60 + 1.61 + if (ptr) { 1.62 + const SkTLSRec* rec = (const SkTLSRec*)ptr; 1.63 + do { 1.64 + if (rec->fCreateProc == createProc) { 1.65 + SkASSERT(rec->fDeleteProc == deleteProc); 1.66 + return rec->fData; 1.67 + } 1.68 + } while ((rec = rec->fNext) != NULL); 1.69 + // not found, so create a new one 1.70 + } 1.71 + 1.72 + // add a new head of our change 1.73 + SkTLSRec* rec = new SkTLSRec; 1.74 + rec->fNext = (SkTLSRec*)ptr; 1.75 + 1.76 + SkTLS::PlatformSetSpecific(rec); 1.77 + 1.78 + rec->fData = createProc(); 1.79 + rec->fCreateProc = createProc; 1.80 + rec->fDeleteProc = deleteProc; 1.81 + return rec->fData; 1.82 +} 1.83 + 1.84 +void* SkTLS::Find(CreateProc createProc) { 1.85 + if (NULL == createProc) { 1.86 + return NULL; 1.87 + } 1.88 + 1.89 + void* ptr = SkTLS::PlatformGetSpecific(false); 1.90 + 1.91 + if (ptr) { 1.92 + const SkTLSRec* rec = (const SkTLSRec*)ptr; 1.93 + do { 1.94 + if (rec->fCreateProc == createProc) { 1.95 + return rec->fData; 1.96 + } 1.97 + } while ((rec = rec->fNext) != NULL); 1.98 + } 1.99 + return NULL; 1.100 +} 1.101 + 1.102 +void SkTLS::Delete(CreateProc createProc) { 1.103 + if (NULL == createProc) { 1.104 + return; 1.105 + } 1.106 + 1.107 + void* ptr = SkTLS::PlatformGetSpecific(false); 1.108 + 1.109 + SkTLSRec* curr = (SkTLSRec*)ptr; 1.110 + SkTLSRec* prev = NULL; 1.111 + while (curr) { 1.112 + SkTLSRec* next = curr->fNext; 1.113 + if (curr->fCreateProc == createProc) { 1.114 + if (prev) { 1.115 + prev->fNext = next; 1.116 + } else { 1.117 + // we have a new head of our chain 1.118 + SkTLS::PlatformSetSpecific(next); 1.119 + } 1.120 + SkDELETE(curr); 1.121 + break; 1.122 + } 1.123 + prev = curr; 1.124 + curr = next; 1.125 + } 1.126 +}