Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00012 #include <df1b2fun.h>
00013 #include <adpool.h>
00014 #include <stdint.h>
00015 #ifndef OPT_LIB
00016 #include <cassert>
00017 #include <climits>
00018 #endif
00019
00020
00025 int adpool::depth_check(void)
00026 {
00027 link * p=head;
00028 int depth=0;
00029 while (p)
00030 {
00031 depth++;
00032 p=p->next;
00033 }
00034 return depth;
00035 }
00036
00037
00038 int adpool::num_adpools=0;
00039
00040 #if defined(__CHECK_MEMORY__)
00041
00045 void adpool::sanity_check(void)
00046 {
00047 link * p=head;
00048 int depth=0;
00049 while (p)
00050 {
00051 depth++;
00052 if(bad(p))
00053 cerr << "Error in adpool structure" << endl;
00054 p=p->next;
00055 }
00056 cout << "Depth = " << depth << endl;
00057 }
00058
00063 void adpool::sanity_check2(void)
00064 {
00065 link * p=head;
00066 int depth=0;
00067 while (p)
00068 {
00069 depth++;
00070 if(badaddress(p))
00071 cerr << "Error in adpool adresses" << endl;
00072 p=p->next;
00073 }
00074 cout << "Depth = " << depth << endl;
00075 }
00076
00081 void adpool::sanity_check(void * ptr)
00082 {
00083 link * p=head;
00084 int depth=0;
00085 while (p)
00086 {
00087 depth++;
00088 if (p == ptr)
00089 {
00090 cerr << "both allocated and unallocated memory at entry "
00091 << depth << endl;
00092 break;
00093 }
00094 p=p->next;
00095 }
00096 }
00097
00103 void adpool::write_pointers(int mmin,int mmax)
00104 {
00105 link * p=head;
00106 int index=0;
00107 while (p)
00108 {
00109 index++;
00110 if (index >=mmin && index <=mmax)
00111 cout << index << " " << int(p) << endl;
00112 p=p->next;
00113 }
00114 }
00115 #endif
00116
00120 void* adpool::alloc(void)
00121 {
00122 if (!head)
00123 {
00124 grow();
00125 }
00126 link* p = head;
00127
00128 #if defined(__CHECK_MEMORY__)
00129 if(bad(p))
00130 {
00131 cerr << "Error in adpool structure" << endl;
00132 ad_exit(1);
00133 }
00134 if (p->next)
00135 {
00136 if(bad(p->next))
00137 {
00138 cerr << "Error in adpool structure" << endl;
00139 ad_exit(1);
00140 }
00141 }
00142 #endif
00143
00144 head = p->next;
00145 num_allocated++;
00146
00147 #if defined(__CHECK_MEMORY__)
00148 if (p == pchecker)
00149 {
00150 cout << "trying to allocate already allocated object " << endl;
00151 }
00152 #endif
00153
00154 #ifndef OPT_LIB
00155 assert(nvar <= SHRT_MAX);
00156 #endif
00157 ((twointsandptr*)p)->nvar=(short)nvar;
00158 ((twointsandptr*)p)->ptr=this;
00159 #if defined (INCLUDE_BLOCKSIZE)
00160 ((twointsandptr*)p)->blocksize=size;
00161 #endif
00162
00163 return p;
00164 }
00165
00166 #if defined(__CHECK_MEMORY__)
00167
00170 int adpool::bad(link * p)
00171 {
00172 int flag=1;
00173
00174 {
00175
00176 for (int i=1;i<maxchunks;i++)
00177 {
00178 if ( p >= minaddress[i] && p <= maxaddress[i])
00179 {
00180 flag=0;
00181 break;
00182 }
00183 }
00184 }
00185
00186
00187
00188
00189 if (flag)
00190 {
00191 cerr << "bad pool object" << endl;
00192 }
00193 return flag;
00194 }
00195
00200 int adpool::badaddress(link * p)
00201 {
00202 int flag=1;
00203 int ip=(int)p;
00204 for (int i=0;i<=nalloc;i++)
00205 {
00206 if ( ip == pvalues[i])
00207 {
00208 flag=0;
00209 break;
00210 }
00211 }
00212 return flag;
00213 }
00214 void * pchecker=0;
00215 #endif
00216
00221 void adpool::free(void * b)
00222 {
00223 #if defined(SAFE_ALL)
00224 twointsandptr* tmp = (twointsandptr*)(b);
00225 if (tmp->nvar != nvar)
00226 {
00227 cerr << "trying to add wrong sized memory block to adpool" << endl;
00228 ad_exit(1);
00229 }
00230 #endif
00231
00232 #if defined (INCLUDE_BLOCKSIZE)
00233
00234 {
00235 twointsandptr* tmp = (twointsandptr*)(b);
00236 if (tmp->blocksize != size)
00237 {
00238 cerr << "trying to add wrong sized memory block to adpool" << endl;
00239 ad_exit(1);
00240 }
00241 }
00242 #endif
00243
00244 #if defined(__CHECK_MEMORY__)
00245 if (pchecker)
00246 {
00247 if (b == pchecker)
00248 {
00249 cout << "trying to deallocate allocated object " << endl;
00250 }
00251 }
00252 #endif
00253
00254 link * p = (link*) b;
00255 p->next = head;
00256 num_allocated--;
00257 head = p;
00258 }
00259
00264 adpool::~adpool(void)
00265 {
00266 num_adpools--;
00267 deallocate();
00268 }
00269
00274 adpool::adpool(const size_t sz):
00275 size(sz < sizeof(link*) ? sizeof(link*) : sz)
00276 {
00277 num_adpools++;
00278 adpool_vector_flag=0;
00279 if (!sz) size=0;
00280 last_chunk=0;
00281 head = 0;
00282 num_allocated=0;
00283 num_chunks=0;
00284 #if defined(__CHECK_MEMORY__)
00285 nalloc=0;
00286 pvalues=0;
00287 maxchunks=0;
00288 #endif
00289 }
00290
00294 adpool::adpool()
00295 {
00296 num_adpools++;
00297 size_t i1=sizeof(twointsandptr);
00298 size_t i2=2*sizeof(double);
00299 if (i1>i2)
00300 {
00301 cout << "Error because sizeof(twointsandptr)>2*sizeof(double)" << endl;
00302 ad_exit(1);
00303 }
00304 adpool_vector_flag=0;
00305 size=0;
00306 last_chunk=0;
00307 head = 0;
00308 num_allocated=0;
00309 num_chunks=0;
00310 #if defined(__CHECK_MEMORY__)
00311 nalloc=0;
00312 pvalues=0;
00313 maxchunks=0;
00314 #endif
00315 }
00316
00322 void adpool::set_size(const size_t sz)
00323 {
00324 if (size != sz && size != 0)
00325 {
00326 cerr << "You can not change the allocation size in mid stream\n"
00327 << " current size is " << size << " trying to change to "
00328 << sz << '\n';
00329 }
00330 size = sz;
00331 }
00332
00337 void adpool::deallocate(void)
00338 {
00339 #if defined(__CHECK_MEMORY__)
00340 sanity_check();
00341 sanity_check2();
00342 #endif
00343 while (last_chunk)
00344 {
00345 num_chunks--;
00346 char * tmp=*(char**) last_chunk;
00347 delete [] last_chunk;
00348 last_chunk=tmp;
00349 }
00350 size=0;
00351 head=0;
00352 num_allocated=0;
00353 first=0;
00354 #if defined(__CHECK_MEMORY__)
00355 nalloc=0;
00356 delete [] pvalues;
00357 pvalues=0;
00358 #endif
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00371 void adpool::grow(void)
00372 {
00373 #if defined(__CHECK_MEMORY__)
00374 const int pvalues_size=500000;
00375 if (!pvalues)
00376 {
00377 maxchunks=20000;
00378 nalloc=0;
00379 pvalues=new int[pvalues_size];
00380 }
00381 #endif
00382
00383 const size_t overhead = sizeof(intptr_t);
00384 const size_t chunk_size = 16 * 65000 - overhead;
00385 if (size > 0)
00386 {
00387 nelem = chunk_size / size;
00388 }
00389 else
00390 {
00391 cerr << "error in adpool object "
00392 << " you must set the unit size " << endl;
00393 ad_exit(1);
00394 }
00395 const size_t total_size = overhead + nelem * size;
00396 char* real_start = new char[total_size];
00397 memset(real_start, 0, total_size);
00398
00399 #if defined(_USE_VALGRIND_)
00400 VALGRIND_MAKE_MEM_NOACCESS(realstart,chunk_size);
00401 #endif
00402
00403 char* start = real_start + overhead;
00404 char* last = &start[(nelem - 1) * size];
00405 num_chunks++;
00406
00407 #if defined(__CHECK_MEMORY__)
00408 if (num_chunks<maxchunks)
00409 {
00410 minaddress[num_chunks]=(real_start);
00411 maxaddress[num_chunks]=(real_start+chunk_size-1);
00412 }
00413 #endif
00414
00415 if (last_chunk == 0)
00416 {
00417 last_chunk = real_start;
00418 *(char**)real_start = 0;
00419 }
00420 else
00421 {
00422 *(char**)real_start = last_chunk;
00423 last_chunk = real_start;
00424 }
00425
00426 #if defined(__CHECK_MEMORY__)
00427 if (nalloc>pvalues_size-1)
00428 {
00429 cerr << "Error in check memory need to make pvalues bigger than "
00430 << pvalues_size << endl;
00431 ad_exit(1);
00432 }
00433 pvalues[nalloc++]=int(start);
00434 #endif
00435
00436 for (char* p = start; p < last; p += size)
00437 {
00438 ((link *)p)->next = (link*)(p+size);
00439 #if defined(__CHECK_MEMORY__)
00440 pvalues[nalloc++]=int((link*)(p+size));
00441 #endif
00442 }
00443
00444 ((link*)last)->next = 0;
00445 head = (link*)start;
00446 first = (double*)start;
00447 }
00448
00453 void adpool::clean(void)
00454 {
00455 if (!size)
00456 {
00457 cerr << "error in adpool object "
00458 << " you must set the unit size " << endl;
00459 }
00460
00461
00462 double *ptr=first;
00463 for (size_t i=1;i<=nelem;i++)
00464 {
00465 ptr++;
00466 for(unsigned int j=1;j<=size/sizeof(double)-2;j++) *ptr++=0.0;
00467 ptr++;
00468 }
00469 }