ADMB Documentation  11.5.3197
 All Classes Files Functions Variables Typedefs Friends Defines
dfpool.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id$
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(const size_t 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()
00381 {
00382   dfpool_vector_flag=0;
00383   size=0;
00384   last_chunk=0;
00385   head = 0;
00386   num_allocated=0;
00387   num_chunks=0;
00388 #if defined(__CHECK_MEMORY__)
00389   nalloc=0;
00390   pvalues=0;
00391   maxchunks=0;
00392 #endif
00393   nvar = 0;
00394   nelem = 0;
00395   first = NULL;
00396 }
00400 dfpool::dfpool(const size_t sz):
00401   size(sz < sizeof(link *)?sizeof(link*):sz)
00402 {
00403   dfpool_vector_flag=0;
00404   if (!sz) size=0;
00405   last_chunk=0;
00406   head = 0;
00407   num_allocated=0;
00408   num_chunks=0;
00409 #if defined(__CHECK_MEMORY__)
00410   nalloc=0;
00411   pvalues=0;
00412   maxchunks=0;
00413 #endif
00414   nvar = 0;
00415   nelem = 0;
00416   first = NULL;
00417 }
00421 dfpool::~dfpool()
00422 {
00423   deallocate();
00424 }
00429 void dfpool::set_size(const size_t sz)
00430 {
00431   if (size !=sz && size != 0)
00432     cerr << "You can not change the allocation size in mid stream" << endl;
00433   else
00434     size=sz;
00435 }
00436 
00441 void dfpool::deallocate(void)
00442 {
00443 #if defined(__CHECK_MEMORY__)
00444   sanity_check();
00445   sanity_check2();
00446 #endif
00447   while (last_chunk)
00448   {
00449     num_chunks--;
00450     char * tmp=*(char**) last_chunk;
00451     delete [] last_chunk;
00452     last_chunk=tmp;
00453   }
00454   size=0;
00455   head=0;
00456   num_allocated=0;
00457   first=0;
00458 #if defined(__CHECK_MEMORY__)
00459   nalloc=0;
00460   delete [] pvalues;
00461   pvalues=0;
00462 #endif
00463 }
00464 /*
00465 void dfpool::deallocate(void)
00466 {
00467   last_chunk=0
00468   size=0;
00469   head = 0;
00470 }
00471 */
00472 
00477 void dfpool::grow(void)
00478 {
00479 #if defined(__CHECK_MEMORY__)
00480   const int pvalues_size=500000;
00481   if (!pvalues)
00482   {
00483     maxchunks=100;
00484     nalloc=0;
00485     pvalues=new int[pvalues_size];
00486   }
00487 #endif
00488   const size_t overhead = 12+sizeof(char*);
00489   const size_t chunk_size= 65000-overhead;
00490 
00491   if (size > 0)
00492   {
00493     nelem = chunk_size / size;
00494   }
00495   else
00496   {
00497     cerr << "error in dfpool object " // << poolname
00498          << " you must set the unit size " << endl;
00499     ad_exit(1);
00500   }
00501 
00502   char * real_start=new char[chunk_size+6];
00503   char * start=real_start+sizeof(char *);
00504   char *last = &start[(nelem-1)*size];
00505   num_chunks++;
00506 #if defined(__CHECK_MEMORY__)
00507   if (num_chunks<maxchunks)
00508   {
00509     minaddress[num_chunks]=real_start;
00510     maxaddress[num_chunks]=real_start+chunk_size-1;
00511   }
00512 #endif
00513   if (last_chunk == 0 )
00514   {
00515     last_chunk=real_start;
00516     *(char**) real_start=0;
00517   }
00518   else
00519   {
00520     *(char**) real_start=last_chunk;
00521     last_chunk=real_start;
00522   }
00523 
00524 #if defined(__CHECK_MEMORY__)
00525   if (nalloc>pvalues_size-1)
00526   {
00527     cerr << "Error in check memory need to make pvalues bigger than "
00528       << pvalues_size << endl;
00529     ad_exit(1);
00530   }
00531   pvalues[nalloc++]=int(start);
00532 #endif
00533   for (char *p=start; p<last; p+=size)
00534   {
00535     ((link *)p)->next = (link*)(p+size);
00536 #if defined(__CHECK_MEMORY__)
00537     pvalues[nalloc++]=int((link*)(p+size));
00538 #endif
00539   }
00540   ((link*)last)->next=0;
00541   head = (link*) start;
00542   first= (double*) start;
00543 }
00544 
00549 void dfpool::clean(void)
00550 {
00551   if (!size)
00552   {
00553     cerr << "error in dfpool object " // << poolname
00554          << " you must set the unit size " << endl;
00555   }
00556   //const int overhead = 12;
00557 
00558   double *ptr=first;
00559   for (size_t i=1;i<=nelem;i++)
00560   {
00561     ptr++;
00562     for(unsigned int j=1;j<=size/sizeof(double)-2;j++) *ptr++=0.0;
00563     ptr++;
00564   }
00565 }
00566 
00567 #endif  // #if defined(USE_VECTOR_SHAPE_POOL)