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