|
1 /* |
|
2 * Copyright 2012 Google Inc. |
|
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 #ifndef GrMemoryPool_DEFINED |
|
9 #define GrMemoryPool_DEFINED |
|
10 |
|
11 #include "GrTypes.h" |
|
12 |
|
13 /** |
|
14 * Allocates memory in blocks and parcels out space in the blocks for allocation |
|
15 * requests. It is optimized for allocate / release speed over memory |
|
16 * effeciency. The interface is designed to be used to implement operator new |
|
17 * and delete overrides. All allocations are expected to be released before the |
|
18 * pool's destructor is called. Allocations will be 8-byte aligned. |
|
19 */ |
|
20 class GrMemoryPool { |
|
21 public: |
|
22 /** |
|
23 * Prealloc size is the amount of space to make available at pool creation |
|
24 * time and keep around until pool destruction. The min alloc size is the |
|
25 * smallest allowed size of additional allocations. |
|
26 */ |
|
27 GrMemoryPool(size_t preallocSize, size_t minAllocSize); |
|
28 |
|
29 ~GrMemoryPool(); |
|
30 |
|
31 /** |
|
32 * Allocates memory. The memory must be freed with release(). |
|
33 */ |
|
34 void* allocate(size_t size); |
|
35 |
|
36 /** |
|
37 * p must have been returned by allocate() |
|
38 */ |
|
39 void release(void* p); |
|
40 |
|
41 /** |
|
42 * Returns true if there are no unreleased allocations. |
|
43 */ |
|
44 bool isEmpty() const { return fTail == fHead && !fHead->fLiveCount; } |
|
45 |
|
46 private: |
|
47 struct BlockHeader; |
|
48 |
|
49 static BlockHeader* CreateBlock(size_t size); |
|
50 |
|
51 static void DeleteBlock(BlockHeader* block); |
|
52 |
|
53 void validate(); |
|
54 |
|
55 struct BlockHeader { |
|
56 BlockHeader* fNext; ///< doubly-linked list of blocks. |
|
57 BlockHeader* fPrev; |
|
58 int fLiveCount; ///< number of outstanding allocations in the |
|
59 ///< block. |
|
60 intptr_t fCurrPtr; ///< ptr to the start of blocks free space. |
|
61 intptr_t fPrevPtr; ///< ptr to the last allocation made |
|
62 size_t fFreeSize; ///< amount of free space left in the block. |
|
63 }; |
|
64 |
|
65 enum { |
|
66 // We assume this alignment is good enough for everybody. |
|
67 kAlignment = 8, |
|
68 kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment), |
|
69 kPerAllocPad = GR_CT_ALIGN_UP(sizeof(BlockHeader*), kAlignment), |
|
70 }; |
|
71 size_t fPreallocSize; |
|
72 size_t fMinAllocSize; |
|
73 BlockHeader* fHead; |
|
74 BlockHeader* fTail; |
|
75 #ifdef SK_DEBUG |
|
76 int fAllocationCnt; |
|
77 #endif |
|
78 }; |
|
79 |
|
80 #endif |