Jpp test-rotations-old
the software that should make you happy
Loading...
Searching...
No Matches
JAllocator.hh
Go to the documentation of this file.
1#ifndef __JLANG__JALLOCATOR__
2#define __JLANG__JALLOCATOR__
3
4#include <vector>
5#include <limits>
6
7#include "JLang/JException.hh"
8
9
10/**
11 * \file
12 * Auxiliary class to speed up new/delete operations of any class.
13 * \author mdejong
14 */
15namespace JLANG {}
16namespace JPP { using namespace JLANG; }
17
18namespace JLANG {
19
20 /**
21 * Low-level memory management.
22 *
23 * Source code is taken from reference:
24 * A. Alexandrescu, Modern C++ Design, Addison Wesley.
25 */
27
28 typedef unsigned short JBlock_t;
29
30
31 /**
32 * Constructor.
33 *
34 * \param block_size number of bytes
35 * \param number_of_blocks number of blocks
36 */
37 JAllocatorBuffer(const std::size_t block_size,
38 const JBlock_t number_of_blocks)
39 {
40 buffer = new unsigned char[block_size * number_of_blocks];
41
42 if (buffer == NULL) {
43 THROW(JException, "JAllocatorBuffer::init(): not enough space in memory.");
44 }
45
46 // initialise memory as linked list
47
48 unsigned char* p = buffer;
49
50 for (JBlock_t i = 0; i != number_of_blocks; p += block_size) {
51 ((JBlock_t&) *p) = ++i;
52 }
53
55 numberOfFreeBlocks = number_of_blocks;
56 }
57
58
59 /**
60 * Allocate memory.
61 *
62 * \param block_size number of bytes
63 * \return pointer to available memory
64 */
65 inline void* allocate(const std::size_t block_size)
66 {
67 unsigned char* p = buffer + firstAvailableBlock * block_size;
68
70
72
73 return p;
74 }
75
76
77 /**
78 * Deallocate memory.
79 *
80 * \param p pointer to memory to be freed
81 * \param block_size number of bytes
82 */
83 void free(void* p, const std::size_t block_size)
84 {
85 unsigned char* q = static_cast<unsigned char*>(p);
86
87 if (p < buffer || (q - buffer) % block_size != 0) {
88 THROW(JException, "JAllocatorBuffer::free(): inconsistent pointer.");
89 }
90
92
93 firstAvailableBlock = static_cast<JBlock_t>((q - buffer) / block_size);
94
95 if (firstAvailableBlock != (q - buffer) / block_size) {
96 THROW(JException, "JAllocatorBuffer::free(): failed truncation check.");
97 }
98
100 }
101
102
103 unsigned char* buffer;
106 };
107
108
109 /**
110 * Memory management for small objects.
111 * This object allocator consitutes a comprimise between speed and memory overhead.
112 *
113 * Source code is taken from reference:
114 * A. Alexandrescu, Modern C++ Design, Addison Wesley.
115 */
117 public std::vector<JAllocatorBuffer>
118 {
119 private:
120
122
123 std::size_t BLOCK_SIZE;
125
128
129 public:
130 /**
131 * Constructor.
132 *
133 * \param block_size number of bytes
134 * \param number_of_blocks number of blocks
135 */
136 JAllocator(const std::size_t block_size,
137 const JBlock_t number_of_blocks = std::numeric_limits<JBlock_t>::max()) :
138 std::vector<JAllocatorBuffer>(),
139 BLOCK_SIZE (block_size),
140 numberOfBlocks(number_of_blocks),
141 pAlloc (NULL),
142 pDealloc(NULL)
143 {}
144
145
146 /**
147 * Get total used RAM.
148 *
149 * \return number of bytes
150 */
151 long long int getTotalRAM()
152 {
153 return this->size() * BLOCK_SIZE * numberOfBlocks;
154 }
155
156
157 /**
158 * Get total free RAM.
159 *
160 * \return number of bytes
161 */
162 long long int getFreeRAM()
163 {
164 long long int n = 0;
165
166 for (const_iterator i = this->begin(); i != this->end(); ++i) {
167 n += i->numberOfFreeBlocks;
168 }
169
170 return n * BLOCK_SIZE;
171 }
172
173
174 /**
175 * Allocate memory.
176 *
177 * \return pointer to avaible memory
178 */
179 void* allocate()
180 {
181 if (pAlloc == NULL || pAlloc->numberOfFreeBlocks == 0) {
182
183 for (iterator i = this->begin(); ; ++i) {
184
185 if (i == this->end()) {
186
187 this->push_back(JAllocatorBuffer(BLOCK_SIZE, numberOfBlocks));
188
189 pAlloc = &this->back();
191 break;
192 }
193
194 if (i->numberOfFreeBlocks != 0) {
195
196 pAlloc = &(*i);
197 break;
198 }
199 }
200
201 if (pAlloc == NULL) {
202 THROW(JException, "JAllocator::allocate() no buffer available.");
203 }
204
205 if (pAlloc->numberOfFreeBlocks == 0) {
206 THROW(JException, "JAllocator::allocate() no buffer available.");
207 }
208 }
209
210 return pAlloc->allocate(BLOCK_SIZE);
211 }
212
213
214 /**
215 * Deallocate memory.
216 *
217 * \param p pointer to memory to be freed
218 */
219 void free(void* p)
220 {
221 if (this->size() != 1) {
222
223 if (p < pDealloc->buffer ||
225
226 for (std::vector<JAllocatorBuffer>::iterator i = this->begin(); i != this->end(); ++i) {
227
228 if (p >= i->buffer &&
229 p < i->buffer + numberOfBlocks * BLOCK_SIZE) {
230 pDealloc = &(*i);
231 break;
232 }
233 }
234 }
235 }
236
237
239
240
241 if (this->size() != 1 && pDealloc->numberOfFreeBlocks == numberOfBlocks) {
242
244
245 for ( ; &(*i) != pDealloc && i->numberOfFreeBlocks == numberOfBlocks; ++i) {}
246
247 if (&(*i) != pDealloc) {
248
249 std::swap(*pDealloc, *i);
250
251 if (i != this->rend()) {
252
253 delete [] this->rbegin()->buffer;
254
255 this->pop_back();
256 }
257 }
258 }
259
261 }
262 };
263}
264
265#endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Memory management for small objects.
JAllocatorBuffer * pDealloc
long long int getTotalRAM()
Get total used RAM.
std::size_t BLOCK_SIZE
JAllocator(const std::size_t block_size, const JBlock_t number_of_blocks=std::numeric_limits< JBlock_t >::max())
Constructor.
JAllocatorBuffer::JBlock_t JBlock_t
void * allocate()
Allocate memory.
JBlock_t numberOfBlocks
void free(void *p)
Deallocate memory.
long long int getFreeRAM()
Get total free RAM.
JAllocatorBuffer * pAlloc
General exception.
Definition JException.hh:24
Auxiliary classes and methods for language specific functionality.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Low-level memory management.
Definition JAllocator.hh:26
JAllocatorBuffer(const std::size_t block_size, const JBlock_t number_of_blocks)
Constructor.
Definition JAllocator.hh:37
unsigned char * buffer
unsigned short JBlock_t
Definition JAllocator.hh:28
void free(void *p, const std::size_t block_size)
Deallocate memory.
Definition JAllocator.hh:83
void * allocate(const std::size_t block_size)
Allocate memory.
Definition JAllocator.hh:65