1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2020 Google LLC 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_POOL 9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_POOL 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef> 12*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 13*c8dee2aaSAndroid Build Coastguard Worker 14*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL { 15*c8dee2aaSAndroid Build Coastguard Worker 16*c8dee2aaSAndroid Build Coastguard Worker class MemoryPool; 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker /** 19*c8dee2aaSAndroid Build Coastguard Worker * Efficiently allocates memory in an SkSL program. Optimized for allocate/release performance over 20*c8dee2aaSAndroid Build Coastguard Worker * memory efficiency. 21*c8dee2aaSAndroid Build Coastguard Worker * 22*c8dee2aaSAndroid Build Coastguard Worker * All allocated memory must be released back to the pool before it can be destroyed or recycled. 23*c8dee2aaSAndroid Build Coastguard Worker */ 24*c8dee2aaSAndroid Build Coastguard Worker 25*c8dee2aaSAndroid Build Coastguard Worker class Pool { 26*c8dee2aaSAndroid Build Coastguard Worker public: 27*c8dee2aaSAndroid Build Coastguard Worker ~Pool(); 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker // Creates a pool to store objects during program creation. Call attachToThread() to start using 30*c8dee2aaSAndroid Build Coastguard Worker // the pool for its allocations. When your program is complete, call pool->detachFromThread() to 31*c8dee2aaSAndroid Build Coastguard Worker // take ownership of the pool and its allocations. Before freeing any of the program's 32*c8dee2aaSAndroid Build Coastguard Worker // allocations, make sure to reattach the pool by calling pool->attachToThread() again. 33*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<Pool> Create(); 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker // Attaches a pool to the current thread. 36*c8dee2aaSAndroid Build Coastguard Worker // It is an error to call this while a pool is already attached. 37*c8dee2aaSAndroid Build Coastguard Worker void attachToThread(); 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker // Once you are done creating or destroying objects in the pool, detach it from the thread. 40*c8dee2aaSAndroid Build Coastguard Worker // It is an error to call this while no pool is attached. 41*c8dee2aaSAndroid Build Coastguard Worker void detachFromThread(); 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker // Allocates memory from the thread pool. If the pool is exhausted, an additional block of pool 44*c8dee2aaSAndroid Build Coastguard Worker // storage will be created to hold the data. 45*c8dee2aaSAndroid Build Coastguard Worker static void* AllocMemory(size_t size); 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker // Releases memory that was created by AllocMemory. All objects in the pool must be freed before 48*c8dee2aaSAndroid Build Coastguard Worker // the pool can be destroyed. 49*c8dee2aaSAndroid Build Coastguard Worker static void FreeMemory(void* ptr); 50*c8dee2aaSAndroid Build Coastguard Worker 51*c8dee2aaSAndroid Build Coastguard Worker static bool IsAttached(); 52*c8dee2aaSAndroid Build Coastguard Worker 53*c8dee2aaSAndroid Build Coastguard Worker private: 54*c8dee2aaSAndroid Build Coastguard Worker Pool(); // use Create to make a pool 55*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::MemoryPool> fMemPool; 56*c8dee2aaSAndroid Build Coastguard Worker }; 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker /** 59*c8dee2aaSAndroid Build Coastguard Worker * If your class inherits from Poolable, its objects will be allocated from the pool. 60*c8dee2aaSAndroid Build Coastguard Worker */ 61*c8dee2aaSAndroid Build Coastguard Worker class Poolable { 62*c8dee2aaSAndroid Build Coastguard Worker public: 63*c8dee2aaSAndroid Build Coastguard Worker // Override operator new and delete to allow us to use a memory pool. new(const size_t size)64*c8dee2aaSAndroid Build Coastguard Worker static void* operator new(const size_t size) { 65*c8dee2aaSAndroid Build Coastguard Worker return Pool::AllocMemory(size); 66*c8dee2aaSAndroid Build Coastguard Worker } 67*c8dee2aaSAndroid Build Coastguard Worker delete(void * ptr)68*c8dee2aaSAndroid Build Coastguard Worker static void operator delete(void* ptr) { 69*c8dee2aaSAndroid Build Coastguard Worker Pool::FreeMemory(ptr); 70*c8dee2aaSAndroid Build Coastguard Worker } 71*c8dee2aaSAndroid Build Coastguard Worker }; 72*c8dee2aaSAndroid Build Coastguard Worker 73*c8dee2aaSAndroid Build Coastguard Worker /** 74*c8dee2aaSAndroid Build Coastguard Worker * Temporarily attaches a pool to the current thread within a scope. 75*c8dee2aaSAndroid Build Coastguard Worker */ 76*c8dee2aaSAndroid Build Coastguard Worker class AutoAttachPoolToThread { 77*c8dee2aaSAndroid Build Coastguard Worker public: AutoAttachPoolToThread(Pool * p)78*c8dee2aaSAndroid Build Coastguard Worker AutoAttachPoolToThread(Pool* p) : fPool(p) { 79*c8dee2aaSAndroid Build Coastguard Worker if (fPool) { 80*c8dee2aaSAndroid Build Coastguard Worker fPool->attachToThread(); 81*c8dee2aaSAndroid Build Coastguard Worker } 82*c8dee2aaSAndroid Build Coastguard Worker } ~AutoAttachPoolToThread()83*c8dee2aaSAndroid Build Coastguard Worker ~AutoAttachPoolToThread() { 84*c8dee2aaSAndroid Build Coastguard Worker if (fPool) { 85*c8dee2aaSAndroid Build Coastguard Worker fPool->detachFromThread(); 86*c8dee2aaSAndroid Build Coastguard Worker } 87*c8dee2aaSAndroid Build Coastguard Worker } 88*c8dee2aaSAndroid Build Coastguard Worker 89*c8dee2aaSAndroid Build Coastguard Worker private: 90*c8dee2aaSAndroid Build Coastguard Worker Pool* fPool = nullptr; 91*c8dee2aaSAndroid Build Coastguard Worker }; 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker 94*c8dee2aaSAndroid Build Coastguard Worker } // namespace SkSL 95*c8dee2aaSAndroid Build Coastguard Worker 96*c8dee2aaSAndroid Build Coastguard Worker #endif 97