blob: ecd2acfa05b464b5642fb426309d0b808c20e72b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/*
* Copyright 2010 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrAllocPool.h"
#define GrAllocPool_MIN_BLOCK_SIZE ((size_t)128)
struct GrAllocPool::Block {
Block* fNext;
char* fPtr;
size_t fBytesFree;
size_t fBytesTotal;
static Block* Create(size_t size, Block* next) {
GrAssert(size >= GrAllocPool_MIN_BLOCK_SIZE);
Block* block = (Block*)GrMalloc(sizeof(Block) + size);
block->fNext = next;
block->fPtr = (char*)block + sizeof(Block);
block->fBytesFree = size;
block->fBytesTotal = size;
return block;
}
bool canAlloc(size_t bytes) const {
return bytes <= fBytesFree;
}
void* alloc(size_t bytes) {
GrAssert(bytes <= fBytesFree);
fBytesFree -= bytes;
void* ptr = fPtr;
fPtr += bytes;
return ptr;
}
size_t release(size_t bytes) {
GrAssert(bytes > 0);
size_t free = GrMin(bytes, fBytesTotal - fBytesFree);
fBytesFree += free;
fPtr -= free;
return bytes - free;
}
bool empty() const { return fBytesTotal == fBytesFree; }
};
///////////////////////////////////////////////////////////////////////////////
GrAllocPool::GrAllocPool(size_t blockSize) {
fBlock = NULL;
fMinBlockSize = GrMax(blockSize, GrAllocPool_MIN_BLOCK_SIZE);
GR_DEBUGCODE(fBlocksAllocated = 0;)
}
GrAllocPool::~GrAllocPool() {
this->reset();
}
void GrAllocPool::reset() {
this->validate();
Block* block = fBlock;
while (block) {
Block* next = block->fNext;
GrFree(block);
block = next;
}
fBlock = NULL;
GR_DEBUGCODE(fBlocksAllocated = 0;)
}
void* GrAllocPool::alloc(size_t size) {
this->validate();
if (!fBlock || !fBlock->canAlloc(size)) {
size_t blockSize = GrMax(fMinBlockSize, size);
fBlock = Block::Create(blockSize, fBlock);
GR_DEBUGCODE(fBlocksAllocated += 1;)
}
return fBlock->alloc(size);
}
void GrAllocPool::release(size_t bytes) {
this->validate();
while (bytes && NULL != fBlock) {
bytes = fBlock->release(bytes);
if (fBlock->empty()) {
Block* next = fBlock->fNext;
GrFree(fBlock);
fBlock = next;
GR_DEBUGCODE(fBlocksAllocated -= 1;)
}
}
}
#if GR_DEBUG
void GrAllocPool::validate() const {
Block* block = fBlock;
int count = 0;
while (block) {
count += 1;
block = block->fNext;
}
GrAssert(fBlocksAllocated == count);
}
#endif
|