36 class KZoneAllocator::MemBlock
39 MemBlock(
size_t s) : size(s),
ref(0), older(0), newer(0)
40 { begin =
new char[s]; }
41 ~MemBlock() {
delete [] begin; }
42 bool is_in(
void *ptr)
const {
return !(begin > (
char *)ptr
43 || (begin + size) <= (
char *)ptr); }
51 class KZoneAllocator::Private
55 : currentBlock(0), blockSize(1),
56 blockOffset(0), log2(0), num_blocks(0),
57 hashList(0), hashSize(0), hashDirty(true)
62 MemBlock *currentBlock;
64 unsigned long blockSize;
66 unsigned long blockOffset;
70 unsigned int num_blocks;
74 unsigned int hashSize;
82 while (d->blockSize < _blockSize) {
89 d->blockOffset = d->blockSize + 1;
94 unsigned int count = 0;
98 for (
unsigned int i = 0; i < d->hashSize; i++)
99 delete d->hashList[i];
100 delete [] d->hashList;
104 for (; d->currentBlock; d->currentBlock = next) {
105 next = d->currentBlock->older;
106 delete d->currentBlock;
109 #ifndef NDEBUG // as this is called quite late in the app, we don't care
112 fprintf(stderr,
"zone still contained %d blocks", count);
119 quintptr adr = ((quintptr)b->begin) & (~(d->blockSize - 1));
120 quintptr end = ((quintptr)b->begin) + d->blockSize;
122 quintptr key = adr >> d->log2;
123 key = key & (d->hashSize - 1);
124 if (!d->hashList[key])
126 d->hashList[key]->append(b);
139 b->older = d->currentBlock;
147 if (d->hashList && ((d->num_blocks / 4) > d->hashSize && d->hashSize < 64*1024))
151 if (d->hashList && !d->hashDirty)
159 for (
unsigned int i = 0; i < d->hashSize; i++)
160 delete d->hashList[i];
161 delete [] d->hashList;
165 while (d->hashSize < d->num_blocks)
167 if (d->hashSize < 1024)
169 if (d->hashSize > 64*1024)
170 d->hashSize = 64*1024;
173 d->hashDirty =
false;
174 for (MemBlock *b = d->currentBlock; b; b = b->older)
186 if (d->hashList && !d->hashDirty) {
187 quintptr adr = (( quintptr )b->begin) & (~(d->blockSize - 1));
188 quintptr end = (( quintptr )b->begin) + d->blockSize;
190 quintptr key = adr >> d->log2;
191 key = key & (d->hashSize - 1);
192 if (d->hashList[key]) {
196 for (; it != endit; ++it)
206 b->older->newer = b->newer;
208 b->newer->older = b->older;
209 if (b == d->currentBlock) {
211 d->blockOffset = d->blockSize;
221 const size_t alignment =
sizeof(
void *) - 1;
222 _size = (_size + alignment) & ~alignment;
224 if ((
unsigned long) _size + d->blockOffset > d->blockSize)
226 if (_size > d->blockSize) {
227 qDebug(
"KZoneAllocator: allocating more than %lu bytes", d->blockSize);
230 addBlock(
new MemBlock(d->blockSize));
234 void *result = (
void *)(d->currentBlock->begin+d->blockOffset);
235 d->currentBlock->ref++;
236 d->blockOffset += _size;
246 quintptr key = (((quintptr)ptr) >> d->log2) & (d->hashSize - 1);
256 for (; it != endit; ++it) {
258 if (cur->is_in(ptr)) {
260 if (cur != d->currentBlock)
279 if (d->hashList && !d->hashDirty)
282 unsigned int removed = 0;
283 for (b = d->currentBlock; b; b = b->older, removed++)
286 if (d->hashSize >= 4 * (d->num_blocks - removed))
289 while (d->currentBlock && !d->currentBlock->is_in(ptr)) {
290 d->currentBlock = d->currentBlock->older;
293 d->blockOffset = ((
char*)ptr) - d->currentBlock->begin;
void ref()
Tells KGlobal about one more operations that should be finished before the application exits...
KZoneAllocator(unsigned long _blockSize=8 *1024)
Creates a KZoneAllocator object.
void free_since(void *ptr)
Deallocate many objects at once.
void addBlock(MemBlock *b)
Add a new memory block to the pool of blocks, and reorganize the hash lists if needed.
~KZoneAllocator()
Destructs the ZoneAllocator and free all memory allocated by it.
void insertHash(MemBlock *b)
void delBlock(MemBlock *b)
Delete a memory block.
void deallocate(void *ptr)
Gives back a block returned by allocate() to the zone allocator, and possibly deallocates the block h...
QList< MemBlock * > MemList
A list of chunks.
void initHash()
Reinitialize hash list.
void * allocate(size_t _size)
Allocates a memory block.