• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright 2010 Google Inc.
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8          http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15  */
16 
17 
18 #include "GrAllocPool.h"
19 
20 #define GrAllocPool_MIN_BLOCK_SIZE      ((size_t)128)
21 
22 struct GrAllocPool::Block {
23     Block*  fNext;
24     char*   fPtr;
25     size_t  fBytesFree;
26     size_t  fBytesTotal;
27 
CreateGrAllocPool::Block28     static Block* Create(size_t size, Block* next) {
29         GrAssert(size >= GrAllocPool_MIN_BLOCK_SIZE);
30 
31         Block* block = (Block*)GrMalloc(sizeof(Block) + size);
32         block->fNext = next;
33         block->fPtr = (char*)block + sizeof(Block);
34         block->fBytesFree = size;
35         block->fBytesTotal = size;
36         return block;
37     }
38 
canAllocGrAllocPool::Block39     bool canAlloc(size_t bytes) const {
40         return bytes <= fBytesFree;
41     }
42 
allocGrAllocPool::Block43     void* alloc(size_t bytes) {
44         GrAssert(bytes <= fBytesFree);
45         fBytesFree -= bytes;
46         void* ptr = fPtr;
47         fPtr += bytes;
48         return ptr;
49     }
50 
releaseGrAllocPool::Block51     size_t release(size_t bytes) {
52         GrAssert(bytes > 0);
53         size_t free = GrMin(bytes, fBytesTotal - fBytesFree);
54         fBytesFree += free;
55         fPtr -= free;
56         return bytes - free;
57     }
58 
emptyGrAllocPool::Block59     bool empty() const { return fBytesTotal == fBytesFree; }
60 };
61 
62 ///////////////////////////////////////////////////////////////////////////////
63 
GrAllocPool(size_t blockSize)64 GrAllocPool::GrAllocPool(size_t blockSize) {
65     fBlock = NULL;
66     fMinBlockSize = GrMax(blockSize, GrAllocPool_MIN_BLOCK_SIZE);
67     GR_DEBUGCODE(fBlocksAllocated = 0;)
68 }
69 
~GrAllocPool()70 GrAllocPool::~GrAllocPool() {
71     this->reset();
72 }
73 
reset()74 void GrAllocPool::reset() {
75     this->validate();
76 
77     Block* block = fBlock;
78     while (block) {
79         Block* next = block->fNext;
80         GrFree(block);
81         block = next;
82     }
83     fBlock = NULL;
84     GR_DEBUGCODE(fBlocksAllocated = 0;)
85 }
86 
alloc(size_t size)87 void* GrAllocPool::alloc(size_t size) {
88     this->validate();
89 
90     if (!fBlock || !fBlock->canAlloc(size)) {
91         size_t blockSize = GrMax(fMinBlockSize, size);
92         fBlock = Block::Create(blockSize, fBlock);
93         GR_DEBUGCODE(fBlocksAllocated += 1;)
94     }
95     return fBlock->alloc(size);
96 }
97 
release(size_t bytes)98 void GrAllocPool::release(size_t bytes) {
99     this->validate();
100 
101     while (bytes && NULL != fBlock) {
102         bytes = fBlock->release(bytes);
103         if (fBlock->empty()) {
104             Block* next = fBlock->fNext;
105             GrFree(fBlock);
106             fBlock = next;
107             GR_DEBUGCODE(fBlocksAllocated -= 1;)
108         }
109     }
110 }
111 
112 
113 #if GR_DEBUG
114 
validate() const115 void GrAllocPool::validate() const {
116     Block* block = fBlock;
117     int count = 0;
118     while (block) {
119         count += 1;
120         block = block->fNext;
121     }
122     GrAssert(fBlocksAllocated == count);
123 }
124 
125 #endif
126 
127 
128