diff options
Diffstat (limited to 'Src/Wasabi/bfc/freelist.cpp')
-rw-r--r-- | Src/Wasabi/bfc/freelist.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/freelist.cpp b/Src/Wasabi/bfc/freelist.cpp new file mode 100644 index 00000000..06a9218d --- /dev/null +++ b/Src/Wasabi/bfc/freelist.cpp @@ -0,0 +1,81 @@ +#include "precomp_wasabi_bfc.h" + +#include "freelist.h" + +// define this to turn off freelist behavior +//#define FREELIST_FUCT + +FreelistPriv::FreelistPriv() { + total_allocated = 0; +} + +FreelistPriv::~FreelistPriv() { +#ifdef ASSERTS_ENABLED +// ASSERTPR(total_allocated == 0, "didn't free entire freelist!(1)"); +// ASSERTPR(blocks.getNumItems() == 0, "didn't free entire freelist!(2)"); + if (total_allocated != 0) DebugStringW(L"didn't free entire freelist!(1)\n"); + if (blocks.getNumItems() != 0) DebugStringW(L"didn't free entire freelist!(2)\n"); +#endif +} + +void *FreelistPriv::getRecord(int typesize, int blocksize, int initialblocksize) { +#ifdef FREELIST_FUCT + return MALLOC(typesize); +#else + ASSERT(typesize >= sizeof(void *)); + FLMemBlock *mem = NULL; + for (int i = 0; i < blocks.getNumItems(); i++) { + mem = blocks[i]; + if (mem->freelist != NULL) break; + mem = NULL; + } + if (mem == NULL) { + // figure record count for this new block + int siz = (blocks.getNumItems() ? blocksize : initialblocksize); + // allocate another block of memory + mem = new FLMemBlock(siz*typesize); + // prelink it into a freelist + char *record = static_cast<char *>(mem->freelist); + void **ptr; + for (int i = 0; i < siz-1; i++) { + ptr = reinterpret_cast<void **>(record); + record += typesize; + *ptr = static_cast<void *>(record); + } + // terminate newly made freelist + ptr = reinterpret_cast<void **>(record); + *ptr = NULL; + blocks.addItem(mem); + } + // get first free record + void *ret = mem->freelist; + // advance freelist * + mem->freelist = *(static_cast<void **>(mem->freelist)); + mem->nallocated++; + total_allocated++; + return ret; +#endif +} + +void FreelistPriv::freeRecord(void *record) { +#ifdef FREELIST_FUCT + FREE(record); +#else + FLMemBlock *mem=NULL; + for (int i = 0; i < blocks.getNumItems(); i++) { + mem = blocks[i]; + if (mem->isMine(reinterpret_cast<MBT*>(record))) break; + mem = NULL; + } + ASSERTPR(mem != NULL, "attempted to free record with no block"); + // stash it back on the block's freelist + *reinterpret_cast<void **>(record) = mem->freelist; + mem->freelist = record; + ASSERT(mem->nallocated > 0); + mem->nallocated--; + if (mem->nallocated == 0) { + blocks.delItem(mem); + } + total_allocated--; +#endif +} |