1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
#ifndef _objpool_h_
#define _objpool_h_
#include <stdint.h>
#include <assert.h>
#include <new> /* for placement new */
#ifndef SUPPORT_NO_POOLING
class base_objpool {
public:
base_objpool(uint32_t _count, uint32_t _single);
base_objpool(const base_objpool &pool);
void *generic_request_obj();
protected:
struct _memchunk;
struct _objhead {
/* 2 * sizeof(void *) per object */
_memchunk *parent;
_objhead *next;
uint8_t _obj[0];
} __attribute((packed));
struct _memchunk {
uint8_t *chunk, *endchunk;
uint32_t count, free;
_memchunk *prev, *next;
_objhead *head;
} __attribute((packed));
void base_return_obj(void *obj, _memchunk * &m);
_memchunk *_alloc_chunk(uint32_t count);
void _free_chunk(_memchunk *m);
_memchunk *_find_chunk(_objhead *h);
void _clear_memchunks(_memchunk *);
void _clear_memchunks();
uint32_t granularity, single;
_memchunk *light, *heavy;
};
template<typename objtype>
class objpool : public base_objpool {
public:
objpool(uint32_t _count)
: base_objpool(_count, sizeof(objtype)) {}
objpool(const objpool<objtype> &pool)
: base_objpool(pool) {}
~objpool() {
clear();
}
void clear() {
clear(heavy);
clear(light);
_clear_memchunks();
}
objtype *request_obj() {
void *p = generic_request_obj();
if (!p)
return 0;
/* XXX handle exceptions in constructor */
return new (p) objtype();
}
/* One of each helper method below for the number of arguments */
template <typename Arg>
objtype *request_obj(const Arg &arg) {
void *p = generic_request_obj();
if (!p)
return 0;
/* XXX handle exceptions in constructor */
return new (p) objtype(arg);
}
template <typename Arg1, typename Arg2>
objtype *request_obj(const Arg1 &arg1, const Arg2 &arg2) {
void *p = generic_request_obj();
if (!p)
return 0;
/* XXX handle exceptions in constructor */
return new (p) objtype(arg1, arg2);
}
void return_obj(objtype *obj) {
_memchunk *m;
base_return_obj(obj, m);
obj->~objtype();
if (m->free == m->count) {
if (!m->prev)
light = m->next;
else
m->prev->next = m->next;
_free_chunk(m);
}
}
private:
void clear(_memchunk *head) {
uint32_t one_size = sizeof(_objhead) + sizeof(objtype);
for (; head; head = head->next) {
for (uint8_t *p = head->chunk; p < head->endchunk;
p += one_size) {
_objhead *h = (_objhead *)p;
if (h->next == 0)
((objtype *)&h->_obj)->~objtype();
}
}
}
};
#else
template<typename objtype>
class objpool {
public:
objpool(uint32_t _count) {
}
objpool(const objpool<objtype> &pool) {
}
~objpool() {
}
void clear() {
/* empty */
}
objtype *request_obj() {
return new objtype();
}
template <typename Arg>
objtype *request_obj(const Arg &arg) {
return new objtype(arg);
}
template <typename Arg1, typename Arg2>
objtype *request_obj(const Arg1 &arg1, const Arg2 &arg2) {
return new objtype(arg1, arg2);
}
void return_obj(objtype *obj) {
delete obj;
}
};
#endif
#endif
|