#include <cmemheap.h>
Definition at line 32 of file cmemheap.h.
| static CMachine::ubit32 mFreeCount PikeAero::CMemHeap::__attribute__ | ( | (aligned) | ) | [static, private] |
| static CMachine::bit32 mFreeListSize PikeAero::CMemHeap::__attribute__ | ( | (aligned) | ) | [static, private] |
| static CMachine::ubit8 mHeap [] PikeAero::CMemHeap::__attribute__ | ( | (aligned(4)) | ) | [static, private] |
| CMemHeap::FreeListBlock * PikeAero::CMemHeap::_freelist | ( | CMachine::bit32 | i | ) | [static, private] |
Return a pointer to the FreeListBlock corresponding to freelist offset i.
_freelist() - return a pointer to a freelist entry from an index number.
Definition at line 65 of file cmemheap.cpp.
Referenced by _freelist_free().
00066 { 00067 FreeListBlock* f = (FreeListBlock*)NULL; 00068 if ( i < mFreeListSize && mFreeListSize > 0 ) 00069 { 00070 f = (FreeListBlock*)&mHeap[i*sizeof(FreeListBlock)]; 00071 } 00072 return f; 00073 }

| CMemHeap::FreeListBlock * PikeAero::CMemHeap::_freelist_alloc | ( | CMachine::bit32 | size | ) | [static, private] |
Allocate a FreeListBlock of size and return a pointer to the FreeListBlock or NULL if failed.
_freelist_alloc - attempt to find a chunk, and if found, create a FreeListBlock, adjust the freelist, and return a pointer to the FreeListBlock struct. Allocates from top of heap downward toward freelist.
first, attemp to find a chunk that will fit....
The simple case, we found a chuck that fits exactly...
Create a new free list entry and take some memory from the free block that we found, then append to freelist.
fetch the pointer to the newly allocated freelist entry.
The heap is probably full to the point that we can't allocate a new freelist entry, so let's undo and return an error...
Definition at line 316 of file cmemheap.cpp.
References _freelist_append(), and _freelist_find().
Referenced by malloc().
00317 { 00318 /** 00319 ** first, attemp to find a chunk that will fit.... 00320 */ 00321 FreeListBlock* f = _freelist_find(size); 00322 if ( f != (FreeListBlock*)NULL ) 00323 { 00324 FreeListBlock f_new; 00325 FreeListBlock* ff; 00326 /** 00327 ** The simple case, we found a chuck that fits exactly... 00328 */ 00329 if ( f->size == size ) 00330 { 00331 f->free = false; 00332 return f; 00333 } 00334 /** 00335 ** Create a new free list entry and take some memory from 00336 ** the free block that we found, then append to freelist. 00337 */ 00338 f_new.free = false; 00339 f_new.p = &f->p[f->size-size]; 00340 f_new.size = size; 00341 f->size -= size; 00342 ff = _freelist_append(&f_new); 00343 if ( ff != (FreeListBlock*)NULL ) 00344 { 00345 /** fetch the pointer to the newly allocated freelist entry. */ 00346 f = ff; 00347 } else { 00348 /** 00349 ** The heap is probably full to the point that we can't allocate 00350 ** a new freelist entry, so let's undo and return an error... 00351 */ 00352 f->size += size; 00353 return (FreeListBlock*)NULL; 00354 } 00355 } 00356 return f; 00357 }


| CMemHeap::FreeListBlock * PikeAero::CMemHeap::_freelist_append | ( | FreeListBlock * | f | ) | [static, private] |
Append a FreeListBlock to the freelist and return a pointer to it.
_freelist_append - append a FreeListBlock to the freelist the contents of the input FreeListBlock struct are copied , so the caller maintains pointer ownership of the input pointer.
Get the target destination for the new freelist entry as well as the new target destination for the new free heap base..
Resize the free pointer that's pointi to the base of the heap area..
we found it, now just resize it and point to the new heap base...
this is an already allocated block. this means the heap is very full and we are having freelist allocation problems. Let's not push it....sorry...
We've sucessfully made room, so now copy the new freelist entry in the freed up heap slot and increment the freelist size.
Definition at line 97 of file cmemheap.cpp.
References _fast_freelist, and memcpy.
Referenced by _freelist_alloc(), and initialize().
00098 { 00099 /** 00100 ** Get the target destination for the new freelist entry as well 00101 ** as the new target destination for the new free heap base.. 00102 */ 00103 CMachine::ubit8* dst = &mHeap[mFreeListSize*sizeof(FreeListBlock)]; 00104 CMachine::ubit8* hbase = &mHeap[(mFreeListSize+1)*sizeof(FreeListBlock)]; 00105 00106 /** 00107 ** Resize the free pointer that's pointi to the base of the heap 00108 ** area.. 00109 */ 00110 CMachine::bit32 i; 00111 for( i=mFreeListSize-1; i >=0; i-- ) 00112 { 00113 FreeListBlock* f = _fast_freelist(i); 00114 if ( f->p == dst ) 00115 { 00116 if ( f->free ) 00117 { 00118 /** we found it, now just resize it and point to the new heap base... */ 00119 f->p = hbase; 00120 f->size -= sizeof(FreeListBlock); 00121 } 00122 else 00123 { 00124 /** 00125 ** this is an already allocated block. 00126 ** this means the heap is very full and 00127 ** we are having freelist allocation 00128 ** problems. Let's not push it....sorry... 00129 */ 00130 return (FreeListBlock*)NULL; 00131 } 00132 } 00133 } 00134 /** 00135 ** We've sucessfully made room, so now copy the new freelist 00136 ** entry in the freed up heap slot and increment the freelist size. 00137 */ 00138 memcpy(dst,f,sizeof(FreeListBlock)); 00139 ++mFreeListSize; 00140 return (FreeListBlock*)dst; 00141 }

| void PikeAero::CMemHeap::_freelist_compress | ( | void | ) | [static, private] |
Remove FreeListBlocks from the freelist which have no size
_freelist_compress - remove 0 size blocks
Definition at line 188 of file cmemheap.cpp.
References _fast_freelist, and _freelist_remove().
Referenced by _freelist_defragment().
00189 { 00190 CMachine::bit32 i; 00191 bool clean; 00192 do { 00193 clean=true; 00194 for( i=0; i < mFreeListSize; i++ ) 00195 { 00196 FreeListBlock* f = _fast_freelist(i); 00197 if ( f->size == 0 ) 00198 { 00199 _freelist_remove(i); 00200 clean=false; 00201 break; 00202 } 00203 } 00204 } while (!clean); 00205 }


| void PikeAero::CMemHeap::_freelist_defragment | ( | void | ) | [static, private] |
Attempt to re-integrate previously split blocks.
_freelist_defragment - attempt to re-integrate previously split blocks.
Definition at line 212 of file cmemheap.cpp.
References _fast_freelist, _freelist_compress(), and _freelist_findfriend().
Referenced by _freelist_free(), and compress().
00213 { 00214 CMachine::bit32 i; 00215 bool clean; 00216 mFreeCount=0; 00217 do 00218 { 00219 clean=true; 00220 for( i=0; i < mFreeListSize; i++ ) 00221 { 00222 FreeListBlock* f = _fast_freelist(i); 00223 if ( f != (FreeListBlock*)NULL && f->free == true && f->size != 0 ) 00224 { 00225 FreeListBlock* ff = _freelist_findfriend(f); 00226 if ( ff != (FreeListBlock*)NULL && ff->size != 0 ) 00227 { 00228 if ( f->p == &(ff->p[ff->size]) ) 00229 { 00230 ff->size += f->size; 00231 f->size=0; 00232 } 00233 else if ( ff->p == &(f->p[f->size]) ) 00234 { 00235 f->size += ff->size; 00236 ff->size=0; 00237 } 00238 clean=false; 00239 break; 00240 } 00241 } 00242 } 00243 } while(!clean); 00244 _freelist_compress(); 00245 }


| CMemHeap::FreeListBlock * PikeAero::CMemHeap::_freelist_find | ( | CMachine::bit32 | size | ) | [static, private] |
Attempt to find a FreeListBlock with enough memory to fit size
_freelist_find - find a free block with enough space to fit requested size.
First, try to find a chuck that fits exactly....
Second, try to find a chuck that fits pretty good.... This assumes that much of the time we will be aloocating objects of the same size, so we look for a block which is at no more than twice the size of what we need so that the remaining free block will at least be able to allocate another of the same object size.
Third, try to find a chuck that fits at all....
Forth, no matching chunk was found...return NULL..
Definition at line 266 of file cmemheap.cpp.
References _fast_freelist.
Referenced by _freelist_alloc().
00267 { 00268 /** 00269 ** First, try to find a chuck that fits exactly.... 00270 */ 00271 for( CMachine::bit32 i=mFreeListSize-1; i >= 0; i-- ) 00272 { 00273 FreeListBlock* f = _fast_freelist(i); 00274 if ( f->free && f->size == size ) 00275 { 00276 return f; 00277 } 00278 } 00279 /** 00280 ** Second, try to find a chuck that fits pretty good.... 00281 ** This assumes that much of the time we will be aloocating 00282 ** objects of the same size, so we look for a block which is at no more than 00283 ** twice the size of what we need so that the remaining free block will 00284 ** at least be able to allocate another of the same object size. 00285 */ 00286 for( CMachine::bit32 i=mFreeListSize-1; i >= 0; i-- ) 00287 { 00288 FreeListBlock* f = _fast_freelist(i); 00289 if ( f->free && f->size > size && f->size <= (size*2) ) 00290 { 00291 return f; 00292 } 00293 } 00294 /** 00295 ** Third, try to find a chuck that fits at all.... 00296 */ 00297 for( CMachine::bit32 i=0; i < mFreeListSize; i++ ) 00298 { 00299 FreeListBlock* f = _fast_freelist(i); 00300 if ( f->free && f->size >= size ) 00301 { 00302 return f; 00303 } 00304 } 00305 /** 00306 ** Forth, no matching chunk was found...return NULL.. 00307 */ 00308 return (FreeListBlock*)NULL; 00309 }

| CMemHeap::FreeListBlock * PikeAero::CMemHeap::_freelist_findfriend | ( | FreeListBlock * | f | ) | [static, private] |
Attempt to find another free block which is contiguous with respect to the input block. Return NULL if not found
_freelist_findfriend - find another free block which is contiguous with respect to the input block.
Definition at line 165 of file cmemheap.cpp.
References _fast_freelist.
Referenced by _freelist_defragment().
00166 { 00167 if ( f->free ) 00168 { 00169 CMachine::bit32 i; 00170 for( i=0; i < mFreeListSize; i++ ) 00171 { 00172 FreeListBlock* ff = _fast_freelist(i); 00173 if ( ff->free && ff->size > 0) 00174 { 00175 if ( f->p == &(ff->p[ff->size]) || ff->p == &(f->p[f->size]) ) 00176 { 00177 return ff; 00178 } 00179 } 00180 } 00181 } 00182 return (FreeListBlock*)NULL; 00183 }

| void PikeAero::CMemHeap::_freelist_free | ( | CMachine::bit32 | i | ) | [static, private] |
Free a FreeListBlock from the freelist. The data pointer is assumed to have been already freed
_freelist_free - free a block
Definition at line 250 of file cmemheap.cpp.
References _freelist(), _freelist_defragment(), and DEFRAG_THRESHOLD.
Referenced by free(), and realloc().
00251 { 00252 FreeListBlock* f = _freelist(i); 00253 if ( f != NULL ) 00254 { 00255 f->free = true; 00256 if ( ++mFreeCount > DEFRAG_THRESHOLD ) 00257 { 00258 _freelist_defragment(); 00259 } 00260 } 00261 }


| CMachine::bit32 PikeAero::CMemHeap::_freelist_locate | ( | void * | ptr | ) | [static, private] |
Get the freelist offset from a FreeListBlock pointer
_freelist_locate - attempt to locate a freelist entry based on a heap memory pointer.
Definition at line 79 of file cmemheap.cpp.
References _fast_freelist.
Referenced by free(), and realloc().
00080 { 00081 for(CMachine::bit32 i=mFreeListSize-1; i >= 0; i-- ) 00082 { 00083 FreeListBlock* f = _fast_freelist(i); 00084 if ( f->p == (CMachine::ubit8*)ptr ) 00085 { 00086 return i; 00087 } 00088 } 00089 return (-1); 00090 }

| bool PikeAero::CMemHeap::_freelist_remove | ( | CMachine::bit32 | index | ) | [static, private] |
Remove a FreeListBlock from the freelist referenced by offset i
_freelist_remove - remove a FreeListBlock from the freelist based on an index reference.
Definition at line 147 of file cmemheap.cpp.
References memmove.
Referenced by _freelist_compress().
00148 { 00149 if ( index < mFreeListSize && mFreeListSize > 0 ) 00150 { 00151 CMachine::bit32 dst = index*sizeof(FreeListBlock); 00152 CMachine::bit32 src = (index+1)*sizeof(FreeListBlock); 00153 CMachine::bit32 len = (mFreeListSize-index)*sizeof(FreeListBlock); 00154 memmove(&mHeap[dst],&mHeap[src],len); 00155 --mFreeListSize; 00156 return true; 00157 } 00158 return false; 00159 }

| CMachine::ubit32 PikeAero::CMemHeap::available | ( | ) | [static] |
available() Total up the amout of available memory on the heap.
Definition at line 464 of file cmemheap.cpp.
References _fast_freelist.
Referenced by PikeAero::CTaskConsolePacket::monitor(), and PikeAero::CTaskConsole::monitor().
00465 { 00466 CMachine::ubit32 size=0; 00467 for( CMachine::bit32 i=0; i < mFreeListSize; i++ ) 00468 { 00469 FreeListBlock* f = _fast_freelist(i); 00470 if ( f->free ) 00471 { 00472 size += f->size - sizeof( FreeListBlock ); 00473 } 00474 } 00475 return size; 00476 }

| CMachine::ubit8 * PikeAero::CMemHeap::bottom | ( | ) | [static] |
bottom() - return the address of the byte at the bottom of the heap space
Definition at line 57 of file cmemheap.cpp.
Referenced by PikeAero::CTaskConsolePacket::monitor(), and PikeAero::CTaskConsole::monitor().

| static void PikeAero::CMemHeap::compress | ( | ) | [inline, static] |
Definition at line 44 of file cmemheap.h.
References _freelist_defragment().
Referenced by PikeAero::CTaskQueue::initialize().
00044 {_freelist_defragment();}


| void PikeAero::CMemHeap::free | ( | void * | ptr | ) | [static] |
free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no opera‐ tion is performed.
Definition at line 436 of file cmemheap.cpp.
References _freelist_free(), and _freelist_locate().
Referenced by PikeAero::CByteArray::clear(), PikeAero::CArray< T >::clear(), PikeAero::CConfiguration::createVolatileRecord(), PikeAero::CConfiguration::disposeVolatile1DMap(), PikeAero::CConfiguration::disposeVolatile2DMap(), PikeAero::CConfiguration::disposeVolatileRecord(), PikeAero::CObject::operator delete(), PikeAero::CObject::operator delete[](), realloc(), PikeAero::CMap::unload(), and PikeAero::CObject::~CObject().
00437 { 00438 CMachine::bit32 i = _freelist_locate(ptr); 00439 if ( i >= 0 ) { 00440 _freelist_free(i); 00441 } 00442 }


| void PikeAero::CMemHeap::initialize | ( | void | ) | [static] |
FIXME - Make this class thread-safe using CMutexLock when accessing the freelist table. FIXME - Emit a CEventTriggerSourceprogramFault on allocation/free errors TODO - Provide an interface for retrieving information about memory usage and fragmentation TODO - use const where applicable
initialize() - initialize memory.
Definition at line 38 of file cmemheap.cpp.
References _freelist_append().
00039 { 00040 FreeListBlock f; 00041 00042 mFreeListSize=0; 00043 mFreeCount=0; 00044 f.free = true; 00045 f.p = &mHeap[sizeof(FreeListBlock)]; 00046 f.size = sizeof(mHeap)-sizeof(FreeListBlock); 00047 _freelist_append(&f); 00048 }

| void * PikeAero::CMemHeap::malloc | ( | CMachine::bit32 | size | ) | [static] |
malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
Adjust size to end up on 32 bit boundary...
Definition at line 363 of file cmemheap.cpp.
References _freelist_alloc().
Referenced by PikeAero::CConfiguration::createVolatile1DMap(), PikeAero::CConfiguration::createVolatile2DMap(), PikeAero::CConfiguration::createVolatileRecord(), PikeAero::CEventQueue::initialize(), PikeAero::CObject::installCallback(), PikeAero::CMap::load(), PikeAero::CObject::operator new(), PikeAero::CObject::operator new[](), and realloc().
00364 { 00365 /** 00366 ** Adjust size to end up on 32 bit boundary... 00367 */ 00368 while ( (size & 0x03) != 0x00 ) 00369 { 00370 ++size; 00371 } 00372 if ( size > 0 ) 00373 { 00374 FreeListBlock* f = _freelist_alloc(size); 00375 if ( f != (FreeListBlock*)NULL ) 00376 { 00377 return f->p; 00378 } 00379 } 00380 return (void*)NULL; 00381 }


| void * PikeAero::CMemHeap::realloc | ( | void * | ptr, | |
| CMachine::bit32 | size | |||
| ) | [static] |
realloc() changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged to the minimum of the old and new sizes; newly allocated memory will be uninitialized. If ptr is NULL, then the call is equivalent to mal‐ loc(size), for all values of size; if size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr). Unless ptr is NULL, it must have been returned by an earlier call to malloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.
Adjust size to end up on 32 bit boundary...
Definition at line 390 of file cmemheap.cpp.
References _fast_freelist, _freelist_free(), _freelist_locate(), free(), malloc(), and memmove.
Referenced by PikeAero::CObjectList::append(), PikeAero::CObjectList::insert(), PikeAero::CObject::installCallback(), PikeAero::CObjectList::remove(), PikeAero::CByteArray::resize(), and PikeAero::CArray< T >::resize().
00391 { 00392 /** 00393 ** Adjust size to end up on 32 bit boundary... 00394 */ 00395 while ( (size & 0x03) != 0x00 ) 00396 { 00397 ++size; 00398 } 00399 if ( ptr != (void*)NULL ) 00400 { 00401 if ( size == 0 ) 00402 { 00403 free( ptr ); 00404 } 00405 else 00406 { 00407 CMachine::bit32 i = _freelist_locate(ptr); 00408 if ( i >= 0 ) 00409 { 00410 FreeListBlock* f = _fast_freelist(i); 00411 CMachine::bit32 s = f->size; 00412 CMachine::ubit8* p = (CMachine::ubit8*)f->p; 00413 if ( f->size < size ) 00414 { 00415 CMachine::ubit8* pp = (CMachine::ubit8*)malloc(size); 00416 _freelist_free(i); 00417 if ( pp != (CMachine::ubit8*)NULL ) 00418 { 00419 memmove(pp,p,s); 00420 } 00421 return pp; 00422 } 00423 return f->p; 00424 } 00425 } 00426 return((void*)NULL); 00427 } 00428 return malloc(size); 00429 }


| CMachine::ubit8 * PikeAero::CMemHeap::top | ( | ) | [static] |
top() - return the address of the byte at the top of the heap space
Definition at line 51 of file cmemheap.cpp.
References HEAP_SIZE.
Referenced by PikeAero::CTaskConsolePacket::monitor(), and PikeAero::CTaskConsole::monitor().
00052 { 00053 return &mHeap[HEAP_SIZE-1]; 00054 }

| CMachine::ubit32 PikeAero::CMemHeap::used | ( | ) | [static] |
used() Total up the amout of used memory on the heap.
Definition at line 447 of file cmemheap.cpp.
References _fast_freelist.
Referenced by PikeAero::CTaskConsolePacket::monitor(), and PikeAero::CTaskConsole::monitor().
00448 { 00449 CMachine::ubit32 size=0; 00450 for( CMachine::bit32 i=0; i < mFreeListSize; i++ ) 00451 { 00452 FreeListBlock* f = _fast_freelist(i); 00453 if ( !f->free ) 00454 { 00455 size += f->size + sizeof( FreeListBlock ); 00456 } 00457 } 00458 return size; 00459 }

1.5.8