1 /*
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
10 #include "include/private/SkSLDefines.h"
11
12 #define VLOG(...) // printf(__VA_ARGS__)
13
14 namespace SkSL {
15
16 static thread_local MemoryPool* sMemPool = nullptr;
17
get_thread_local_memory_pool()18 static MemoryPool* get_thread_local_memory_pool() {
19 return sMemPool;
20 }
21
set_thread_local_memory_pool(MemoryPool * memPool)22 static void set_thread_local_memory_pool(MemoryPool* memPool) {
23 sMemPool = memPool;
24 }
25
~Pool()26 Pool::~Pool() {
27 if (get_thread_local_memory_pool() == fMemPool.get()) {
28 SkDEBUGFAIL("SkSL pool is being destroyed while it is still attached to the thread");
29 set_thread_local_memory_pool(nullptr);
30 }
31
32 fMemPool->reportLeaks();
33 SkASSERT(fMemPool->isEmpty());
34
35 VLOG("DELETE Pool:0x%016llX\n", (uint64_t)fMemPool.get());
36 }
37
Create()38 std::unique_ptr<Pool> Pool::Create() {
39 auto pool = std::unique_ptr<Pool>(new Pool);
40 pool->fMemPool = MemoryPool::Make(/*preallocSize=*/65536, /*minAllocSize=*/32768);
41 VLOG("CREATE Pool:0x%016llX\n", (uint64_t)pool->fMemPool.get());
42 return pool;
43 }
44
IsAttached()45 bool Pool::IsAttached() {
46 return get_thread_local_memory_pool();
47 }
48
attachToThread()49 void Pool::attachToThread() {
50 VLOG("ATTACH Pool:0x%016llX\n", (uint64_t)fMemPool.get());
51 SkASSERT(get_thread_local_memory_pool() == nullptr);
52 set_thread_local_memory_pool(fMemPool.get());
53 }
54
detachFromThread()55 void Pool::detachFromThread() {
56 MemoryPool* memPool = get_thread_local_memory_pool();
57 VLOG("DETACH Pool:0x%016llX\n", (uint64_t)memPool);
58 SkASSERT(memPool == fMemPool.get());
59 memPool->resetScratchSpace();
60 set_thread_local_memory_pool(nullptr);
61 }
62
AllocMemory(size_t size)63 void* Pool::AllocMemory(size_t size) {
64 // Is a pool attached?
65 MemoryPool* memPool = get_thread_local_memory_pool();
66 if (memPool) {
67 void* ptr = memPool->allocate(size);
68 VLOG("ALLOC Pool:0x%016llX 0x%016llX\n", (uint64_t)memPool, (uint64_t)ptr);
69 return ptr;
70 }
71
72 // There's no pool attached. Allocate memory using the system allocator.
73 void* ptr = ::operator new(size);
74 VLOG("ALLOC Pool:__________________ 0x%016llX\n", (uint64_t)ptr);
75 return ptr;
76 }
77
FreeMemory(void * ptr)78 void Pool::FreeMemory(void* ptr) {
79 // Is a pool attached?
80 MemoryPool* memPool = get_thread_local_memory_pool();
81 if (memPool) {
82 VLOG("FREE Pool:0x%016llX 0x%016llX\n", (uint64_t)memPool, (uint64_t)ptr);
83 memPool->release(ptr);
84 return;
85 }
86
87 // There's no pool attached. Free it using the system allocator.
88 VLOG("FREE Pool:__________________ 0x%016llX\n", (uint64_t)ptr);
89 ::operator delete(ptr);
90 }
91
92 } // namespace SkSL
93