Tulip  4.1.0
Better Visualization Through Research
 All Classes Files Functions Variables Enumerations Enumerator Properties Groups Pages
memorypool.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 ///@cond DOXYGEN_HIDDEN
20 
21 #ifndef MEMORYPOOL_H
22 #define MEMORYPOOL_H
23 #include <vector>
24 #include <iostream>
25 #include <cstdlib>
26 #include <cassert>
27 #ifdef _OPENMP
28 #include <omp.h>
29 #endif
30 
31 #ifdef _OPENMP
32 #define THREAD_NUMBER omp_get_thread_num()
33 static const size_t MAXNBTHREADS = 128;
34 #else
35 #define THREAD_NUMBER 0
36 static const size_t MAXNBTHREADS = 1;
37 #endif
38 
39 static const size_t BUFFOBJ = 20;
40 
41 namespace tlp {
42 /**
43  * @class MemoryPool
44  * \brief That class enables to easily create a memory pool for an a class
45  *
46  * It allocates chunk of BUFFOBJ size of continous memory to allocate
47  * instance of the class. After a delete the memory is not free, and
48  * will be reused at the next new of the class.
49  *
50  * @warning it is not recommended to inherit from an object that inherit of that class
51  *
52  * The following code only calls malloc one time even if NBTRY object are created
53  * in that example, the speedup is about 23, without MemoryPool malloc is called NBTRY times
54  * @code
55  * class A : public MemoryPool<A> {
56  * public:
57  * A(){}
58  * ~A(){}
59  * int data[1000];
60  * };
61  *
62  * size_t NBTRY = 1000 * 1000;
63  * for (size_t j=0; j < NBTRY; ++j) {
64  * A *a = new A();
65  * a->data[100] = j;
66  * r1 += a->data[100];
67  * delete a;
68  * }
69  * @endcode
70  *
71  */
72 template <typename TYPE >
73 class MemoryPool {
74 public:
75  MemoryPool() {
76  }
77 
78 #ifndef NDEBUG
79  inline void *operator new( size_t sizeofObj) {
80 #else
81  inline void *operator new( size_t ) {
82 #endif
83  assert(sizeof(TYPE) == sizeofObj); //to prevent inheritance with different size of object
84  TYPE * t;
85  t = getObject(THREAD_NUMBER);
86  return t;
87  }
88 
89  inline void operator delete( void *p ) {
90  _freeObject[THREAD_NUMBER].push_back(p);
91  }
92 private:
93  static std::vector<void * > _freeObject[MAXNBTHREADS];
94 
95  static TYPE* getObject(size_t threadId) {
96  TYPE *result;
97 
98  if (_freeObject[threadId].empty()) {
99  TYPE * p = (TYPE *)malloc(BUFFOBJ * sizeof(TYPE));
100 
101  for (size_t j=0; j< BUFFOBJ - 1; ++j) {
102  _freeObject[threadId].push_back((void *)p);
103  p += 1;
104  }
105 
106  result = p;
107  }
108  else {
109  result = (TYPE *)_freeObject[threadId].back();
110  _freeObject[threadId].pop_back();
111  }
112 
113  return result;
114  }
115 };
116 
117 template <typename TYPE >
118 std::vector<void * > MemoryPool<TYPE>::_freeObject[MAXNBTHREADS];
119 
120 }
121 #endif // MEMORYPOOL_H
122 ///@endcond