File: objpool.h

package info (click to toggle)
mrd6 0.9.5-release-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,308 kB
  • ctags: 3,956
  • sloc: cpp: 25,728; perl: 462; makefile: 281; ansic: 142; sh: 67
file content (173 lines) | stat: -rw-r--r-- 3,006 bytes parent folder | download
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