1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkTObjectPool.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,104 @@ 1.4 +/* 1.5 + * Copyright 2014 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkFreeList_DEFINED 1.12 +#define SkFreeList_DEFINED 1.13 + 1.14 +#include "SkTInternalSList.h" 1.15 + 1.16 +/** 1.17 + * An implementation of a self growing pool of objects. 1.18 + * It maintains a pool of fully initialized objects. If an attempt is made to 1.19 + * acquire one, and there are none left, it makes some more. 1.20 + * It does not automatically reclaim them, they have to be given back to it. 1.21 + * Constructors will be called on objects allocated by the pool at allocation 1.22 + * time. 1.23 + * All allocated objects will be destroyed and memory will be reclaimed when 1.24 + * the pool is destroyed, so the pool must survive longer than you are using 1.25 + * any item taken from it. 1.26 + */ 1.27 +template<typename T, int numItemsPerBlock = 4096/sizeof(T)> class SkTObjectPool { 1.28 +public: 1.29 + SkTObjectPool() {} 1.30 + ~SkTObjectPool() { 1.31 + while (!fBlocks.isEmpty()) { 1.32 + SkDELETE(fBlocks.pop()); 1.33 + } 1.34 + } 1.35 + 1.36 + /** 1.37 + * Get an item from the pool. 1.38 + * If the pool has no free items, it will allocate and construct some more. 1.39 + * The returned item is only valid as long as the pool has not been 1.40 + * destroyed, at that point all memory allocated by grow will have been 1.41 + * reclaimed. 1.42 + * This method is *not* thread safe. 1.43 + */ 1.44 + T* acquire() { 1.45 + if (fAvailable.isEmpty()) { 1.46 + grow(); 1.47 + } 1.48 + return fAvailable.pop(); 1.49 + } 1.50 + 1.51 + /** 1.52 + * Release an item into the pool. 1.53 + * The item does not have to have come from the pool, but if it did not 1.54 + * it must have a lifetime greater than the pool does. 1.55 + * This method is *not* thread safe. 1.56 + */ 1.57 + void release(T* entry) { 1.58 + fAvailable.push(entry); 1.59 + } 1.60 + 1.61 + /** 1.62 + * Takes all the items from an SkTInternalSList and adds them back to this 1.63 + * pool. The other list will be left empty. 1.64 + */ 1.65 + void releaseAll(SkTInternalSList<T>* other) { 1.66 + fAvailable.pushAll(other); 1.67 + } 1.68 + 1.69 + /** 1.70 + * Returns the number of items immediately available without having to 1.71 + * construct any new ones. 1.72 + */ 1.73 + int available() const { return fAvailable.getCount(); } 1.74 + 1.75 + /** 1.76 + * Returns the number of blocks of items the pool has allocated so far. 1.77 + */ 1.78 + int blocks() const { return fBlocks.getCount(); } 1.79 + 1.80 +private: 1.81 + /** 1.82 + * The type for a new block of entries for the list. 1.83 + */ 1.84 + struct Block { 1.85 + T entries[numItemsPerBlock]; 1.86 + SK_DECLARE_INTERNAL_SLIST_INTERFACE(Block); 1.87 + }; 1.88 + SkTInternalSList<Block> fBlocks; 1.89 + SkTInternalSList<T> fAvailable; 1.90 + 1.91 + /** 1.92 + * When the free list runs out of items, this method is called to allocate 1.93 + * a new block of them. 1.94 + * It calls the constructors and then pushes the nodes into the available 1.95 + * list. 1.96 + */ 1.97 + void grow() { 1.98 + Block* block = SkNEW(Block); 1.99 + fBlocks.push(block); 1.100 + for(int index = 0; index < numItemsPerBlock; ++index) { 1.101 + fAvailable.push(&block->entries[index]); 1.102 + } 1.103 + } 1.104 + 1.105 +}; 1.106 + 1.107 +#endif