From f0400fbf9b1993ef8c4e722e5bfd32fc53b1b898 Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Mon, 10 Oct 2011 01:10:31 +0200 Subject: Add memory pool allocator. --- pool.cpp | 5 +++ pool.h | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 pool.cpp create mode 100644 pool.h diff --git a/pool.cpp b/pool.cpp new file mode 100644 index 0000000..f059b05 --- /dev/null +++ b/pool.cpp @@ -0,0 +1,5 @@ +#include "pool.h" + +void* operator new(unsigned int, char* buf) { + return (void*)buf; +} diff --git a/pool.h b/pool.h new file mode 100644 index 0000000..1cb0a71 --- /dev/null +++ b/pool.h @@ -0,0 +1,146 @@ +#ifndef POOL_H +#define POOL_H + +#include "stdint.h" + +template +class BasePool { + public: + struct Element { + unsigned int use_count; + BasePool* pool; + + char data[sizeof(T)]; + }; + + virtual void free(Element* e) = 0; +}; + +template +class P { + private: + typedef typename BasePool::Element Element; + + Element* e; + + void inc() { + e->use_count++; + } + + void dec() { + e->use_count--; + if(!e->use_count) { + T* p = (T*)e->data; + p->~T(); + e->pool->free(e); + } + } + + public: + P() : e(0) {} + + explicit P(Element* ep) : e(ep) { + inc(); + } + + P(const P& p) : e(p.e) { + inc(); + } + + ~P() { + if(e) { + dec(); + } + } + + void operator=(const P& p) { + if(e) { + dec(); + } + + e = p.e; + + if(e) { + inc(); + } + } + + void reset() { + if(e) { + dec(); + } + + e = 0; + } + + T* operator->() { + return (T*)e->data; + } + + T* operator*() { + return (T*)e->data; + } + + operator bool() { + return bool(e); + } +}; + +template +class Pool : public BasePool { + private: + typedef typename BasePool::Element Element; + + union Node { + Element e; + Node* next; + }; + + Node elements[size]; + + Node* next_free; + + void free(Element* e) { + Node* n = (Node*)e; + + n->next = next_free; + next_free = n; + } + + Element* alloc() { + if(!next_free) { + return 0; + } + + Element* e = &next_free->e; + next_free = next_free->next; + + e->use_count = 0; + e->pool = this; + + return e; + } + + public: + Pool() : next_free(0) { + for(unsigned int i = 0; i < size; i++) { + free(&elements[i].e); + } + } + + P create() { + Element* e = alloc(); + + if(!e) { + return P(); + } + + new (e->data) T; + + return P(e); + } +}; + +void* operator new(unsigned int, char* buf); + +#endif -- cgit v1.2.3