blob: 94d0f4e03f54895c12c222920b142fe28592a30c [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
John Stiles5c7bb322020-10-22 11:09:15 -040010#define VLOG(...) // printf(__VA_ARGS__)
11
12namespace SkSL {
13
John Stiles0bb9ec52020-10-22 11:35:18 -040014#if defined(SK_BUILD_FOR_IOS) && \
15 (!defined(__IPHONE_9_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
16
17#include <pthread.h>
18
19static pthread_key_t get_pthread_key() {
20 static pthread_key_t sKey = []{
21 pthread_key_t key;
22 int result = pthread_key_create(&key, /*destructor=*/nullptr);
23 if (result != 0) {
24 SK_ABORT("pthread_key_create failure: %d", result);
25 }
26 return key;
27 }();
28 return sKey;
29}
30
John Stiles23e68662020-10-29 10:17:15 -040031static MemoryPool* get_thread_local_memory_pool() {
32 return static_cast<MemoryPool*>(pthread_getspecific(get_pthread_key()));
John Stiles0bb9ec52020-10-22 11:35:18 -040033}
34
John Stiles23e68662020-10-29 10:17:15 -040035static void set_thread_local_memory_pool(MemoryPool* poolData) {
John Stiles0bb9ec52020-10-22 11:35:18 -040036 pthread_setspecific(get_pthread_key(), poolData);
37}
38
39#else
40
John Stiles23e68662020-10-29 10:17:15 -040041static thread_local MemoryPool* sMemPool = nullptr;
John Stiles5c7bb322020-10-22 11:09:15 -040042
John Stiles23e68662020-10-29 10:17:15 -040043static MemoryPool* get_thread_local_memory_pool() {
44 return sMemPool;
John Stiles0bb9ec52020-10-22 11:35:18 -040045}
46
John Stiles23e68662020-10-29 10:17:15 -040047static void set_thread_local_memory_pool(MemoryPool* memPool) {
48 sMemPool = memPool;
John Stiles0bb9ec52020-10-22 11:35:18 -040049}
50
51#endif
52
John Stiles5c7bb322020-10-22 11:09:15 -040053Pool::~Pool() {
John Stiles23e68662020-10-29 10:17:15 -040054 if (get_thread_local_memory_pool() == fMemPool.get()) {
John Stiles5c7bb322020-10-22 11:09:15 -040055 SkDEBUGFAIL("SkSL pool is being destroyed while it is still attached to the thread");
John Stiles23e68662020-10-29 10:17:15 -040056 set_thread_local_memory_pool(nullptr);
John Stiles5c7bb322020-10-22 11:09:15 -040057 }
58
John Stiles23e68662020-10-29 10:17:15 -040059 fMemPool->reportLeaks();
60 SkASSERT(fMemPool->isEmpty());
John Stiles5c7bb322020-10-22 11:09:15 -040061
John Stiles23e68662020-10-29 10:17:15 -040062 VLOG("DELETE Pool:0x%016llX\n", (uint64_t)fMemPool.get());
John Stiles5c7bb322020-10-22 11:09:15 -040063}
64
John Stiles2d68ea32020-10-22 15:42:27 -040065std::unique_ptr<Pool> Pool::Create() {
John Stilesdd13dba2020-10-29 10:45:34 -040066 auto pool = std::unique_ptr<Pool>(new Pool);
67 pool->fMemPool = MemoryPool::Make(/*preallocSize=*/65536, /*minAllocSize=*/32768);
68 VLOG("CREATE Pool:0x%016llX\n", (uint64_t)pool->fMemPool.get());
John Stiles5c7bb322020-10-22 11:09:15 -040069 return pool;
70}
71
John Stiles5c7bb322020-10-22 11:09:15 -040072void Pool::attachToThread() {
John Stiles23e68662020-10-29 10:17:15 -040073 VLOG("ATTACH Pool:0x%016llX\n", (uint64_t)fMemPool.get());
74 SkASSERT(get_thread_local_memory_pool() == nullptr);
75 set_thread_local_memory_pool(fMemPool.get());
John Stiles5c7bb322020-10-22 11:09:15 -040076}
77
John Stiles2d68ea32020-10-22 15:42:27 -040078void Pool::detachFromThread() {
John Stilese5d729c2020-10-29 10:26:28 -040079 MemoryPool* memPool = get_thread_local_memory_pool();
80 VLOG("DETACH Pool:0x%016llX\n", (uint64_t)memPool);
81 SkASSERT(memPool == fMemPool.get());
82 memPool->resetScratchSpace();
John Stiles23e68662020-10-29 10:17:15 -040083 set_thread_local_memory_pool(nullptr);
John Stiles2d68ea32020-10-22 15:42:27 -040084}
85
John Stiles270b5c02020-10-27 17:49:37 -040086void* Pool::AllocIRNode(size_t size) {
John Stiles3898bb52020-10-27 17:03:14 +000087 // Is a pool attached?
John Stiles23e68662020-10-29 10:17:15 -040088 MemoryPool* memPool = get_thread_local_memory_pool();
89 if (memPool) {
90 void* node = memPool->allocate(size);
91 VLOG("ALLOC Pool:0x%016llX 0x%016llX\n", (uint64_t)memPool, (uint64_t)node);
92 return node;
John Stiles5c7bb322020-10-22 11:09:15 -040093 }
94
John Stiles23e68662020-10-29 10:17:15 -040095 // There's no pool attached. Allocate nodes using the system allocator.
96 void* node = ::operator new(size);
97 VLOG("ALLOC Pool:__________________ 0x%016llX\n", (uint64_t)node);
98 return node;
John Stiles5c7bb322020-10-22 11:09:15 -040099}
100
John Stiles15bfe382020-10-27 19:07:05 -0400101void Pool::FreeIRNode(void* node) {
John Stiles5c7bb322020-10-22 11:09:15 -0400102 // Is a pool attached?
John Stiles23e68662020-10-29 10:17:15 -0400103 MemoryPool* memPool = get_thread_local_memory_pool();
104 if (memPool) {
105 VLOG("FREE Pool:0x%016llX 0x%016llX\n", (uint64_t)memPool, (uint64_t)node);
106 memPool->release(node);
107 return;
John Stiles5c7bb322020-10-22 11:09:15 -0400108 }
109
John Stiles23e68662020-10-29 10:17:15 -0400110 // There's no pool attached. Free it using the system allocator.
111 VLOG("FREE Pool:__________________ 0x%016llX\n", (uint64_t)node);
John Stiles15bfe382020-10-27 19:07:05 -0400112 ::operator delete(node);
John Stiles5c7bb322020-10-22 11:09:15 -0400113}
114
John Stiles5c7bb322020-10-22 11:09:15 -0400115} // namespace SkSL