ADMB Documentation  11.1.2192
 All Classes Files Functions Variables Typedefs Friends Defines
adpool.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: adpool.cpp 1919 2014-04-22 22:02:01Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00012 #include <df1b2fun.h>
00013 #include <adpool.h>
00014 //#define (_USE_VALGRIND_)
00015 
00016 //ofstream xofs("allocation");
00021 int adpool::depth_check(void)
00022 {
00023   link * p=head;
00024   int depth=0;
00025   while (p)
00026   {
00027     depth++;
00028     p=p->next;
00029   }
00030   return depth;
00031 }
00032 
00033 
00034   int adpool::num_adpools=0;
00035 
00036 #if defined(__CHECK_MEMORY__)
00037 
00041 void adpool::sanity_check(void)
00042 {
00043   link * p=head;
00044   int depth=0;
00045   while (p)
00046   {
00047     depth++;
00048     if(bad(p))
00049       cerr << "Error in adpool structure" << endl;
00050     p=p->next;
00051   }
00052   cout << "Depth = " << depth << endl;
00053 }
00054 
00059 void adpool::sanity_check2(void)
00060 {
00061   link * p=head;
00062   int depth=0;
00063   while (p)
00064   {
00065     depth++;
00066     if(badaddress(p))
00067       cerr << "Error in adpool adresses" << endl;
00068     p=p->next;
00069   }
00070   cout << "Depth = " << depth << endl;
00071 }
00072 
00077 void adpool::sanity_check(void * ptr)
00078 {
00079   link * p=head;
00080   int depth=0;
00081   while (p)
00082   {
00083     depth++;
00084     if (p == ptr)
00085     {
00086       cerr << "both allocated and unallocated memory at entry "
00087            << depth << endl;
00088       break;
00089     }
00090     p=p->next;
00091   }
00092 }
00093 
00099 void adpool::write_pointers(int mmin,int mmax)
00100 {
00101   link * p=head;
00102   int index=0;
00103   while (p)
00104   {
00105     index++;
00106     if (index >=mmin && index <=mmax)
00107       cout << index << "  "  << int(p) << endl;
00108     p=p->next;
00109   }
00110 }
00111 #endif
00112 
00116 void* adpool::alloc(void)
00117 {
00118   if (!head)
00119   {
00120     grow();
00121   }
00122   link* p = head;
00123 
00124 #if defined(__CHECK_MEMORY__)
00125   if(bad(p))
00126   {
00127     cerr << "Error in adpool structure" << endl;
00128     ad_exit(1);
00129   }
00130   if (p->next)
00131   {
00132     if(bad(p->next))
00133     {
00134       cerr << "Error in adpool structure" << endl;
00135       ad_exit(1);
00136     }
00137   }
00138 #endif
00139 
00140   head = p->next;
00141   num_allocated++;
00142 
00143 #if defined(__CHECK_MEMORY__)
00144   if (p == pchecker)
00145   {
00146     cout << "trying to allocate already allocated object " << endl;
00147   }
00148 #endif
00149 
00150   ((twointsandptr*)p)->nvar=nvar;
00151   ((twointsandptr*)p)->ptr=this;
00152 #if defined (INCLUDE_BLOCKSIZE)
00153   ((twointsandptr*)p)->blocksize=size;
00154 #endif
00155 
00156   return p;
00157 }
00158 
00159 #if defined(__CHECK_MEMORY__)
00160 
00163 int adpool::bad(link * p)
00164 {
00165   int flag=1;
00166   //if (!df1b2variable::adpool_counter)
00167   {
00168     //int ip=(int)p;
00169     for (int i=1;i<maxchunks;i++)
00170     {
00171       if ( p >= minaddress[i] && p <= maxaddress[i])
00172       {
00173         flag=0;
00174         break;
00175       }
00176     }
00177   }
00178   //else
00179   //{
00180   //  flag=0;
00181   //}
00182   if (flag)
00183   {
00184     cerr << "bad pool object" << endl;
00185   }
00186   return flag;
00187 }
00188 
00193 int adpool::badaddress(link * p)
00194 {
00195   int flag=1;
00196   int ip=(int)p;
00197   for (int i=0;i<=nalloc;i++)
00198   {
00199     if ( ip == pvalues[i])
00200     {
00201       flag=0;
00202       break;
00203     }
00204   }
00205   return flag;
00206 }
00207 void * pchecker=0;
00208 #endif
00209 
00214 void adpool::free(void * b)
00215 {
00216 #if defined(SAFE_ALL)
00217   twointsandptr* tmp = (twointsandptr*)(b);
00218   if (tmp->nvar != nvar)
00219   {
00220     cerr << "trying to add wrong sized memory block to adpool" << endl;
00221     ad_exit(1);
00222   }
00223 #endif
00224 
00225 #if defined (INCLUDE_BLOCKSIZE)
00226 
00227   {
00228     twointsandptr* tmp = (twointsandptr*)(b);
00229     if (tmp->blocksize != size)
00230     {
00231       cerr << "trying to add wrong sized memory block to adpool" << endl;
00232       ad_exit(1);
00233     }
00234   }
00235 #endif
00236 
00237 #if defined(__CHECK_MEMORY__)
00238    if (pchecker)
00239    {
00240      if (b == pchecker)
00241      {
00242        cout << "trying to deallocate allocated object " << endl;
00243      }
00244    }
00245 #endif
00246   //cout << "freeing " << b << endl;
00247   link * p = (link*) b;
00248   p->next = head;
00249   num_allocated--;
00250   head = p;
00251 }
00252 
00257 adpool::~adpool(void)
00258 {
00259   num_adpools--;
00260   deallocate();
00261 }
00262 
00267 adpool::adpool(unsigned sz) : size(sz<sizeof(link *)?sizeof(link*):sz)
00268 {
00269   num_adpools++;
00270   adpool_vector_flag=0;
00271   if (!sz) size=0;
00272   last_chunk=0;
00273   head = 0;
00274   num_allocated=0;
00275   num_chunks=0;
00276 #if defined(__CHECK_MEMORY__)
00277   nalloc=0;
00278   pvalues=0;
00279   maxchunks=0;
00280 #endif
00281 }
00282 
00287 adpool::adpool(void)
00288 {
00289   num_adpools++;
00290   int i1=sizeof(twointsandptr);
00291   int i2=2*sizeof(double);
00292   if (i1>i2)
00293   {
00294     cout << "Error because sizeof(twointsandptr)>2*sizeof(double)" << endl;
00295     ad_exit(1);
00296   }
00297   adpool_vector_flag=0;
00298   size=0;
00299   last_chunk=0;
00300   head = 0;
00301   num_allocated=0;
00302   num_chunks=0;
00303 #if defined(__CHECK_MEMORY__)
00304   nalloc=0;
00305   pvalues=0;
00306   maxchunks=0;
00307 #endif
00308 }
00309 
00315 void adpool::set_size(unsigned int sz)
00316 {
00317   if (size != sz && size != 0)
00318   {
00319     cerr << "You can not change the allocation size in mid stream\n"
00320          << " current size is " << size << " trying to change to "
00321          << sz << '\n';
00322   }
00323   size = sz;
00324 }
00325 
00330 void adpool::deallocate(void)
00331 {
00332 #if defined(__CHECK_MEMORY__)
00333   sanity_check();
00334   sanity_check2();
00335 #endif
00336   while (last_chunk)
00337   {
00338     num_chunks--;
00339     char * tmp=*(char**) last_chunk;
00340     delete [] last_chunk;
00341     last_chunk=tmp;
00342   }
00343   size=0;
00344   head=0;
00345   num_allocated=0;
00346   first=0;
00347 #if defined(__CHECK_MEMORY__)
00348   nalloc=0;
00349   delete [] pvalues;
00350   pvalues=0;
00351 #endif
00352 }
00353 /*
00354 void adpool::deallocate(void)
00355 {
00356   last_chunk=0
00357   size=0;
00358   head = 0;
00359 }
00360 */
00361 
00364 void adpool::grow(void)
00365 {
00366 #if defined(__CHECK_MEMORY__)
00367   const int pvalues_size=500000;
00368   if (!pvalues)
00369   {
00370     maxchunks=20000;
00371     nalloc=0;
00372     pvalues=new int[pvalues_size];
00373   }
00374 #endif
00375 
00376   if (!size)
00377   {
00378     cerr << "error in adpool object " // << poolname
00379          << " you must set the unit size " << endl;
00380     ad_exit(1);
00381   }
00382 
00383   const int overhead = 12 + sizeof(char*);
00384   const int chunk_size = 16 * 65000 - overhead;
00385   char* real_start = new char[chunk_size];
00386   nelem = chunk_size / size;
00387 
00388 #if defined(_USE_VALGRIND_)
00389    VALGRIND_MAKE_MEM_NOACCESS(realstart,chunk_size);
00390 #endif
00391 
00392   char* start = real_start + sizeof(char*);
00393   char* last = &start[(nelem - 1) * size];
00394   num_chunks++;
00395 
00396 #if defined(__CHECK_MEMORY__)
00397   if (num_chunks<maxchunks)
00398   {
00399     minaddress[num_chunks]=(real_start);
00400     maxaddress[num_chunks]=(real_start+chunk_size-1);
00401   }
00402 #endif
00403 
00404   if (last_chunk == 0)
00405   {
00406     last_chunk = real_start;
00407     *(char**)real_start = 0;
00408   }
00409   else
00410   {
00411     *(char**)real_start = last_chunk;
00412     last_chunk = real_start;
00413   }
00414 
00415 #if defined(__CHECK_MEMORY__)
00416   if (nalloc>pvalues_size-1)
00417   {
00418     cerr << "Error in check memory need to make pvalues bigger than "
00419       << pvalues_size << endl;
00420     ad_exit(1);
00421   }
00422   pvalues[nalloc++]=int(start);
00423 #endif
00424 
00425   for (char* p = start; p < last; p += size)
00426   {
00427     ((link *)p)->next = (link*)(p+size);
00428 #if defined(__CHECK_MEMORY__)
00429     pvalues[nalloc++]=int((link*)(p+size));
00430 #endif
00431   }
00432 
00433   ((link*)last)->next = 0;
00434   head = (link*)start;
00435   first = (double*)start;
00436 }
00437 
00442 void adpool::clean(void)
00443 {
00444   if (!size)
00445   {
00446     cerr << "error in adpool object " // << poolname
00447          << " you must set the unit size " << endl;
00448   }
00449   //const int overhead = 12;
00450 
00451   double *ptr=first;
00452   for (int i=1;i<=nelem;i++)
00453   {
00454     ptr++;
00455     for(unsigned int j=1;j<=size/sizeof(double)-2;j++) *ptr++=0.0;
00456     ptr++;
00457   }
00458 }