Commit | Line | Data |
---|---|---|
3077abb6 MM |
1 | #ifndef _MEMORYPOOL_H |
2 | #define _MEMORYPOOL_H | |
3 | ||
4 | #include <cstdint> | |
5 | // #include <cstdio> | |
6 | #include <cstdlib> | |
7 | ||
8 | #ifdef MEMDEBUG | |
9 | #define MDEBUG(...) printf(__VA_ARGS__) | |
10 | #else | |
11 | #define MDEBUG(...) do {} while (0) | |
12 | #endif | |
13 | ||
1803076a MM |
14 | #include "StreamOutput.h" |
15 | ||
3077abb6 MM |
16 | /* |
17 | * with MUCH thanks to http://www.parashift.com/c++-faq-lite/memory-pools.html | |
18 | * | |
19 | * test framework at https://gist.github.com/triffid/5563987 | |
20 | */ | |
21 | ||
22 | class MemoryPool | |
23 | { | |
24 | public: | |
25 | MemoryPool(void* base, uint16_t size); | |
26 | ~MemoryPool(); | |
27 | ||
28 | void* alloc(size_t); | |
29 | void dealloc(void* p); | |
30 | ||
1803076a | 31 | void debug(StreamOutput*); |
3077abb6 MM |
32 | |
33 | bool has(void*); | |
34 | ||
35 | uint32_t free(void); | |
36 | ||
37 | MemoryPool* next; | |
38 | ||
39 | static MemoryPool* first; | |
40 | ||
41 | private: | |
42 | void* base; | |
43 | uint16_t size; | |
3077abb6 MM |
44 | }; |
45 | ||
46 | // this overloads "placement new" | |
47 | inline void* operator new(size_t nbytes, MemoryPool& pool) | |
48 | { | |
49 | return pool.alloc(nbytes); | |
50 | } | |
51 | ||
52 | // this allows placement new to free memory if the constructor fails | |
53 | inline void operator delete(void* p, MemoryPool& pool) | |
54 | { | |
55 | pool.dealloc(p); | |
56 | } | |
57 | ||
58 | // this catches all usages of delete blah. The object's destructor is called before we get here | |
59 | // it first checks if the deleted object is part of a pool, and uses free otherwise. | |
60 | inline void operator delete(void* p) | |
61 | { | |
62 | MemoryPool* m = MemoryPool::first; | |
63 | while (m) | |
64 | { | |
65 | if (m->has(p)) | |
66 | { | |
67 | MDEBUG("Pool %p has %p, using dealloc()\n", m, p); | |
68 | m->dealloc(p); | |
69 | return; | |
70 | } | |
71 | m = m->next; | |
72 | } | |
73 | ||
74 | MDEBUG("no pool has %p, using free()\n", p); | |
75 | free(p); | |
76 | } | |
77 | ||
78 | #endif /* _MEMORYPOOL_H */ |