diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2011-10-10 01:10:31 +0200 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2011-10-10 01:10:31 +0200 |
commit | f0400fbf9b1993ef8c4e722e5bfd32fc53b1b898 (patch) | |
tree | 287992052d2a4f8b80551af50f1e513ead45b9e0 | |
parent | 0f47d350019773a57706b03af5af7440d06840d9 (diff) |
Add memory pool allocator.
-rw-r--r-- | pool.cpp | 5 | ||||
-rw-r--r-- | pool.h | 146 |
2 files changed, 151 insertions, 0 deletions
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; +} @@ -0,0 +1,146 @@ +#ifndef POOL_H +#define POOL_H + +#include "stdint.h" + +template<class T> +class BasePool { + public: + struct Element { + unsigned int use_count; + BasePool* pool; + + char data[sizeof(T)]; + }; + + virtual void free(Element* e) = 0; +}; + +template<class T> +class P { + private: + typedef typename BasePool<T>::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 T, unsigned int size> +class Pool : public BasePool<T> { + private: + typedef typename BasePool<T>::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<T> create() { + Element* e = alloc(); + + if(!e) { + return P<T>(); + } + + new (e->data) T; + + return P<T>(e); + } +}; + +void* operator new(unsigned int, char* buf); + +#endif |