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