diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkSemaphore.cpp | 49 | ||||
-rw-r--r-- | src/lazy/SkDiscardableMemoryPool.cpp | 13 | ||||
-rw-r--r-- | src/lazy/SkDiscardableMemoryPool.h | 3 |
3 files changed, 47 insertions, 18 deletions
diff --git a/src/core/SkSemaphore.cpp b/src/core/SkSemaphore.cpp index 0646b152e8..da422e282f 100644 --- a/src/core/SkSemaphore.cpp +++ b/src/core/SkSemaphore.cpp @@ -9,7 +9,7 @@ #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) #include <mach/mach.h> - struct SkSemaphore::OSSemaphore { + struct SkBaseSemaphore::OSSemaphore { semaphore_t fSemaphore; OSSemaphore() { @@ -21,7 +21,7 @@ void wait() { semaphore_wait(fSemaphore); } }; #elif defined(SK_BUILD_FOR_WIN32) - struct SkSemaphore::OSSemaphore { + struct SkBaseSemaphore::OSSemaphore { HANDLE fSemaphore; OSSemaphore() { @@ -41,7 +41,7 @@ // It's important we test for Mach before this. This code will compile but not work there. #include <errno.h> #include <semaphore.h> - struct SkSemaphore::OSSemaphore { + struct SkBaseSemaphore::OSSemaphore { sem_t fSemaphore; OSSemaphore() { sem_init(&fSemaphore, 0/*cross process?*/, 0/*initial count*/); } @@ -57,16 +57,43 @@ /////////////////////////////////////////////////////////////////////////////// -void SkSemaphore::osSignal(int n) { - fOSSemaphoreOnce([this] { fOSSemaphore = new OSSemaphore; }); - fOSSemaphore->signal(n); +void SkBaseSemaphore::signal(int n) { + SkASSERT(n >= 0); + + // We only want to call the OS semaphore when our logical count crosses + // from <= 0 to >0 (when we need to wake sleeping threads). + // + // This is easiest to think about with specific examples of prev and n. + // If n == 5 and prev == -3, there are 3 threads sleeping and we signal + // SkTMin(-(-3), 5) == 3 times on the OS semaphore, leaving the count at 2. + // + // If prev >= 0, no threads are waiting, SkTMin(-prev, n) is always <= 0, + // so we don't call the OS semaphore, leaving the count at (prev + n). + int prev = sk_atomic_fetch_add(&fCount, n, sk_memory_order_release); + int toSignal = SkTMin(-prev, n); + if (toSignal > 0) { + this->osSignal(toSignal); + } } -void SkSemaphore::osWait() { - fOSSemaphoreOnce([this] { fOSSemaphore = new OSSemaphore; }); - fOSSemaphore->wait(); +static SkBaseSemaphore::OSSemaphore* semaphore(SkBaseSemaphore* semaphore) { + return semaphore->fOSSemaphore.get([](){ return new SkBaseSemaphore::OSSemaphore(); }); } -SkSemaphore::~SkSemaphore() { - delete fOSSemaphore; +void SkBaseSemaphore::osSignal(int n) { semaphore(this)->signal(n); } + +void SkBaseSemaphore::osWait() { semaphore(this)->wait(); } + +void SkBaseSemaphore::deleteSemaphore() { + delete (OSSemaphore*) fOSSemaphore; } + +/////////////////////////////////////////////////////////////////////////////// + +SkSemaphore::SkSemaphore(){ fBaseSemaphore = {0, {0}}; } + +SkSemaphore::~SkSemaphore() { fBaseSemaphore.deleteSemaphore(); } + +void SkSemaphore::wait() { fBaseSemaphore.wait(); } + +void SkSemaphore::signal(int n) {fBaseSemaphore.signal(n); } diff --git a/src/lazy/SkDiscardableMemoryPool.cpp b/src/lazy/SkDiscardableMemoryPool.cpp index 2be4c755f1..1f3bcf93e9 100644 --- a/src/lazy/SkDiscardableMemoryPool.cpp +++ b/src/lazy/SkDiscardableMemoryPool.cpp @@ -29,7 +29,7 @@ public: /** * Without mutex, will be not be thread safe. */ - DiscardableMemoryPool(size_t budget, SkMutex* mutex = nullptr); + DiscardableMemoryPool(size_t budget, SkBaseMutex* mutex = nullptr); virtual ~DiscardableMemoryPool(); SkDiscardableMemory* create(size_t bytes) override; @@ -52,9 +52,9 @@ public: #endif // SK_LAZY_CACHE_STATS private: - SkMutex* fMutex; - size_t fBudget; - size_t fUsed; + SkBaseMutex* fMutex; + size_t fBudget; + size_t fUsed; SkTInternalLList<PoolDiscardableMemory> fList; /** Function called to free memory if needed */ @@ -128,7 +128,8 @@ void PoolDiscardableMemory::unlock() { //////////////////////////////////////////////////////////////////////////////// -DiscardableMemoryPool::DiscardableMemoryPool(size_t budget, SkMutex* mutex) +DiscardableMemoryPool::DiscardableMemoryPool(size_t budget, + SkBaseMutex* mutex) : fMutex(mutex) , fBudget(budget) , fUsed(0) { @@ -240,7 +241,7 @@ void DiscardableMemoryPool::dumpPool() { } // namespace -SkDiscardableMemoryPool* SkDiscardableMemoryPool::Create(size_t size, SkMutex* mutex) { +SkDiscardableMemoryPool* SkDiscardableMemoryPool::Create(size_t size, SkBaseMutex* mutex) { return new DiscardableMemoryPool(size, mutex); } diff --git a/src/lazy/SkDiscardableMemoryPool.h b/src/lazy/SkDiscardableMemoryPool.h index ad8d796f66..92ba48bcb4 100644 --- a/src/lazy/SkDiscardableMemoryPool.h +++ b/src/lazy/SkDiscardableMemoryPool.h @@ -52,7 +52,8 @@ public: * the pool works. * Without mutex, will be not be thread safe. */ - static SkDiscardableMemoryPool* Create(size_t size, SkMutex* mutex = nullptr); + static SkDiscardableMemoryPool* Create( + size_t size, SkBaseMutex* mutex = nullptr); }; /** |