• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * 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.
7  */
8 
9 
10 
11 #include "GrAllocPool.h"
12 
13 #define GrAllocPool_MIN_BLOCK_SIZE      ((size_t)128)
14 
15 struct GrAllocPool::Block {
16     Block*  fNext;
17     char*   fPtr;
18     size_t  fBytesFree;
19     size_t  fBytesTotal;
20 
CreateGrAllocPool::Block21     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 
canAllocGrAllocPool::Block32     bool canAlloc(size_t bytes) const {
33         return bytes <= fBytesFree;
34     }
35 
allocGrAllocPool::Block36     void* alloc(size_t bytes) {
37         GrAssert(bytes <= fBytesFree);
38         fBytesFree -= bytes;
39         void* ptr = fPtr;
40         fPtr += bytes;
41         return ptr;
42     }
43 
releaseGrAllocPool::Block44     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 
emptyGrAllocPool::Block52     bool empty() const { return fBytesTotal == fBytesFree; }
53 };
54 
55 ///////////////////////////////////////////////////////////////////////////////
56 
GrAllocPool(size_t blockSize)57 GrAllocPool::GrAllocPool(size_t blockSize) {
58     fBlock = NULL;
59     fMinBlockSize = GrMax(blockSize, GrAllocPool_MIN_BLOCK_SIZE);
60     GR_DEBUGCODE(fBlocksAllocated = 0;)
61 }
62 
~GrAllocPool()63 GrAllocPool::~GrAllocPool() {
64     this->reset();
65 }
66 
reset()67 void 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 
alloc(size_t size)80 void* 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 
release(size_t bytes)91 void 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 
validate() const108 void 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