Jpp  18.4.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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  */
15 namespace JLANG {}
16 namespace JPP { using namespace JLANG; }
17 
18 namespace 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 
69  firstAvailableBlock = ((JBlock_t&) *p);
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 
91  ((JBlock_t&) *q) = firstAvailableBlock;
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  */
116  class JAllocator :
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();
190  pDealloc = pAlloc;
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 
238  pDealloc->free(p, BLOCK_SIZE);
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 
260  pAlloc = pDealloc;
261  }
262  };
263 }
264 
265 #endif
General exception.
Definition: JException.hh:24
Exceptions.
long long int getFreeRAM()
Get total free RAM.
Definition: JAllocator.hh:162
JAllocatorBuffer * pDealloc
Definition: JAllocator.hh:127
JAllocator(const std::size_t block_size, const JBlock_t number_of_blocks=std::numeric_limits< JBlock_t >::max())
Constructor.
Definition: JAllocator.hh:136
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
unsigned short JBlock_t
Definition: JAllocator.hh:28
JAllocatorBuffer * pAlloc
Definition: JAllocator.hh:126
JAllocatorBuffer::JBlock_t JBlock_t
Definition: JAllocator.hh:121
void free(void *p, const std::size_t block_size)
Deallocate memory.
Definition: JAllocator.hh:83
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
const int n
Definition: JPolint.hh:786
JBlock_t numberOfBlocks
Definition: JAllocator.hh:124
long long int getTotalRAM()
Get total used RAM.
Definition: JAllocator.hh:151
void free(void *p)
Deallocate memory.
Definition: JAllocator.hh:219
void * allocate(const std::size_t block_size)
Allocate memory.
Definition: JAllocator.hh:65
Memory management for small objects.
Definition: JAllocator.hh:116
unsigned char * buffer
Definition: JAllocator.hh:103
std::size_t BLOCK_SIZE
Definition: JAllocator.hh:123
void * allocate()
Allocate memory.
Definition: JAllocator.hh:179