NEURON
pool.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 // create and manage a vector of objects as a memory pool of those objects
4 // the object must have a void clear() method which takes care of any
5 // data the object contains which should be deleted upon free_all.
6 // clear() is NOT called on free, only on free_all.
7 
8 // the chain of Pool
9 // is only for extra items in a pool_ and no other fields are used.
10 // the pool doubles in size every time a chain Pool is added.
11 // maxget() tells the most number of pool items used at once.
12 
13 #include <nrnmutdec.h>
14 
15 #include <cassert>
16 
17 template <typename T>
18 class MutexPool {
19  public:
20  MutexPool(long count, int mkmut = 0);
21  ~MutexPool();
22  T* alloc();
23  void hpfree(T*);
24  int maxget() {
25  return maxget_;
26  }
27  void free_all();
28 
29  private:
30  void grow();
31  T** items_{};
32  T* pool_{};
33  long pool_size_{};
34  long count_{};
35  long get_{};
36  long put_{};
37  long nget_{};
38  long maxget_{};
40  MUTDEC
41 };
42 
43 template <typename T>
44 MutexPool<T>::MutexPool(long count, int mkmut) {
45  count_ = count;
46  pool_ = new T[count_];
47  pool_size_ = count;
48  items_ = new T*[count_];
49  for (long i = 0; i < count_; ++i) {
50  items_[i] = pool_ + i;
51  }
52  MUTCONSTRUCT(mkmut)
53 }
54 
55 template <typename T>
57  assert(get_ == put_);
58  MutexPool<T>* p = new MutexPool<T>(count_);
59  p->chain_ = chain_;
60  chain_ = p;
61  long newcnt = 2 * count_;
62  T** itms = new T*[newcnt];
63  put_ += count_;
64  for (long i = 0; i < get_; ++i) {
65  itms[i] = items_[i];
66  }
67  for (long i = get_, j = 0; j < count_; ++i, ++j) {
68  itms[i] = p->items_[j];
69  }
70  for (long i = put_, j = get_; j < count_; ++i, ++j) {
71  itms[i] = items_[j];
72  }
73  delete[] items_;
74  delete[] p->items_;
75  p->items_ = 0;
76  items_ = itms;
77  count_ = newcnt;
78 }
79 
80 template <typename T>
82  delete chain_;
83  delete[] pool_;
84  delete[] items_;
86 }
87 
88 template <typename T>
90  MUTLOCK
91  if (nget_ >= count_) {
92  grow();
93  }
94  T* item = items_[get_];
95  get_ = (get_ + 1) % count_;
96  ++nget_;
97 
98  maxget_ = std::max(nget_, maxget_);
99 
100  MUTUNLOCK
101  return item;
102 }
103 
104 template <typename T>
105 void MutexPool<T>::hpfree(T* item) {
106  MUTLOCK
107  assert(nget_ > 0);
108  items_[put_] = item;
109  put_ = (put_ + 1) % count_;
110  --nget_;
111  MUTUNLOCK
112 }
113 
114 template <typename T>
116  MUTLOCK
117  MutexPool<T>* pp;
118  long i;
119  nget_ = 0;
120  get_ = 0;
121  put_ = 0;
122  for (pp = this; pp; pp = pp->chain_) {
123  for (i = 0; i < pp->pool_size_; ++i) {
124  items_[put_++] = pp->pool_ + i;
125  pp->pool_[i].clear();
126  }
127  }
128  assert(put_ == count_);
129  put_ = 0;
130  MUTUNLOCK
131 }
long put_
Definition: pool.hpp:36
long maxget_
Definition: pool.hpp:38
MutexPool(long count, int mkmut=0)
Definition: pool.hpp:44
T * alloc()
Definition: pool.hpp:89
long pool_size_
Definition: pool.hpp:33
long nget_
Definition: pool.hpp:37
T * pool_
Definition: pool.hpp:32
void free_all()
Definition: pool.hpp:115
long get_
Definition: pool.hpp:35
void hpfree(T *)
Definition: pool.hpp:105
int maxget()
Definition: pool.hpp:24
void grow()
Definition: pool.hpp:56
T ** items_
Definition: pool.hpp:31
~MutexPool()
Definition: pool.hpp:81
long count_
Definition: pool.hpp:34
MutexPool< T > * chain_
Definition: pool.hpp:39
#define i
Definition: md1redef.h:19
#define assert(ex)
Definition: hocassrt.h:24
size_t p
size_t j
#define MUTCONSTRUCT(mkmut)
Definition: nrnmutdec.h:33
#define MUTDESTRUCT
Definition: nrnmutdec.h:34
#define MUTDEC
Definition: nrnmutdec.h:31
#define MUTLOCK
Definition: nrnmutdec.h:35
#define MUTUNLOCK
Definition: nrnmutdec.h:36