blob: 3c14b54d0a26c0df4a48b4bbf02defed935d1cdb [file] [log] [blame]
John Stiles5c7bb322020-10-22 11:09:15 -04001/*
2 * Copyright 2020 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/sksl/SkSLPool.h"
9
Ethan Nicholas7b776b52020-12-01 13:38:32 -050010#include "src/sksl/SkSLDefines.h"
11
John Stiles5c7bb322020-10-22 11:09:15 -040012#define VLOG(...) // printf(__VA_ARGS__)
13
14namespace SkSL {
15
Ethan Nicholas7b776b52020-12-01 13:38:32 -050016#if SKSL_USE_THREAD_LOCAL
17
18static thread_local MemoryPool* sMemPool = nullptr;
19
20static MemoryPool* get_thread_local_memory_pool() {
21 return sMemPool;
22}
23
24static void set_thread_local_memory_pool(MemoryPool* memPool) {
25 sMemPool = memPool;
26}
27
28#else
John Stiles0bb9ec52020-10-22 11:35:18 -040029
30#include <pthread.h>
31
32static pthread_key_t get_pthread_key() {
33 static pthread_key_t sKey = []{
34 pthread_key_t key;
35 int result = pthread_key_create(&key, /*destructor=*/nullptr);
36 if (result != 0) {
37 SK_ABORT("pthread_key_create failure: %d", result);
38 }
39 return key;
40 }();
41 return sKey;
42}
43
John Stiles23e68662020-10-29 10:17:15 -040044static MemoryPool* get_thread_local_memory_pool() {
45 return static_cast<MemoryPool*>(pthread_getspecific(get_pthread_key()));
John Stiles0bb9ec52020-10-22 11:35:18 -040046}
47
John Stiles23e68662020-10-29 10:17:15 -040048static void set_thread_local_memory_pool(MemoryPool* poolData) {
John Stiles0bb9ec52020-10-22 11:35:18 -040049 pthread_setspecific(get_pthread_key(), poolData);
50}
51
Ethan Nicholas7b776b52020-12-01 13:38:32 -050052#endif // SKSL_USE_THREAD_LOCAL
John Stiles0bb9ec52020-10-22 11:35:18 -040053
John Stiles5c7bb322020-10-22 11:09:15 -040054Pool::~Pool() {
John Stiles23e68662020-10-29 10:17:15 -040055 if (get_thread_local_memory_pool() == fMemPool.get()) {
John Stiles5c7bb322020-10-22 11:09:15 -040056 SkDEBUGFAIL("SkSL pool is being destroyed while it is still attached to the thread");
John Stiles23e68662020-10-29 10:17:15 -040057 set_thread_local_memory_pool(nullptr);
John Stiles5c7bb322020-10-22 11:09:15 -040058 }
59
John Stiles23e68662020-10-29 10:17:15 -040060 fMemPool->reportLeaks();
61 SkASSERT(fMemPool->isEmpty());
John Stiles5c7bb322020-10-22 11:09:15 -040062
John Stiles23e68662020-10-29 10:17:15 -040063 VLOG("DELETE Pool:0x%016llX\n", (uint64_t)fMemPool.get());
John Stiles5c7bb322020-10-22 11:09:15 -040064}
65
John Stiles2d68ea32020-10-22 15:42:27 -040066std::unique_ptr<Pool> Pool::Create() {
John Stilesdd13dba2020-10-29 10:45:34 -040067 auto pool = std::unique_ptr<Pool>(new Pool);
68 pool->fMemPool = MemoryPool::Make(/*preallocSize=*/65536, /*minAllocSize=*/32768);
69 VLOG("CREATE Pool:0x%016llX\n", (uint64_t)pool->fMemPool.get());
John Stiles5c7bb322020-10-22 11:09:15 -040070 return pool;
71}
72
John Stiles5c7bb322020-10-22 11:09:15 -040073void Pool::attachToThread() {
John Stiles23e68662020-10-29 10:17:15 -040074 VLOG("ATTACH Pool:0x%016llX\n", (uint64_t)fMemPool.get());
75 SkASSERT(get_thread_local_memory_pool() == nullptr);
76 set_thread_local_memory_pool(fMemPool.get());
John Stiles5c7bb322020-10-22 11:09:15 -040077}
78
John Stiles2d68ea32020-10-22 15:42:27 -040079void Pool::detachFromThread() {
John Stilese5d729c2020-10-29 10:26:28 -040080 MemoryPool* memPool = get_thread_local_memory_pool();
81 VLOG("DETACH Pool:0x%016llX\n", (uint64_t)memPool);
82 SkASSERT(memPool == fMemPool.get());
83 memPool->resetScratchSpace();
John Stiles23e68662020-10-29 10:17:15 -040084 set_thread_local_memory_pool(nullptr);
John Stiles2d68ea32020-10-22 15:42:27 -040085}
86
John Stilesb69a9d42020-11-19 14:50:56 -050087void* Pool::AllocMemory(size_t size) {
John Stiles3898bb52020-10-27 17:03:14 +000088 // Is a pool attached?
John Stiles23e68662020-10-29 10:17:15 -040089 MemoryPool* memPool = get_thread_local_memory_pool();
90 if (memPool) {
John Stilesb69a9d42020-11-19 14:50:56 -050091 void* ptr = memPool->allocate(size);
92 VLOG("ALLOC Pool:0x%016llX 0x%016llX\n", (uint64_t)memPool, (uint64_t)ptr);
93 return ptr;
John Stiles5c7bb322020-10-22 11:09:15 -040094 }
95
John Stilesb69a9d42020-11-19 14:50:56 -050096 // There's no pool attached. Allocate memory using the system allocator.
97 void* ptr = ::operator new(size);
98 VLOG("ALLOC Pool:__________________ 0x%016llX\n", (uint64_t)ptr);
99 return ptr;
John Stiles5c7bb322020-10-22 11:09:15 -0400100}
101
John Stilesb69a9d42020-11-19 14:50:56 -0500102void Pool::FreeMemory(void* ptr) {
John Stiles5c7bb322020-10-22 11:09:15 -0400103 // Is a pool attached?
John Stiles23e68662020-10-29 10:17:15 -0400104 MemoryPool* memPool = get_thread_local_memory_pool();
105 if (memPool) {
John Stilesb69a9d42020-11-19 14:50:56 -0500106 VLOG("FREE Pool:0x%016llX 0x%016llX\n", (uint64_t)memPool, (uint64_t)ptr);
107 memPool->release(ptr);
John Stiles23e68662020-10-29 10:17:15 -0400108 return;
John Stiles5c7bb322020-10-22 11:09:15 -0400109 }
110
John Stiles23e68662020-10-29 10:17:15 -0400111 // There's no pool attached. Free it using the system allocator.
John Stilesb69a9d42020-11-19 14:50:56 -0500112 VLOG("FREE Pool:__________________ 0x%016llX\n", (uint64_t)ptr);
113 ::operator delete(ptr);
John Stiles5c7bb322020-10-22 11:09:15 -0400114}
115
John Stiles5c7bb322020-10-22 11:09:15 -0400116} // namespace SkSL