aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/bfc/freelist.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/bfc/freelist.h')
-rw-r--r--Src/Wasabi/bfc/freelist.h93
1 files changed, 93 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/freelist.h b/Src/Wasabi/bfc/freelist.h
new file mode 100644
index 00000000..dba7e46e
--- /dev/null
+++ b/Src/Wasabi/bfc/freelist.h
@@ -0,0 +1,93 @@
+#ifndef _FREELIST_H
+#define _FREELIST_H
+
+#include <bfc/wasabi_std.h>
+#include <bfc/memblock.h>
+#include <bfc/ptrlist.h>
+
+// actual implementation
+class FreelistPriv {
+protected:
+ FreelistPriv();
+ ~FreelistPriv();
+
+ void *getRecord(int typesize, int blocksize, int initialblocksize);
+ void freeRecord(void *rec);
+
+private:
+ int total_allocated;
+ typedef uint8_t MBT;
+ class FLMemBlock : public MemBlock<MBT> {
+ public:
+ FLMemBlock(int siz) : MemBlock<MBT>(siz) {
+ freelist = getMemory();
+ nallocated = 0;
+ }
+ void *freelist;
+ int nallocated; // # of records assigned from block
+ };
+ PtrList< FLMemBlock > blocks; // the blocks of mem we alloc from
+};
+
+// type-safe template
+static const int DEF_BLOCKSIZE=250;
+template
+<class T, int BLOCKSIZE=DEF_BLOCKSIZE, int INITIALBLOCKSIZE=DEF_BLOCKSIZE, int ALIGNMENT=4>
+class Freelist : private FreelistPriv {
+public:
+ // just returns the memory, you have to call constructor manually
+ T *getRecord() {
+ return static_cast<T *>(FreelistPriv::getRecord(itemsize(), BLOCKSIZE, INITIALBLOCKSIZE));
+ }
+
+ // creates object via default constructor
+ T *newRecord() {
+ T *ret = getRecord();
+#ifdef FORTIFY
+#undef new
+#endif
+ new(ret) T;
+#ifdef FORTIFY
+#define new ZFortify_New
+#endif
+ return ret;
+ }
+
+ // creates object via 1-parameter constructor
+ template<class P1>
+ T *newRecord(P1 p1) {
+ T *ret = getRecord();
+#ifdef FORTIFY
+#undef new
+#endif
+ new(ret) T(p1);
+#ifdef FORTIFY
+#define new ZFortify_New
+#endif
+ return ret;
+ }
+
+ // just frees it, you have to call destructor manually
+ void freeRecord(T *record) { FreelistPriv::freeRecord(record); }
+
+ // calls delete for you, and frees it
+ void deleteRecord(T *record) {
+ if (record != NULL) {
+ record->~T();
+ freeRecord(record);
+ }
+ }
+
+ void deletePtrList(PtrList<T> *list) {
+ ASSERT(list != NULL);
+ for (int i = 0; i < list->getNumItems(); i++) {
+ deleteRecord(list->enumItem(i));
+ }
+ list->removeAll();
+ }
+
+protected:
+ int itemsize() { return (sizeof(T) + (ALIGNMENT-1)) - (sizeof(T) % ALIGNMENT); }
+};
+
+#endif