gfx/skia/trunk/src/core/SkTLS.cpp

changeset 0
6474c204b198
     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 +}

mercurial