ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dfpool.cpp
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Author: David Fournier
5  * Copyright (c) 2008-2012 Regents of the University of California
6  */
11 //#define THREAD_SAFE
12 #include <fvar.hpp>
13 
14 #include <dfpool.h>
15 
16 #if defined(USE_VECTOR_SHAPE_POOL)
17 
20 vector_shape_pool* vector_shapex::xpool = nullptr;
21 
23 {
24  if (arr_link::xpool)
25  {
26  if (arr_link::xpool->num_allocated > 0)
27  {
28  }
29  else
30  {
31  delete arr_link::xpool;
32  arr_link::xpool = nullptr;
33  }
34  }
35  if (vector_shape::xpool)
36  {
37  if (vector_shape::xpool->num_allocated > 0)
38  {
39  }
40  else
41  {
42  delete vector_shape::xpool;
43  vector_shape::xpool = nullptr;
44  }
45  }
46  if (vector_shapex::xpool)
47  {
48  if (vector_shapex::xpool->num_allocated > 0)
49  {
50  }
51  else
52  {
53  delete vector_shapex::xpool;
54  vector_shapex::xpool = nullptr;
55  }
56  }
57 }
58 
59 #if defined(THREAD_SAFE)
60  pthread_mutex_t mutex_dfpool = PTHREAD_MUTEX_INITIALIZER;
61 #endif
62 
63 #if defined(THREAD_SAFE)
65 { ;}
66 #endif
67 
72 void* vector_shape::operator new(size_t n)
73 {
74 #if defined(DEBUG)
75  if (xpool && xpool->size != n)
76  {
77  cerr << "incorrect size requested in dfpool" << endl;
78  ad_exit(1);
79  }
80 #endif
81  if (!xpool)
82  {
83  xpool = new vector_shape_pool(sizeof(vector_shape));
84  }
85  return xpool->alloc();
86 }
87 void vector_shape::operator delete(void* ptr, size_t)
88 {
89  xpool->free(ptr);
90  if (xpool->num_allocated <= 0)
91  {
92  delete xpool;
93  xpool = nullptr;
94  }
95 }
100 void* arr_link::operator new(size_t n)
101 {
102 #if defined(DEBUG)
103  if (xpool && xpool->size != n)
104  {
105  cerr << "incorrect size requested in dfpool" << endl;
106  ad_exit(1);
107  }
108 #endif
109  if (!xpool)
110  {
111  xpool = new vector_shape_pool(sizeof(arr_link));
112  }
113  return xpool->alloc();
114 }
115 void arr_link::operator delete(void* ptr, size_t)
116 {
117  xpool->free(ptr);
118  if (xpool->num_allocated <= 0)
119  {
120  delete xpool;
121  xpool = nullptr;
122  }
123 }
128 void* vector_shapex::operator new(size_t n)
129 {
130 #if defined(DEBUG)
131  if (xpool && xpool->size != n)
132  {
133  cerr << "incorrect size requested in dfpool" << endl;
134  ad_exit(1);
135  }
136 #endif
137  if (!xpool)
138  {
139  xpool = new vector_shape_pool(sizeof(vector_shapex));
140  }
141  return xpool->alloc();
142 }
143 void vector_shapex::operator delete(void* ptr, size_t)
144 {
145  xpool->free(ptr);
146  if (xpool->num_allocated <= 0)
147  {
148  delete xpool;
149  xpool = nullptr;
150  }
151 }
152 
153 #if defined(__CHECK_MEMORY__)
154 
158 void dfpool::sanity_check(void)
159 {
160  link * p=head;
161  int depth=0;
162  while (p)
163  {
164  depth++;
165  if(bad(p))
166  cerr << "Error in dfpool structure" << endl;
167  p=p->next;
168  }
169  cout << "Depth = " << depth << endl;
170 }
171 
176 void dfpool::sanity_check2(void)
177 {
178  link * p=head;
179  int depth=0;
180  while (p)
181  {
182  depth++;
183  if(badaddress(p))
184  cerr << "Error in dfpool adresses" << endl;
185  p=p->next;
186  }
187  cout << "Depth = " << depth << endl;
188 }
189 
194 void dfpool::sanity_check(void * ptr)
195 {
196  link * p=head;
197  int depth=0;
198  while (p)
199  {
200  depth++;
201  if (p == ptr)
202  {
203  cerr << "both allocated and unallocated memory at entry "
204  << depth << endl;
205  break;
206  }
207  p=p->next;
208  }
209 }
210 
215 void dfpool::write_pointers(int mmin,int mmax)
216 {
217  link * p=head;
218  int index=0;
219  while (p)
220  {
221  index++;
222  if (index >=mmin && index <=mmax)
223  cout << index << " " << int(p) << endl;
224  p=p->next;
225  }
226 }
227 #endif
228 
230 
235 void * dfpool::alloc(void)
236 {
237 #if defined(THREAD_SAFE)
238  pthread_mutex_lock(&mutex_dfpool);
239 #endif
240  if (!head) grow();
241  link * p = head;
242  global_p = &head;
243 #if defined(__CHECK_MEMORY__)
244  if(bad(p))
245  {
246  cerr << "Error in dfpool structure" << endl;
247  ad_exit(1);
248  }
249  if (p->next)
250  {
251  if(bad(p->next))
252  {
253  cerr << "Error in dfpool structure" << endl;
254  ad_exit(1);
255  }
256  }
257 #endif
258  head = p->next;
259  num_allocated++;
260  //cout << "allocating " << p << endl;
261 #if defined(__CHECK_MEMORY__)
262  if (p == pchecker)
263  {
264  cout << "trying to allocate already allocated object " << endl;
265  }
266 #endif
267 #if defined(THREAD_SAFE)
268  pthread_mutex_unlock(&mutex_dfpool);
269 #endif
270  return p;
271 }
272 #if defined(THREAD_SAFE)
273 
277 void * tsdfpool::alloc(void)
278 {
279 #if defined(THREAD_SAFE)
280  // pthread_mutex_lock(&mutex_dfpool);
281 #endif
282  if (!head) grow();
283  link * p = head;
284  global_p = &head;
285 #if defined(__CHECK_MEMORY__)
286  if(bad(p))
287  {
288  cerr << "Error in dfpool structure" << endl;
289  ad_exit(1);
290  }
291  if (p->next)
292  {
293  if(bad(p->next))
294  {
295  cerr << "Error in dfpool structure" << endl;
296  ad_exit(1);
297  }
298  }
299 #endif
300  head = p->next;
301  num_allocated++;
302  //cout << "allocating " << p << endl;
303 #if defined(__CHECK_MEMORY__)
304  if (p == pchecker)
305  {
306  cout << "trying to allocate already allocated object " << endl;
307  }
308 #endif
309 #if defined(THREAD_SAFE)
310  //pthread_mutex_unlock(&mutex_dfpool);
311 #endif
312  return p;
313 }
314 #endif
315 
316 #if defined(__CHECK_MEMORY__)
317 
322 int dfpool::bad(link * p)
323 {
324  int flag=1;
325  //if (!df1b2variable::dfpool_counter)
326  {
327  //int ip=(int)p;
328  for (int i=1;i<=99;i++)
329  {
330  if ( p >= minaddress[i] && p <= maxaddress[i])
331  {
332  flag=0;
333  break;
334  }
335  }
336  }
337  //else
338  //{
339  // flag=0;
340  //}
341  if (flag)
342  {
343  cerr << "bad pool object" << endl;
344  }
345  return flag;
346 }
347 
352 int dfpool::badaddress(link * p)
353 {
354  int flag=1;
355  int ip=(int)p;
356  for (int i=0;i<=nalloc;i++)
357  {
358  if ( ip == pvalues[i])
359  {
360  flag=0;
361  break;
362  }
363  }
364  return flag;
365 }
366 void * pchecker=0;
367 #endif
368 
373 void dfpool::free(void * b)
374 {
375 #if defined(THREAD_SAFE)
376  pthread_mutex_lock(&mutex_dfpool);
377 #endif
378 #if defined(__CHECK_MEMORY__)
379  if (pchecker)
380  {
381  if (b == pchecker)
382  {
383  cout << "trying to deallocate allocated object " << endl;
384  }
385  }
386 #endif
387  //cout << "freeing " << b << endl;
388  link * p = (link*) b;
389  p->next = head;
390  num_allocated--;
391  head = p;
392 #if defined(THREAD_SAFE)
393  pthread_mutex_unlock(&mutex_dfpool);
394 #endif
395 }
396 #if defined(THREAD_SAFE)
397 
402 void tsdfpool::free(void * b)
403 {
404 #if defined(THREAD_SAFE)
405  //pthread_mutex_lock(&mutex_dfpool);
406 #endif
407 #if defined(__CHECK_MEMORY__)
408  if (pchecker)
409  {
410  if (b == pchecker)
411  {
412  cout << "trying to deallocate allocated object " << endl;
413  }
414  }
415 #endif
416  //cout << "freeing " << b << endl;
417  link * p = (link*) b;
418  p->next = head;
419  num_allocated--;
420  head = p;
421 #if defined(THREAD_SAFE)
422  //pthread_mutex_unlock(&mutex_dfpool);
423 #endif
424 }
425 #endif
426 
431 {
433  size=0;
434  last_chunk=0;
435  head = 0;
436  num_allocated=0;
437  num_chunks=0;
438 #if defined(__CHECK_MEMORY__)
439  nalloc=0;
440  pvalues=0;
441  maxchunks=0;
442 #endif
443  nvar = 0;
444  nelem = 0;
445  first = NULL;
446 }
450 dfpool::dfpool(const size_t sz):
451  size(sz < sizeof(link *)?sizeof(link*):sz)
452 {
454  if (!sz) size=0;
455  last_chunk=0;
456  head = 0;
457  num_allocated=0;
458  num_chunks=0;
459 #if defined(__CHECK_MEMORY__)
460  nalloc=0;
461  pvalues=0;
462  maxchunks=0;
463 #endif
464  nvar = 0;
465  nelem = 0;
466  first = NULL;
467 }
472 {
473  deallocate();
474 }
479 void dfpool::set_size(const size_t sz)
480 {
481  if (size !=sz && size != 0)
482  cerr << "You can not change the allocation size in mid stream" << endl;
483  else
484  size=sz;
485 }
486 
492 {
493 #if defined(__CHECK_MEMORY__)
494  sanity_check();
495  sanity_check2();
496 #endif
497 #ifdef DEBUG
498  if (num_allocated > 0)
499  {
500  cerr << "Warning: In dfpool::deallocated, "
501  << "the number allocated (" << num_allocated
502  << ") should be zero.\n";
503  }
504 #endif
505  while (num_chunks > 0)
506  {
507  num_chunks--;
508  char * tmp=*(char**) last_chunk;
509  delete [] last_chunk;
510  last_chunk=tmp;
511  }
512  last_chunk=NULL;
513  size=0;
514  head=0;
515  num_allocated=0;
516  first=0;
517 #if defined(__CHECK_MEMORY__)
518  nalloc=0;
519  delete [] pvalues;
520  pvalues=0;
521 #endif
522 }
523 /*
524 void dfpool::deallocate(void)
525 {
526  last_chunk=0
527  size=0;
528  head = 0;
529 }
530 */
531 
536 void dfpool::grow(void)
537 {
538 #if defined(__CHECK_MEMORY__)
539  const int pvalues_size=500000;
540  if (!pvalues)
541  {
542  maxchunks=100;
543  nalloc=0;
544  pvalues=new int[pvalues_size];
545  }
546 #endif
547  const size_t overhead = 12+sizeof(char*);
548  const size_t chunk_size= 65000-overhead;
549 
550  if (size > 0)
551  {
552  nelem = chunk_size / size;
553  }
554  else
555  {
556  cerr << "error in dfpool object " // << poolname
557  << " you must set the unit size " << endl;
558  ad_exit(1);
559  }
560 
561  char * real_start=new char[chunk_size+6];
562  char * start=real_start+sizeof(char *);
563  char *last = &start[(nelem-1)*size];
564  num_chunks++;
565 #if defined(__CHECK_MEMORY__)
566  if (num_chunks<maxchunks)
567  {
568  minaddress[num_chunks]=real_start;
569  maxaddress[num_chunks]=real_start+chunk_size-1;
570  }
571 #endif
572  if (last_chunk == 0 )
573  {
574  last_chunk=real_start;
575  *(char**) real_start=0;
576  }
577  else
578  {
579  *(char**) real_start=last_chunk;
580  last_chunk=real_start;
581  }
582 
583 #if defined(__CHECK_MEMORY__)
584  if (nalloc>pvalues_size-1)
585  {
586  cerr << "Error in check memory need to make pvalues bigger than "
587  << pvalues_size << endl;
588  ad_exit(1);
589  }
590  pvalues[nalloc++]=int(start);
591 #endif
592  for (char *p=start; p<last; p+=size)
593  {
594  ((link *)p)->next = (link*)(p+size);
595 #if defined(__CHECK_MEMORY__)
596  pvalues[nalloc++]=int((link*)(p+size));
597 #endif
598  }
599  ((link*)last)->next=0;
600  head = (link*) start;
601  first= (double*) start;
602 }
603 
608 void dfpool::clean(void)
609 {
610  if (!size)
611  {
612  cerr << "error in dfpool object " // << poolname
613  << " you must set the unit size " << endl;
614  }
615  //const int overhead = 12;
616 
617  double *ptr=first;
618  for (size_t i=1;i<=nelem;i++)
619  {
620  ptr++;
621  for(unsigned int j=1;j<=size/sizeof(double)-2;j++) *ptr++=0.0;
622  ptr++;
623  }
624 }
625 
626 #endif // #if defined(USE_VECTOR_SHAPE_POOL)
int nvar
Definition: dfpool.h:60
void free(void *b)
void grow(void)
Description not yet available.
Definition: dfpool.cpp:536
void free(void *b)
Description not yet available.
Definition: dfpool.cpp:373
size_t size
Definition: dfpool.h:67
void cleanup_xpools()
Definition: dfpool.cpp:22
Description not yet available.
Definition: fvar.hpp:509
exitptr ad_exit
Definition: gradstrc.cpp:53
static vector_shape_pool * xpool
Definition: fvar.hpp:513
void set_size(const size_t)
Description not yet available.
Definition: dfpool.cpp:479
int num_chunks
Definition: dfpool.h:65
dfpool::link ** global_p
Definition: dfpool.cpp:229
void deallocate(void)
Description not yet available.
Definition: dfpool.cpp:491
prnstream & endl(prnstream &)
long int flag
Definition: cbivnorm.cpp:66
virtual ~dfpool()
Destructor.
Definition: dfpool.cpp:471
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
void * alloc(void)
Description not yet available.
Definition: dfpool.cpp:235
void * pchecker
double * first
Definition: dfpool.h:69
Description not yet available.
Definition: dfpool.h:106
link * head
Definition: dfpool.h:68
Holds &quot;shape&quot; information for vector objects.
Definition: vector_shapex.h:46
Description not yet available.
int num_allocated
Definition: dfpool.h:64
int dfpool_vector_flag
Definition: dfpool.h:58
size_t nelem
Definition: dfpool.h:66
dfpool()
Default constructor.
Definition: dfpool.cpp:430
Description not yet available.
Definition: fvar.hpp:480
void clean(void)
Description not yet available.
Definition: dfpool.cpp:608
char * last_chunk
Definition: dfpool.h:62
void * alloc(void)