ADMB Documentation  11.1.2274
 All Classes Files Functions Variables Typedefs Friends Defines
dfpool.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: dfpool.cpp 1948 2014-04-29 18:31:07Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 //#define THREAD_SAFE
00012 #include <fvar.hpp>
00013 
00014 #include <dfpool.h>
00015 
00016 #if defined(USE_VECTOR_SHAPE_POOL)
00017 
00018 #if defined(THREAD_SAFE)
00019   pthread_mutex_t mutex_dfpool = PTHREAD_MUTEX_INITIALIZER;
00020 #endif
00021 
00022 //ofstream xofs("allocation");
00023 vector_shape_pool * vector_shape::xpool =
00024     new vector_shape_pool(sizeof(vector_shape));
00025 
00026 vector_shape_pool * vector_shapex::xpool =
00027     new vector_shape_pool(sizeof(vector_shapex));
00028 
00029 vector_shape_pool  * arr_link::xpool =
00030     new vector_shape_pool (sizeof(arr_link));
00031 
00032 vector_shape_pool::vector_shape_pool(void) : dfpool(sizeof(vector_shape))
00033 { ;}
00034 
00035 #if defined(THREAD_SAFE)
00036 ts_vector_shape_pool::ts_vector_shape_pool(int n) : tsdfpool(n)
00037 { ;}
00038 #endif
00039 
00040 vector_shape_pool::vector_shape_pool(int n) : dfpool(n)
00041 { ;}
00042 
00047 void * vector_shape::operator new(size_t n)
00048 {
00049   if (xpool==0)
00050   {
00051     xpool=new vector_shape_pool(sizeof(vector_shape));
00052   }
00053 # if defined(SAFE_ALL)
00054   if (n != xpool->size)
00055   {
00056     cerr << "incorrect size requested in dfpool" << endl;
00057     ad_exit(1);
00058   }
00059 # endif
00060   return xpool->alloc();
00061 }
00062 
00067 void * arr_link::operator new(size_t n)
00068 {
00069   if (xpool==0)
00070   {
00071     xpool=new vector_shape_pool(sizeof(vector_shape));
00072   }
00073 # if defined(SAFE_ALL)
00074   if (n != xpool->size)
00075   {
00076     cerr << "incorrect size requested in dfpool" << endl;
00077     ad_exit(1);
00078   }
00079 # endif
00080   return xpool->alloc();
00081 }
00082 
00087 void * vector_shapex::operator new(size_t n)
00088 {
00089   if (xpool==0)
00090   {
00091     xpool=new vector_shape_pool(sizeof(vector_shapex));
00092   }
00093 # if defined(SAFE_ALL)
00094   if (n != xpool->size)
00095   {
00096     cerr << "incorrect size requested in dfpool" << endl;
00097     ad_exit(1);
00098   }
00099 # endif
00100   return xpool->alloc();
00101 }
00102 
00103 #if defined(__CHECK_MEMORY__)
00104 
00108 void dfpool::sanity_check(void)
00109 {
00110   link * p=head;
00111   int depth=0;
00112   while (p)
00113   {
00114     depth++;
00115     if(bad(p))
00116       cerr << "Error in dfpool structure" << endl;
00117     p=p->next;
00118   }
00119   cout << "Depth = " << depth << endl;
00120 }
00121 
00126 void dfpool::sanity_check2(void)
00127 {
00128   link * p=head;
00129   int depth=0;
00130   while (p)
00131   {
00132     depth++;
00133     if(badaddress(p))
00134       cerr << "Error in dfpool adresses" << endl;
00135     p=p->next;
00136   }
00137   cout << "Depth = " << depth << endl;
00138 }
00139 
00144 void dfpool::sanity_check(void * ptr)
00145 {
00146   link * p=head;
00147   int depth=0;
00148   while (p)
00149   {
00150     depth++;
00151     if (p == ptr)
00152     {
00153       cerr << "both allocated and unallocated memory at entry "
00154            << depth << endl;
00155       break;
00156     }
00157     p=p->next;
00158   }
00159 }
00160 
00165 void dfpool::write_pointers(int mmin,int mmax)
00166 {
00167   link * p=head;
00168   int index=0;
00169   while (p)
00170   {
00171     index++;
00172     if (index >=mmin && index <=mmax)
00173       cout << index << "  "  << int(p) << endl;
00174     p=p->next;
00175   }
00176 }
00177 #endif
00178 
00179 dfpool::link ** global_p=0;
00180 
00185 void * dfpool::alloc(void)
00186 {
00187 #if defined(THREAD_SAFE)
00188   pthread_mutex_lock(&mutex_dfpool);
00189 #endif
00190   if (!head) grow();
00191   link * p = head;
00192   global_p = &head;
00193 #if defined(__CHECK_MEMORY__)
00194   if(bad(p))
00195   {
00196     cerr << "Error in dfpool structure" << endl;
00197     ad_exit(1);
00198   }
00199   if (p->next)
00200   {
00201     if(bad(p->next))
00202     {
00203       cerr << "Error in dfpool structure" << endl;
00204       ad_exit(1);
00205     }
00206   }
00207 #endif
00208   head = p->next;
00209   num_allocated++;
00210   //cout << "allocating " << p << endl;
00211 #if defined(__CHECK_MEMORY__)
00212   if (p == pchecker)
00213   {
00214     cout << "trying to allocate already allocated object " << endl;
00215   }
00216 #endif
00217 #if defined(THREAD_SAFE)
00218   pthread_mutex_unlock(&mutex_dfpool);
00219 #endif
00220   return p;
00221 }
00222 #if defined(THREAD_SAFE)
00223 
00227 void * tsdfpool::alloc(void)
00228 {
00229 #if defined(THREAD_SAFE)
00230  // pthread_mutex_lock(&mutex_dfpool);
00231 #endif
00232   if (!head) grow();
00233   link * p = head;
00234   global_p = &head;
00235 #if defined(__CHECK_MEMORY__)
00236   if(bad(p))
00237   {
00238     cerr << "Error in dfpool structure" << endl;
00239     ad_exit(1);
00240   }
00241   if (p->next)
00242   {
00243     if(bad(p->next))
00244     {
00245       cerr << "Error in dfpool structure" << endl;
00246       ad_exit(1);
00247     }
00248   }
00249 #endif
00250   head = p->next;
00251   num_allocated++;
00252   //cout << "allocating " << p << endl;
00253 #if defined(__CHECK_MEMORY__)
00254   if (p == pchecker)
00255   {
00256     cout << "trying to allocate already allocated object " << endl;
00257   }
00258 #endif
00259 #if defined(THREAD_SAFE)
00260   //pthread_mutex_unlock(&mutex_dfpool);
00261 #endif
00262   return p;
00263 }
00264 #endif
00265 
00266 #if defined(__CHECK_MEMORY__)
00267 
00272 int dfpool::bad(link * p)
00273 {
00274   int flag=1;
00275   //if (!df1b2variable::dfpool_counter)
00276   {
00277     //int ip=(int)p;
00278     for (int i=1;i<=99;i++)
00279     {
00280       if ( p >= minaddress[i] && p <= maxaddress[i])
00281       {
00282         flag=0;
00283         break;
00284       }
00285     }
00286   }
00287   //else
00288   //{
00289   //  flag=0;
00290   //}
00291   if (flag)
00292   {
00293     cerr << "bad pool object" << endl;
00294   }
00295   return flag;
00296 }
00297 
00302 int dfpool::badaddress(link * p)
00303 {
00304   int flag=1;
00305   int ip=(int)p;
00306   for (int i=0;i<=nalloc;i++)
00307   {
00308     if ( ip == pvalues[i])
00309     {
00310       flag=0;
00311       break;
00312     }
00313   }
00314   return flag;
00315 }
00316 void * pchecker=0;
00317 #endif
00318 
00323 void dfpool::free(void * b)
00324 {
00325 #if defined(THREAD_SAFE)
00326   pthread_mutex_lock(&mutex_dfpool);
00327 #endif
00328 #if defined(__CHECK_MEMORY__)
00329    if (pchecker)
00330    {
00331      if (b == pchecker)
00332      {
00333        cout << "trying to deallocate allocated object " << endl;
00334      }
00335    }
00336 #endif
00337   //cout << "freeing " << b << endl;
00338   link * p = (link*) b;
00339   p->next = head;
00340   num_allocated--;
00341   head = p;
00342 #if defined(THREAD_SAFE)
00343   pthread_mutex_unlock(&mutex_dfpool);
00344 #endif
00345 }
00346 #if defined(THREAD_SAFE)
00347 
00352 void tsdfpool::free(void * b)
00353 {
00354 #if defined(THREAD_SAFE)
00355   //pthread_mutex_lock(&mutex_dfpool);
00356 #endif
00357 #if defined(__CHECK_MEMORY__)
00358    if (pchecker)
00359    {
00360      if (b == pchecker)
00361      {
00362        cout << "trying to deallocate allocated object " << endl;
00363      }
00364    }
00365 #endif
00366   //cout << "freeing " << b << endl;
00367   link * p = (link*) b;
00368   p->next = head;
00369   num_allocated--;
00370   head = p;
00371 #if defined(THREAD_SAFE)
00372   //pthread_mutex_unlock(&mutex_dfpool);
00373 #endif
00374 }
00375 #endif
00376 
00380 dfpool::~dfpool(void)
00381 {
00382   deallocate();
00383 }
00384 
00389 dfpool::dfpool(unsigned sz) : size(sz<sizeof(link *)?sizeof(link*):sz)
00390 {
00391   dfpool_vector_flag=0;
00392   if (!sz) size=0;
00393   last_chunk=0;
00394   head = 0;
00395   num_allocated=0;
00396   num_chunks=0;
00397 #if defined(__CHECK_MEMORY__)
00398   nalloc=0;
00399   pvalues=0;
00400   maxchunks=0;
00401 #endif
00402 }
00403 
00407 dfpool::dfpool(void)
00408 {
00409   dfpool_vector_flag=0;
00410   size=0;
00411   last_chunk=0;
00412   head = 0;
00413   num_allocated=0;
00414   num_chunks=0;
00415 #if defined(__CHECK_MEMORY__)
00416   nalloc=0;
00417   pvalues=0;
00418   maxchunks=0;
00419 #endif
00420 }
00421 
00426 void dfpool::set_size(unsigned int sz)
00427 {
00428   if (size !=sz && size != 0)
00429     cerr << "You can not change the allocation size in mid stream" << endl;
00430   else
00431     size=sz;
00432 }
00433 
00438 void dfpool::deallocate(void)
00439 {
00440 #if defined(__CHECK_MEMORY__)
00441   sanity_check();
00442   sanity_check2();
00443 #endif
00444   while (last_chunk)
00445   {
00446     num_chunks--;
00447     char * tmp=*(char**) last_chunk;
00448     delete [] last_chunk;
00449     last_chunk=tmp;
00450   }
00451   size=0;
00452   head=0;
00453   num_allocated=0;
00454   first=0;
00455 #if defined(__CHECK_MEMORY__)
00456   nalloc=0;
00457   delete [] pvalues;
00458   pvalues=0;
00459 #endif
00460 }
00461 /*
00462 void dfpool::deallocate(void)
00463 {
00464   last_chunk=0
00465   size=0;
00466   head = 0;
00467 }
00468 */
00469 
00474 void dfpool::grow(void)
00475 {
00476 #if defined(__CHECK_MEMORY__)
00477   const int pvalues_size=500000;
00478   if (!pvalues)
00479   {
00480     maxchunks=100;
00481     nalloc=0;
00482     pvalues=new int[pvalues_size];
00483   }
00484 #endif
00485   if (!size)
00486   {
00487     cerr << "error in dfpool object " // << poolname
00488          << " you must set the unit size " << endl;
00489     ad_exit(1);
00490   }
00491   const int overhead = 12+sizeof(char*);
00492   const int chunk_size= 65000-overhead;
00493   nelem= chunk_size/size;
00494   char * real_start=new char[chunk_size+6];
00495   char * start=real_start+sizeof(char *);
00496   char *last = &start[(nelem-1)*size];
00497   num_chunks++;
00498 #if defined(__CHECK_MEMORY__)
00499   if (num_chunks<maxchunks)
00500   {
00501     minaddress[num_chunks]=real_start;
00502     maxaddress[num_chunks]=real_start+chunk_size-1;
00503   }
00504 #endif
00505   if (last_chunk == 0 )
00506   {
00507     last_chunk=real_start;
00508     *(char**) real_start=0;
00509   }
00510   else
00511   {
00512     *(char**) real_start=last_chunk;
00513     last_chunk=real_start;
00514   }
00515 
00516 #if defined(__CHECK_MEMORY__)
00517   if (nalloc>pvalues_size-1)
00518   {
00519     cerr << "Error in check memory need to make pvalues bigger than "
00520       << pvalues_size << endl;
00521     ad_exit(1);
00522   }
00523   pvalues[nalloc++]=int(start);
00524 #endif
00525   for (char *p=start; p<last; p+=size)
00526   {
00527     ((link *)p)->next = (link*)(p+size);
00528 #if defined(__CHECK_MEMORY__)
00529     pvalues[nalloc++]=int((link*)(p+size));
00530 #endif
00531   }
00532   ((link*)last)->next=0;
00533   head = (link*) start;
00534   first= (double*) start;
00535 }
00536 
00541 void dfpool::clean(void)
00542 {
00543   if (!size)
00544   {
00545     cerr << "error in dfpool object " // << poolname
00546          << " you must set the unit size " << endl;
00547   }
00548   //const int overhead = 12;
00549 
00550   double *ptr=first;
00551   for (int i=1;i<=nelem;i++)
00552   {
00553     ptr++;
00554     for(unsigned int j=1;j<=size/sizeof(double)-2;j++) *ptr++=0.0;
00555     ptr++;
00556   }
00557 }
00558 
00559 #endif  // #if defined(USE_VECTOR_SHAPE_POOL)