Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / lang / LangSource / AdvancingAllocPool.cpp
blob6b7fcf803c5a4aea461390665268408939732767
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "AdvancingAllocPool.h"
23 #include "SC_AllocPool.h"
24 //#include <assert.h>
27 AdvancingAllocPool::AdvancingAllocPool()
29 mAllocPool = 0;
30 mInitSize = 0;
31 mGrowSize = 0;
32 mTooBig = 0;
33 mCurSize = 0;
34 mChunks = NULL;
35 mFatties = NULL;
38 void AdvancingAllocPool::Init(AllocPool *inAllocPool, size_t initSize, size_t growSize, size_t tooBigSize)
40 mAllocPool = inAllocPool;
41 mInitSize = initSize;
42 mGrowSize = growSize;
43 mTooBig = tooBigSize;
44 mChunks = NULL;
45 AddChunk(initSize);
46 mFatties = NULL;
47 //assert(SanityCheck());
50 void AdvancingAllocPool::AddChunk(size_t inSize)
52 size_t chunkSize = sizeof(AdvancingAllocPoolChunkHdr) + inSize;
53 AdvancingAllocPoolChunk* chunk = (AdvancingAllocPoolChunk*)mAllocPool->Alloc(chunkSize);
54 FailNil(chunk);
55 chunk->mNext = mChunks;
56 mChunks = chunk;
57 chunk->mSize = mGrowSize;
58 mCurSize = 0;
61 void* AdvancingAllocPool::Alloc(size_t reqsize)
63 //assert(SanityCheck());
64 //assert(mAllocPool);
65 size_t size = (reqsize + 15) & ~15; // round up to 16 byte alignment
66 if (size < mTooBig) {
67 if (!mChunks) AddChunk(mInitSize);
68 else if (mCurSize + size > mChunks->mSize) AddChunk(mGrowSize);
69 char* space = mChunks->mSpace + mCurSize;
70 mCurSize += size;
72 //assert(SanityCheck());
73 return (void*)space;
74 } else {
75 size_t chunkSize = sizeof(AdvancingAllocPoolChunkHdr) + size;
76 AdvancingAllocPoolChunk* fatty = (AdvancingAllocPoolChunk*)mAllocPool->Alloc(chunkSize);
77 FailNil(fatty);
78 fatty->mNext = mFatties;
79 mFatties = fatty;
80 fatty->mSize = size;
82 //assert(SanityCheck());
83 return (void*)fatty->mSpace;
87 void AdvancingAllocPool::FreeAll()
89 //assert(SanityCheck());
90 AdvancingAllocPoolChunk *chunk, *next;
91 for (chunk = mChunks; chunk; chunk = next) {
92 next = chunk->mNext;
93 mAllocPool->Free(chunk);
95 for (chunk = mFatties; chunk; chunk = next) {
96 next = chunk->mNext;
97 mAllocPool->Free(chunk);
99 mChunks = NULL;
100 mFatties = NULL;
101 mCurSize = 0;
102 //assert(SanityCheck());
105 bool AdvancingAllocPool::SanityCheck()
107 AdvancingAllocPoolChunk *chunk, *next;
108 for (chunk = mChunks; chunk; chunk = next) {
109 next = chunk->mNext;
110 mAllocPool->DoCheckInUseChunk(AllocPool::MemToChunk(chunk));
112 for (chunk = mFatties; chunk; chunk = next) {
113 next = chunk->mNext;
114 mAllocPool->DoCheckInUseChunk(AllocPool::MemToChunk(chunk));
116 return true;