MPQC  3.0.0-alpha
pool.h
1 //
2 // pool.h
3 //
4 // Copyright (C) 1996 Limit Point Systems, Inc.
5 //
6 // Author: Curtis Janssen <cljanss@limitpt.com>
7 // Maintainer: LPS
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 #ifndef _util_group_pool_h
29 #define _util_group_pool_h
30 
31 #include <stdlib.h>
32 #include <new>
33 #include <iostream>
34 
35 #include <util/misc/exenv.h>
36 
37 #undef DEBUG_POOL
38 
39 namespace sc {
40 
41 const int pool_data_alignment_bit = 3;
42 //const int pool_data_alignment_bit = 14;
43 const size_t pool_data_alignment = 1<<pool_data_alignment_bit;
44 inline size_t
45 align_pool_data(size_t size)
46 {
47  return (size + pool_data_alignment - 1)
48  & (~ (pool_data_alignment - 1));
49 }
50 inline void*
51 align_pool_data(void* ptr)
52 {
53  return (void*)( (unsigned long) ((char*)ptr + pool_data_alignment - 1)
54  & (~ (pool_data_alignment - 1)));
55 }
56 inline size_t
57 align_pool_data_downward(size_t size)
58 {
59  return size & (~ (pool_data_alignment - 1));
60 }
61 inline void*
62 align_pool_data_downward(void* ptr)
63 {
64  return (void*) ( (unsigned long) ptr & (~ (pool_data_alignment - 1)));
65 }
66 
67 // ////////////////////////////////////////////////////////////////////////////
68 
69 class PoolData;
70 struct FreeData {
71  PoolData* next_free_;
72  PoolData* prev_free_;
73 };
74 
75 // ////////////////////////////////////////////////////////////////////////////
76 
77 struct UsedData {
78  unsigned int flags;
79  unsigned int held_:16;
80  int priority_:15;
81  unsigned int fixed_:1;
82 };
83 
84 // ////////////////////////////////////////////////////////////////////////////
85 
86 class PoolData {
87  public:
88  enum {magic = 0x1f1d1e1c};
89  int magic_;
90  size_t size_;
91  unsigned int free_:1;
92  unsigned int flags_:15;
93  private:
94  PoolData* next_;
95  PoolData* prev_;
96  public:
97  union {
98  FreeData f;
99  UsedData u;
100  };
101 
102  // Allocates a chunk of free memory, only initializing the size.
103  PoolData(size_t size);
104 
105  PoolData* next();
106  PoolData* prev();
107 
108  void next(PoolData*);
109  void prev(PoolData*);
110  void prev_next(PoolData*,PoolData*);
111 
112  PoolData* next_free();
113  PoolData* prev_free();
114 
115  void next_free(PoolData*);
116  void prev_free(PoolData*);
117  void prev_next_free(PoolData*,PoolData*);
118 
119  void set_magic(int = magic);
120 
121  // This new can only be called with aligned memory.
122  //void* operator new(size_t size, void* placement);
123  void* data();
124 
125  void check(void*lower=(void*)0x0,void*upper=(void*)0x7fffffffL);
126 };
127 
128 const int PoolData_aligned_size = (sizeof(PoolData) + pool_data_alignment - 1)
129  & (~ (pool_data_alignment - 1));
130 inline void* PoolData::data()
131 {
132  return (void*)(((char*)this) + PoolData_aligned_size);
133 }
134 
135 inline PoolData*
136 PoolData::next()
137 {
138  return next_;
139 }
140 
141 inline PoolData*
142 PoolData::prev()
143 {
144  return prev_;
145 }
146 
147 inline void
148 PoolData::next(PoolData*p)
149 {
150  next_ = p;
151 #ifdef DEBUG_POOL
152  if (next_ && prev_ && (next_ < prev_)) {
153  ExEnv::errn() << "PoolData::next(PoolData*): next < prev" << endl;
154  abort();
155  }
156 #endif
157 }
158 
159 inline void
160 PoolData::prev(PoolData*p)
161 {
162  prev_ = p;
163 #ifdef DEBUG_POOL
164  if (next_ && prev_ && (next_ < prev_)) {
165  ExEnv::errn() << "PoolData::prev(PoolData*): next < prev" << endl;
166  abort();
167  }
168 #endif
169 }
170 
171 inline void
172 PoolData::prev_next(PoolData*p,PoolData*n)
173 {
174  prev_ = p;
175  next_ = n;
176 #ifdef DEBUG_POOL
177  if (next_ && prev_ && (next_ < prev_)) {
178  ExEnv::errn() << "PoolData::prev_next: next < prev" << endl;
179  abort();
180  }
181 #endif
182 }
183 
184 // ////
185 
186 inline PoolData*
187 PoolData::next_free()
188 {
189 #ifdef DEBUG_POOL
190  if (!free_) {
191  ExEnv::errn() << "PoolData::next_free(): datum is not free" << endl;
192  abort();
193  }
194 #endif
195  return f.next_free_;
196 }
197 
198 inline PoolData*
199 PoolData::prev_free()
200 {
201 #ifdef DEBUG_POOL
202  if (!free_) {
203  ExEnv::errn() << "PoolData::prev_free(): datum is not free" << endl;
204  abort();
205  }
206 #endif
207  return f.prev_free_;
208 }
209 
210 inline void
211 PoolData::next_free(PoolData*p)
212 {
213 #ifdef DEBUG_POOL
214  if (!free_) {
215  ExEnv::errn() << "PoolData::next_free(PoolData*): datum is not free" << endl;
216  abort();
217  }
218 #endif
219  f.next_free_ = p;
220 }
221 
222 inline void
223 PoolData::prev_free(PoolData*p)
224 {
225 #ifdef DEBUG_POOL
226  if (!free_) {
227  ExEnv::errn() << "PoolData::prev_free(PoolData*): datum is not free" << endl;
228  abort();
229  }
230 #endif
231  f.prev_free_ = p;
232 }
233 
234 inline void
235 PoolData::prev_next_free(PoolData*p,PoolData*n)
236 {
237 #ifdef DEBUG_POOL
238  if (!free_) {
239  ExEnv::errn() << "PoolData::prev_next_free: datum is not free" << endl;
240  abort();
241  }
242 #endif
243  f.prev_free_ = p;
244  f.next_free_ = n;
245 }
246 
247 inline
248 PoolData::PoolData(size_t size):
249  magic_(magic),
250  size_(size-PoolData_aligned_size)
251 {
252 }
253 
254 inline void
255 PoolData::set_magic(int magic_a)
256 {
257  magic_ = magic_a;
258 }
259 
260 // ////////////////////////////////////////////////////////////////////////////
261 
262 class Pool {
263  protected:
264  enum { freelist_size = sizeof(size_t)*8 };
265  PoolData* freelist_[freelist_size];
266 
267  size_t size_;
268 
269  PoolData* firstdatum_;
270  PoolData* voidptr_to_pd(void*d);
271 
272  int freelist_find_slot(size_t);
273  void freelist_add(PoolData*);
274  void freelist_del(PoolData*);
275  public:
276  Pool(size_t);
277  ~Pool();
278 
279 // void* operator new(size_t size, void* placement) { return placement; }
280 
281 // Handle& allocate_handle(size_t size, int priority = 0);
282 // void release(Handle&);
283 
284  size_t size() { return size_; }
285 
286  void* allocate(size_t size);
287  void release(void*d);
288  double* allocate_double(size_t n);
289  void release(double*d);
290  int* allocate_int(size_t n);
291  void release(int*d);
292  void print(std::ostream&o=ExEnv::out0());
293  void check();
294 };
295 
296 inline PoolData*
297 Pool::voidptr_to_pd(void*d)
298 {
299  return (PoolData*)((char*)d - PoolData_aligned_size);
300 }
301 
302 inline double*
303 Pool::allocate_double(size_t n)
304 {
305  return (double*) allocate(n*sizeof(double));
306 }
307 
308 inline void
309 Pool::release(double*d)
310 {
311  release((void*)d);
312 }
313 inline int*
314 Pool::allocate_int(size_t n)
315 {
316  return (int*) allocate(n*sizeof(int));
317 }
318 inline void
319 Pool::release(int*d)
320 {
321  release((void*)d);
322 }
323 
324 }
325 
326 #endif
327 
328 
329 // Local Variables:
330 // mode: c++
331 // c-file-style: "CLJ"
332 // End:
sc::PoolData
Definition: pool.h:86
sc::FreeData
Definition: pool.h:70
sc::Pool
Definition: pool.h:262
sc::ExEnv::errn
static std::ostream & errn()
Return an ostream for error messages that writes from all nodes.
Definition: exenv.h:83
sc::ExEnv::out0
static std::ostream & out0()
Return an ostream that writes from node 0.
sc
Contains all MPQC code up to version 3.
Definition: mpqcin.h:14
sc::UsedData
Definition: pool.h:77

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.