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