00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 namespace Gecode {
00035
00052
00053 class Region {
00054 private:
00056 class Chunk : public HeapAllocated {
00057 public:
00059 size_t free;
00061 double area[Kernel::MemoryConfig::region_area_size / sizeof(double)];
00063 Chunk* next;
00065 bool alloc(size_t s, void*& p);
00067 void reset(void);
00068 };
00070 Chunk* chunk;
00072 class GECODE_KERNEL_EXPORT Pool {
00073 protected:
00075 Chunk* c;
00077 unsigned int n_c;
00079 Support::Mutex m;
00080 public:
00082 Pool(void);
00084 Chunk* chunk(void);
00086 void chunk(Chunk* u);
00088 ~Pool(void);
00089 };
00091 GECODE_KERNEL_EXPORT static Pool& pool();
00093 class HeapInfo {
00094 public:
00096 unsigned int n;
00098 unsigned int size;
00100 void* blocks[1];
00101 };
00109 void* hi;
00111 GECODE_KERNEL_EXPORT void* heap_alloc(size_t s);
00113 GECODE_KERNEL_EXPORT void heap_free(void);
00114 public:
00116 Region(void);
00123 void free(void);
00125
00126
00132 template<class T>
00133 T* alloc(long unsigned int n);
00140 template<class T>
00141 T* alloc(long int n);
00148 template<class T>
00149 T* alloc(unsigned int n);
00156 template<class T>
00157 T* alloc(int n);
00167 template<class T>
00168 void free(T* b, long unsigned int n);
00178 template<class T>
00179 void free(T* b, long int n);
00189 template<class T>
00190 void free(T* b, unsigned int n);
00200 template<class T>
00201 void free(T* b, int n);
00213 template<class T>
00214 T* realloc(T* b, long unsigned int n, long unsigned int m);
00226 template<class T>
00227 T* realloc(T* b, long int n, long int m);
00239 template<class T>
00240 T* realloc(T* b, unsigned int n, unsigned int m);
00252 template<class T>
00253 T* realloc(T* b, int n, int m);
00255
00256
00257
00258 void* ralloc(size_t s);
00265 void rfree(void* p, size_t s);
00267
00268
00269
00272 template<class T>
00273 T& construct(void);
00279 template<class T, typename A1>
00280 T& construct(A1 const& a1);
00286 template<class T, typename A1, typename A2>
00287 T& construct(A1 const& a1, A2 const& a2);
00293 template<class T, typename A1, typename A2, typename A3>
00294 T& construct(A1 const& a1, A2 const& a2, A3 const& a3);
00300 template<class T, typename A1, typename A2, typename A3, typename A4>
00301 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4);
00307 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
00308 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5);
00310
00311 ~Region(void);
00312 private:
00314 static void* operator new(size_t s) throw() { (void) s; return NULL; }
00316 static void operator delete(void* p) { (void) p; };
00318 Region(const Region&) {}
00320 const Region& operator =(const Region&) { return *this; }
00321 };
00323
00324
00325
00326
00327
00328
00329 forceinline bool
00330 Region::Chunk::alloc(size_t s, void*& p) {
00331 Kernel::MemoryConfig::align(s);
00332 if (s > free)
00333 return false;
00334 free -= s;
00335 p = ptr_cast<char*>(&area[0]) + free;
00336 return true;
00337 }
00338
00339 forceinline void
00340 Region::Chunk::reset(void) {
00341 free = Kernel::MemoryConfig::region_area_size;
00342 }
00343
00344
00345 forceinline
00346 Region::Region(void)
00347 : chunk(pool().chunk()), hi(0) {}
00348
00349 forceinline void
00350 Region::free(void) {
00351 chunk->reset();
00352 }
00353
00354 forceinline void*
00355 Region::ralloc(size_t s) {
00356 void* p;
00357 if (chunk->alloc(s,p))
00358 return p;
00359 else
00360 return heap_alloc(s);
00361 }
00362
00363 forceinline void
00364 Region::rfree(void*, size_t) {}
00365
00366 forceinline
00367 Region::~Region(void) {
00368 pool().chunk(chunk);
00369 if (hi != NULL)
00370 heap_free();
00371 }
00372
00373
00374
00375
00376
00377
00378 template<class T>
00379 forceinline T*
00380 Region::alloc(long unsigned int n) {
00381 T* p = static_cast<T*>(ralloc(sizeof(T)*n));
00382 for (long unsigned int i=n; i--; )
00383 (void) new (p+i) T();
00384 return p;
00385 }
00386 template<class T>
00387 forceinline T*
00388 Region::alloc(long int n) {
00389 assert(n >= 0);
00390 return alloc<T>(static_cast<long unsigned int>(n));
00391 }
00392 template<class T>
00393 forceinline T*
00394 Region::alloc(unsigned int n) {
00395 return alloc<T>(static_cast<long unsigned int>(n));
00396 }
00397 template<class T>
00398 forceinline T*
00399 Region::alloc(int n) {
00400 assert(n >= 0);
00401 return alloc<T>(static_cast<long unsigned int>(n));
00402 }
00403
00404 template<class T>
00405 forceinline void
00406 Region::free(T* b, long unsigned int n) {
00407 for (long unsigned int i=n; i--; )
00408 b[i].~T();
00409 rfree(b,n*sizeof(T));
00410 }
00411 template<class T>
00412 forceinline void
00413 Region::free(T* b, long int n) {
00414 assert(n >= 0);
00415 free<T>(b,static_cast<long unsigned int>(n));
00416 }
00417 template<class T>
00418 forceinline void
00419 Region::free(T* b, unsigned int n) {
00420 free<T>(b,static_cast<long unsigned int>(n));
00421 }
00422 template<class T>
00423 forceinline void
00424 Region::free(T* b, int n) {
00425 assert(n >= 0);
00426 free<T>(b,static_cast<long unsigned int>(n));
00427 }
00428
00429 template<class T>
00430 forceinline T*
00431 Region::realloc(T* b, long unsigned int n, long unsigned int m) {
00432 if (n < m) {
00433 T* p = static_cast<T*>(ralloc(sizeof(T)*m));
00434 for (long unsigned int i=n; i--; )
00435 (void) new (p+i) T(b[i]);
00436 for (long unsigned int i=n; i<m; i++)
00437 (void) new (p+i) T();
00438 free<T>(b,n);
00439 return p;
00440 } else {
00441 free<T>(b+m,m-n);
00442 return b;
00443 }
00444 }
00445 template<class T>
00446 forceinline T*
00447 Region::realloc(T* b, long int n, long int m) {
00448 assert((n >= 0) && (m >= 0));
00449 return realloc<T>(b,static_cast<long unsigned int>(n),
00450 static_cast<long unsigned int>(m));
00451 }
00452 template<class T>
00453 forceinline T*
00454 Region::realloc(T* b, unsigned int n, unsigned int m) {
00455 return realloc<T>(b,static_cast<long unsigned int>(n),
00456 static_cast<long unsigned int>(m));
00457 }
00458 template<class T>
00459 forceinline T*
00460 Region::realloc(T* b, int n, int m) {
00461 assert((n >= 0) && (m >= 0));
00462 return realloc<T>(b,static_cast<long unsigned int>(n),
00463 static_cast<long unsigned int>(m));
00464 }
00465
00466
00467
00468
00469
00470 template<class T>
00471 forceinline T&
00472 Region::construct(void) {
00473 return alloc<T>(1);
00474 }
00475 template<class T, typename A1>
00476 forceinline T&
00477 Region::construct(A1 const& a1) {
00478 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00479 new (&t) T(a1);
00480 return t;
00481 }
00482 template<class T, typename A1, typename A2>
00483 forceinline T&
00484 Region::construct(A1 const& a1, A2 const& a2) {
00485 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00486 new (&t) T(a1,a2);
00487 return t;
00488 }
00489 template<class T, typename A1, typename A2, typename A3>
00490 forceinline T&
00491 Region::construct(A1 const& a1, A2 const& a2, A3 const& a3) {
00492 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00493 new (&t) T(a1,a2,a3);
00494 return t;
00495 }
00496 template<class T, typename A1, typename A2, typename A3, typename A4>
00497 forceinline T&
00498 Region::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) {
00499 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00500 new (&t) T(a1,a2,a3,a4);
00501 return t;
00502 }
00503 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
00504 forceinline T&
00505 Region::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) {
00506 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00507 new (&t) T(a1,a2,a3,a4,a5);
00508 return t;
00509 }
00510
00511 }
00512
00513