1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
5
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.
10
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.
15
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
19 */
20
21
22 #include "AdvancingAllocPool.h"
23 #include "SC_AllocPool.h"
24 //#include <assert.h>
25
26
AdvancingAllocPool()27 AdvancingAllocPool::AdvancingAllocPool() {
28 mAllocPool = nullptr;
29 mInitSize = 0;
30 mGrowSize = 0;
31 mTooBig = 0;
32 mCurSize = 0;
33 mChunks = nullptr;
34 mFatties = nullptr;
35 }
36
Init(AllocPool * inAllocPool,size_t initSize,size_t growSize,size_t tooBigSize)37 void AdvancingAllocPool::Init(AllocPool* inAllocPool, size_t initSize, size_t growSize, size_t tooBigSize) {
38 mAllocPool = inAllocPool;
39 mInitSize = initSize;
40 mGrowSize = growSize;
41 mTooBig = tooBigSize;
42 mChunks = nullptr;
43 AddChunk(initSize);
44 mFatties = nullptr;
45 // assert(SanityCheck());
46 }
47
AddChunk(size_t inSize)48 void AdvancingAllocPool::AddChunk(size_t inSize) {
49 size_t chunkSize = sizeof(AdvancingAllocPoolChunkHdr) + inSize;
50 AdvancingAllocPoolChunk* chunk = (AdvancingAllocPoolChunk*)mAllocPool->Alloc(chunkSize);
51 FailNil(chunk);
52 chunk->mNext = mChunks;
53 mChunks = chunk;
54 chunk->mSize = mGrowSize;
55 mCurSize = 0;
56 }
57
Alloc(size_t reqsize)58 void* AdvancingAllocPool::Alloc(size_t reqsize) {
59 // assert(SanityCheck());
60 // assert(mAllocPool);
61 size_t size = (reqsize + 15) & ~15; // round up to 16 byte alignment
62 if (size < mTooBig) {
63 if (!mChunks)
64 AddChunk(mInitSize);
65 else if (mCurSize + size > mChunks->mSize)
66 AddChunk(mGrowSize);
67 char* space = mChunks->mSpace + mCurSize;
68 mCurSize += size;
69
70 // assert(SanityCheck());
71 return (void*)space;
72 } else {
73 size_t chunkSize = sizeof(AdvancingAllocPoolChunkHdr) + size;
74 AdvancingAllocPoolChunk* fatty = (AdvancingAllocPoolChunk*)mAllocPool->Alloc(chunkSize);
75 FailNil(fatty);
76 fatty->mNext = mFatties;
77 mFatties = fatty;
78 fatty->mSize = size;
79
80 // assert(SanityCheck());
81 return (void*)fatty->mSpace;
82 }
83 }
84
FreeAll()85 void AdvancingAllocPool::FreeAll() {
86 // assert(SanityCheck());
87 AdvancingAllocPoolChunk *chunk, *next;
88 for (chunk = mChunks; chunk; chunk = next) {
89 next = chunk->mNext;
90 mAllocPool->Free(chunk);
91 }
92 for (chunk = mFatties; chunk; chunk = next) {
93 next = chunk->mNext;
94 mAllocPool->Free(chunk);
95 }
96 mChunks = nullptr;
97 mFatties = nullptr;
98 mCurSize = 0;
99 // assert(SanityCheck());
100 }
101
SanityCheck()102 bool AdvancingAllocPool::SanityCheck() {
103 AdvancingAllocPoolChunk *chunk, *next;
104 for (chunk = mChunks; chunk; chunk = next) {
105 next = chunk->mNext;
106 mAllocPool->DoCheckInUseChunk(AllocPool::MemToChunk(chunk));
107 }
108 for (chunk = mFatties; chunk; chunk = next) {
109 next = chunk->mNext;
110 mAllocPool->DoCheckInUseChunk(AllocPool::MemToChunk(chunk));
111 }
112 return true;
113 }
114