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 #include <cstddef>
00035
00036 namespace Gecode {
00037
00054
00055 class Region {
00056 private:
00058 class Chunk : public HeapAllocated {
00059 public:
00061 size_t free;
00063 alignas((alignof(std::max_align_t) > GECODE_MEMORY_ALIGNMENT) ?
00064 alignof(std::max_align_t) : GECODE_MEMORY_ALIGNMENT)
00065 double area[Kernel::MemoryConfig::region_area_size / sizeof(double)];
00067 Chunk* next;
00069 bool alloc(size_t s, void*& p);
00071 void reset(void);
00072 };
00074 Chunk* chunk;
00076 class GECODE_KERNEL_EXPORT Pool {
00077 protected:
00079 Chunk* c;
00081 unsigned int n_c;
00083 Support::Mutex m;
00084 public:
00086 Pool(void);
00088 Chunk* chunk(void);
00090 void chunk(Chunk* u);
00092 ~Pool(void);
00093 };
00095 GECODE_KERNEL_EXPORT static Pool& pool();
00097 class HeapInfo {
00098 public:
00100 unsigned int n;
00102 unsigned int size;
00104 void* blocks[1];
00105 };
00113 void* hi;
00115 GECODE_KERNEL_EXPORT void* heap_alloc(size_t s);
00117 GECODE_KERNEL_EXPORT void heap_free(void);
00118 public:
00120 Region(void);
00127 void free(void);
00129
00130
00136 template<class T>
00137 T* alloc(long unsigned int n);
00144 template<class T>
00145 T* alloc(long int n);
00152 template<class T>
00153 T* alloc(unsigned int n);
00160 template<class T>
00161 T* alloc(int n);
00171 template<class T>
00172 void free(T* b, long unsigned int n);
00182 template<class T>
00183 void free(T* b, long int n);
00193 template<class T>
00194 void free(T* b, unsigned int n);
00204 template<class T>
00205 void free(T* b, int n);
00217 template<class T>
00218 T* realloc(T* b, long unsigned int n, long unsigned int m);
00230 template<class T>
00231 T* realloc(T* b, long int n, long int m);
00243 template<class T>
00244 T* realloc(T* b, unsigned int n, unsigned int m);
00256 template<class T>
00257 T* realloc(T* b, int n, int m);
00259
00260
00261
00262 void* ralloc(size_t s);
00269 void rfree(void* p, size_t s);
00271
00272
00273
00276 template<class T>
00277 T& construct(void);
00283 template<class T, typename A1>
00284 T& construct(A1 const& a1);
00290 template<class T, typename A1, typename A2>
00291 T& construct(A1 const& a1, A2 const& a2);
00297 template<class T, typename A1, typename A2, typename A3>
00298 T& construct(A1 const& a1, A2 const& a2, A3 const& a3);
00304 template<class T, typename A1, typename A2, typename A3, typename A4>
00305 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4);
00311 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
00312 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5);
00314
00315 ~Region(void);
00316 private:
00318 static void* operator new(size_t s) throw() { (void) s; return NULL; }
00320 static void operator delete(void* p) { (void) p; };
00322 Region(const Region&) {}
00324 const Region& operator =(const Region&) { return *this; }
00325 };
00327
00328
00329
00330
00331
00332
00333 forceinline bool
00334 Region::Chunk::alloc(size_t s, void*& p) {
00335 Kernel::MemoryConfig::align
00336 (s,((alignof(std::max_align_t) > GECODE_MEMORY_ALIGNMENT) ?
00337 alignof(std::max_align_t) : GECODE_MEMORY_ALIGNMENT));
00338 if (s > free)
00339 return false;
00340 free -= s;
00341 p = ptr_cast<char*>(&area[0]) + free;
00342 return true;
00343 }
00344
00345 forceinline void
00346 Region::Chunk::reset(void) {
00347 free = Kernel::MemoryConfig::region_area_size;
00348 }
00349
00350
00351 forceinline
00352 Region::Region(void)
00353 : chunk(pool().chunk()), hi(0) {}
00354
00355 forceinline void
00356 Region::free(void) {
00357 chunk->reset();
00358 }
00359
00360 forceinline void*
00361 Region::ralloc(size_t s) {
00362 void* p;
00363 if (chunk->alloc(s,p))
00364 return p;
00365 else
00366 return heap_alloc(s);
00367 }
00368
00369 forceinline void
00370 Region::rfree(void*, size_t) {}
00371
00372 forceinline
00373 Region::~Region(void) {
00374 pool().chunk(chunk);
00375 if (hi != NULL)
00376 heap_free();
00377 }
00378
00379
00380
00381
00382
00383
00384 template<class T>
00385 forceinline T*
00386 Region::alloc(long unsigned int n) {
00387 T* p = static_cast<T*>(ralloc(sizeof(T)*n));
00388 for (long unsigned int i=0U; i<n; i++)
00389 (void) new (p+i) T();
00390 return p;
00391 }
00392 template<class T>
00393 forceinline T*
00394 Region::alloc(long int n) {
00395 assert(n >= 0);
00396 return alloc<T>(static_cast<long unsigned int>(n));
00397 }
00398 template<class T>
00399 forceinline T*
00400 Region::alloc(unsigned int n) {
00401 return alloc<T>(static_cast<long unsigned int>(n));
00402 }
00403 template<class T>
00404 forceinline T*
00405 Region::alloc(int n) {
00406 assert(n >= 0);
00407 return alloc<T>(static_cast<long unsigned int>(n));
00408 }
00409
00410 template<class T>
00411 forceinline void
00412 Region::free(T* b, long unsigned int n) {
00413 for (long unsigned int i=0U; i<n; i++)
00414 b[i].~T();
00415 rfree(b,n*sizeof(T));
00416 }
00417 template<class T>
00418 forceinline void
00419 Region::free(T* b, long int n) {
00420 assert(n >= 0);
00421 free<T>(b,static_cast<long unsigned int>(n));
00422 }
00423 template<class T>
00424 forceinline void
00425 Region::free(T* b, unsigned int n) {
00426 free<T>(b,static_cast<long unsigned int>(n));
00427 }
00428 template<class T>
00429 forceinline void
00430 Region::free(T* b, int n) {
00431 assert(n >= 0);
00432 free<T>(b,static_cast<long unsigned int>(n));
00433 }
00434
00435 template<class T>
00436 forceinline T*
00437 Region::realloc(T* b, long unsigned int n, long unsigned int m) {
00438 if (n < m) {
00439 T* p = static_cast<T*>(ralloc(sizeof(T)*m));
00440 for (long unsigned int i=0U; i<n; i++)
00441 (void) new (p+i) T(b[i]);
00442 for (long unsigned int i=n; i<m; i++)
00443 (void) new (p+i) T();
00444 free<T>(b,n);
00445 return p;
00446 } else {
00447 free<T>(b+m,m-n);
00448 return b;
00449 }
00450 }
00451 template<class T>
00452 forceinline T*
00453 Region::realloc(T* b, long int n, long int m) {
00454 assert((n >= 0) && (m >= 0));
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, unsigned int n, unsigned int m) {
00461 return realloc<T>(b,static_cast<long unsigned int>(n),
00462 static_cast<long unsigned int>(m));
00463 }
00464 template<class T>
00465 forceinline T*
00466 Region::realloc(T* b, int n, int m) {
00467 assert((n >= 0) && (m >= 0));
00468 return realloc<T>(b,static_cast<long unsigned int>(n),
00469 static_cast<long unsigned int>(m));
00470 }
00471
00472
00473
00474
00475
00476 template<class T>
00477 forceinline T&
00478 Region::construct(void) {
00479 return alloc<T>(1);
00480 }
00481 template<class T, typename A1>
00482 forceinline T&
00483 Region::construct(A1 const& a1) {
00484 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00485 new (&t) T(a1);
00486 return t;
00487 }
00488 template<class T, typename A1, typename A2>
00489 forceinline T&
00490 Region::construct(A1 const& a1, A2 const& a2) {
00491 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00492 new (&t) T(a1,a2);
00493 return t;
00494 }
00495 template<class T, typename A1, typename A2, typename A3>
00496 forceinline T&
00497 Region::construct(A1 const& a1, A2 const& a2, A3 const& a3) {
00498 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00499 new (&t) T(a1,a2,a3);
00500 return t;
00501 }
00502 template<class T, typename A1, typename A2, typename A3, typename A4>
00503 forceinline T&
00504 Region::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) {
00505 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00506 new (&t) T(a1,a2,a3,a4);
00507 return t;
00508 }
00509 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
00510 forceinline T&
00511 Region::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) {
00512 T& t = *static_cast<T*>(ralloc(sizeof(T)));
00513 new (&t) T(a1,a2,a3,a4,a5);
00514 return t;
00515 }
00516
00517 }
00518
00519