ADMB Documentation  -a65f1c97
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
adpool.cpp
Go to the documentation of this file.
1 
6 #include <df1b2fun.h>
7 #include <adpool.h>
8 #include <stdint.h>
9 #ifndef OPT_LIB
10  #include <cassert>
11  #include <climits>
12 #endif
13 //#define (_USE_VALGRIND_)
14 
20 {
21  link * p=head;
22  int depth=0;
23  while (p)
24  {
25  depth++;
26  p=p->next;
27  }
28  return depth;
29 }
30 
31 
32  int adpool::num_adpools=0;
33 
34 #if defined(__CHECK_MEMORY__)
35 
39 void adpool::sanity_check(void)
40 {
41  link * p=head;
42  int depth=0;
43  while (p)
44  {
45  depth++;
46  if(bad(p))
47  cerr << "Error in adpool structure" << endl;
48  p=p->next;
49  }
50  cout << "Depth = " << depth << endl;
51 }
52 
57 void adpool::sanity_check2(void)
58 {
59  link * p=head;
60  int depth=0;
61  while (p)
62  {
63  depth++;
64  if(badaddress(p))
65  cerr << "Error in adpool adresses" << endl;
66  p=p->next;
67  }
68  cout << "Depth = " << depth << endl;
69 }
70 
75 void adpool::sanity_check(void * ptr)
76 {
77  link * p=head;
78  int depth=0;
79  while (p)
80  {
81  depth++;
82  if (p == ptr)
83  {
84  cerr << "both allocated and unallocated memory at entry "
85  << depth << endl;
86  break;
87  }
88  p=p->next;
89  }
90 }
91 
97 void adpool::write_pointers(int mmin,int mmax)
98 {
99  link * p=head;
100  int index=0;
101  while (p)
102  {
103  index++;
104  if (index >=mmin && index <=mmax)
105  cout << index << " " << int(p) << endl;
106  p=p->next;
107  }
108 }
109 #endif
110 
114 void* adpool::alloc(void)
115 {
116  if (!head)
117  {
118  grow();
119  }
120  link* p = head;
121 
122 #if defined(__CHECK_MEMORY__)
123  if(bad(p))
124  {
125  cerr << "Error in adpool structure" << endl;
126  ad_exit(1);
127  }
128  if (p->next)
129  {
130  if(bad(p->next))
131  {
132  cerr << "Error in adpool structure" << endl;
133  ad_exit(1);
134  }
135  }
136 #endif
137 
138  head = p->next;
139  num_allocated++;
140 
141 #if defined(__CHECK_MEMORY__)
142  if (p == pchecker)
143  {
144  cout << "trying to allocate already allocated object " << endl;
145  }
146 #endif
147 
148 #ifndef OPT_LIB
149  assert(nvar <= SHRT_MAX);
150 #endif
151  ((twointsandptr*)p)->nvar=(short)nvar;
152  ((twointsandptr*)p)->ptr=this;
153 #if defined (INCLUDE_BLOCKSIZE)
154  ((twointsandptr*)p)->blocksize=size;
155 #endif
156 
157  return p;
158 }
159 
160 #if defined(__CHECK_MEMORY__)
161 
164 int adpool::bad(link * p)
165 {
166  int flag=1;
167  //if (!df1b2variable::adpool_counter)
168  {
169  //int ip=(int)p;
170  for (int i=1;i<maxchunks;i++)
171  {
172  if ( p >= minaddress[i] && p <= maxaddress[i])
173  {
174  flag=0;
175  break;
176  }
177  }
178  }
179  //else
180  //{
181  // flag=0;
182  //}
183  if (flag)
184  {
185  cerr << "bad pool object" << endl;
186  }
187  return flag;
188 }
189 
194 int adpool::badaddress(link * p)
195 {
196  int flag=1;
197  int ip=(int)p;
198  for (int i=0;i<=nalloc;i++)
199  {
200  if ( ip == pvalues[i])
201  {
202  flag=0;
203  break;
204  }
205  }
206  return flag;
207 }
208 void * pchecker=0;
209 #endif
210 
215 void adpool::free(void * b)
216 {
217 #if defined(SAFE_ALL)
218  twointsandptr* tmp = (twointsandptr*)(b);
219  if (tmp->nvar != nvar)
220  {
221  cerr << "trying to add wrong sized memory block to adpool" << endl;
222  ad_exit(1);
223  }
224 #endif
225 
226 #if defined (INCLUDE_BLOCKSIZE)
227 
228  {
229  twointsandptr* tmp = (twointsandptr*)(b);
230  if (tmp->blocksize != size)
231  {
232  cerr << "trying to add wrong sized memory block to adpool" << endl;
233  ad_exit(1);
234  }
235  }
236 #endif
237 
238 #if defined(__CHECK_MEMORY__)
239  if (pchecker)
240  {
241  if (b == pchecker)
242  {
243  cout << "trying to deallocate allocated object " << endl;
244  }
245  }
246 #endif
247  //cout << "freeing " << b << endl;
248  link * p = (link*) b;
249  p->next = head;
250  num_allocated--;
251  head = p;
252 }
253 
256 {
257  --num_adpools;
258  deallocate();
259 }
260 
266 adpool::adpool(const size_t sz):
267  nvar(0),
268  last_chunk(NULL),
269  num_allocated(0),
270  num_chunks(0),
271  nelem(0),
272  size(0),
273  head(NULL),
274  first(NULL)
275 {
276  num_adpools++;
277  size_t i1=sizeof(twointsandptr);
278  size_t i2=2*sizeof(double);
279  if (i1>i2)
280  {
281  cout << "Error because sizeof(twointsandptr)>2*sizeof(double)" << endl;
282  ad_exit(1);
283  }
285  if (sz)
286  {
287  size = sz < sizeof(link*) ? sizeof(link*) : sz;
288  }
289 #if defined(__CHECK_MEMORY__)
290  nalloc=0;
291  pvalues=0;
292  maxchunks=0;
293 #endif
294 }
295 
298 
304 void adpool::set_size(const size_t sz)
305 {
306  if (size != sz && size != 0)
307  {
308  cerr << "You can not change the allocation size in mid stream\n"
309  << " current size is " << size << " trying to change to "
310  << sz << '\n';
311  }
312  size = sz;
313 }
314 
320 {
321 #if defined(__CHECK_MEMORY__)
322  sanity_check();
323  sanity_check2();
324 #endif
325  while (last_chunk)
326  {
327  num_chunks--;
328  char * tmp=*(char**) last_chunk;
329  delete [] last_chunk;
330  last_chunk=tmp;
331  }
332  size=0;
333  head=0;
334  num_allocated=0;
335  first=0;
336 #if defined(__CHECK_MEMORY__)
337  nalloc=0;
338  delete [] pvalues;
339  pvalues=0;
340 #endif
341 }
342 /*
343 void adpool::deallocate(void)
344 {
345  last_chunk=0
346  size=0;
347  head = 0;
348 }
349 */
350 
353 void adpool::grow(void)
354 {
355 #if defined(__CHECK_MEMORY__)
356  const int pvalues_size=500000;
357  if (!pvalues)
358  {
359  maxchunks=20000;
360  nalloc=0;
361  pvalues=new int[pvalues_size];
362  }
363 #endif
364 
365  const size_t overhead = sizeof(intptr_t);
366  const size_t chunk_size = 16 * 65000 - overhead;
367  if (size > 0)
368  {
369  nelem = chunk_size / size;
370  }
371  else
372  {
373  cerr << "error in adpool object " // << poolname
374  << " you must set the unit size " << endl;
375  ad_exit(1);
376  }
377  const size_t total_size = overhead + nelem * size;
378  char* real_start = new char[total_size];
379  memset(real_start, 0, total_size);
380 
381 #if defined(_USE_VALGRIND_)
382  VALGRIND_MAKE_MEM_NOACCESS(realstart,chunk_size);
383 #endif
384 
385  char* start = real_start + overhead;
386  char* last = &start[(nelem - 1) * size];
387  num_chunks++;
388 
389 #if defined(__CHECK_MEMORY__)
390  if (num_chunks<maxchunks)
391  {
392  minaddress[num_chunks]=(real_start);
393  maxaddress[num_chunks]=(real_start+chunk_size-1);
394  }
395 #endif
396 
397  if (last_chunk == 0)
398  {
399  last_chunk = real_start;
400  *(char**)real_start = 0;
401  }
402  else
403  {
404  *(char**)real_start = last_chunk;
405  last_chunk = real_start;
406  }
407 
408 #if defined(__CHECK_MEMORY__)
409  if (nalloc>pvalues_size-1)
410  {
411  cerr << "Error in check memory need to make pvalues bigger than "
412  << pvalues_size << endl;
413  ad_exit(1);
414  }
415  pvalues[nalloc++]=int(start);
416 #endif
417 
418  for (char* p = start; p < last; p += size)
419  {
420  ((link *)p)->next = (link*)(p+size);
421 #if defined(__CHECK_MEMORY__)
422  pvalues[nalloc++]=int((link*)(p+size));
423 #endif
424  }
425 
426  ((link*)last)->next = 0;
427  head = (link*)start;
428  first = (double*)start;
429 }
430 
435 void adpool::clean(void)
436 {
437  if (!size)
438  {
439  cerr << "error in adpool object " // << poolname
440  << " you must set the unit size " << endl;
441  }
442  //const int overhead = 12;
443 
444  double *ptr=first;
445  for (size_t i=1;i<=nelem;i++)
446  {
447  ptr++;
448  for(unsigned int j=1;j<=size/sizeof(double)-2;j++) *ptr++=0.0;
449  ptr++;
450  }
451 }
size_t nelem
Definition: adpool.h:83
char * last_chunk
Definition: adpool.h:79
double * first
Definition: adpool.h:86
size_t size
Definition: adpool.h:84
void clean(void)
Description not yet available.
Definition: adpool.cpp:435
short int nvar
Definition: df1b2fun.h:83
~adpool()
Destructor.
Definition: adpool.cpp:255
int num_chunks
Definition: adpool.h:82
link * head
Definition: adpool.h:85
exitptr ad_exit
Definition: gradstrc.cpp:53
void deallocate(void)
Description not yet available.
Definition: adpool.cpp:319
void set_size(const size_t)
Set size of adpool.
Definition: adpool.cpp:304
Description not yet available.
Definition: adpool.h:59
int num_allocated
Definition: adpool.h:81
int depth_check(void)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Definition: adpool.cpp:19
prnstream & endl(prnstream &)
long int flag
Definition: cbivnorm.cpp:66
int adpool_vector_flag
Definition: adpool.h:62
static int num_adpools
Definition: adpool.h:61
void * alloc(void)
Allocate memory for link*.
Definition: adpool.cpp:114
void * pchecker
void free(void *b)
Description not yet available.
Definition: adpool.cpp:215
adpool()
Default constructor.
Definition: adpool.cpp:297
Description not yet available.
Definition: df1b2fun.h:79
void grow(void)
Definition: adpool.cpp:353
Description not yet available.
Description not yet available.
unsigned int nvar
Definition: adpool.h:77