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() { return maxget_;} \
24  void free_all(); \
25 private: \
26  void grow(); \
27 private: \
28  T** items_; \
29  T* pool_; \
30  long pool_size_; \
31  long count_; \
32  long get_; \
33  long put_; \
34  long nget_; \
35  long maxget_; \
36  Pool* chain_; \
37  MUTDEC \
38 }; \
39  \
40 
41 #define implementPool(Pool,T) \
42 Pool::Pool(long count, int mkmut) { \
43  count_ = count; \
44  pool_ = new T[count_]; \
45  pool_size_ = count; \
46  items_ = new T*[count_]; \
47  {for (long i = 0; i < count_; ++i) items_[i] = pool_ + i;} \
48  get_ = 0; \
49  put_ = 0; \
50  nget_ = 0; \
51  maxget_ = 0; \
52  chain_ = 0; \
53  MUTCONSTRUCT(mkmut) \
54 } \
55  \
56 void Pool::grow() { \
57  assert(get_ == put_); \
58  Pool* p = new Pool(count_); \
59  p->chain_ = chain_; \
60  chain_ = p; \
61  long newcnt = 2*count_; \
62  T** itms = new T*[newcnt]; \
63  long i, j; \
64  put_ += count_; \
65  {for (i = 0; i < get_; ++i) { \
66  itms[i] = items_[i]; \
67  }} \
68  {for (i = get_, j = 0; j < count_; ++i, ++j) { \
69  itms[i] = p->items_[j]; \
70  }} \
71  {for (i = put_, j = get_; j < count_; ++i, ++j) { \
72  itms[i] = items_[j]; \
73  }} \
74  delete [] items_; \
75  delete [] p->items_; \
76  p->items_ = 0; \
77  items_ = itms; \
78  count_ = newcnt; \
79 } \
80  \
81 Pool::~Pool() { \
82  {if (chain_) { \
83  delete chain_; \
84  }} \
85  delete [] pool_; \
86  {if (items_) { \
87  delete [] items_; \
88  }} \
89  MUTDESTRUCT \
90 } \
91  \
92 T* Pool::alloc() { \
93  MUTLOCK \
94  {if (nget_ >= count_) { grow(); }} \
95  T* item = items_[get_]; \
96  get_ = (get_+1)%count_; \
97  ++nget_; \
98  {if (nget_ > maxget_) { maxget_ = nget_; }} \
99  MUTUNLOCK \
100  return item; \
101 } \
102  \
103 void Pool::hpfree(T* item) { \
104  MUTLOCK \
105  assert(nget_ > 0); \
106  items_[put_] = item; \
107  put_ = (put_ + 1)%count_; \
108  --nget_; \
109  MUTUNLOCK \
110 } \
111 \
112 void Pool::free_all() { \
113  MUTLOCK \
114  Pool* pp; \
115  long i; \
116  nget_ = 0; \
117  get_ = 0; \
118  put_ = 0; \
119  {for(pp = this; pp; pp = pp->chain_) { \
120  for (i=0; i < pp->pool_size_; ++i) { \
121  items_[put_++] = pp->pool_ + i; \
122  pp->pool_[i].clear(); \
123  } \
124  }} \
125  assert(put_ == count_); \
126  put_ = 0; \
127  MUTUNLOCK \
128 } \
129 \
130 
131 #endif