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
00035
00036
00037
00038 #include <cstring>
00039 #include <cstdlib>
00040 #include <algorithm>
00041
00042 #ifdef GECODE_PEAKHEAP_MALLOC_H
00043 #include <malloc.h>
00044 #endif
00045
00046 #ifdef GECODE_PEAKHEAP_MALLOC_MALLOC_H
00047 #include <malloc/malloc.h>
00048 #endif
00049
00050 namespace Gecode {
00051
00066 class Heap {
00067 public:
00069 Heap(void);
00071
00072
00078 template<class T>
00079 T* alloc(long unsigned int n);
00086 template<class T>
00087 T* alloc(long int n);
00094 template<class T>
00095 T* alloc(unsigned int n);
00102 template<class T>
00103 T* alloc(int n);
00110 template<class T>
00111 void free(T* b, long unsigned int n);
00118 template<class T>
00119 void free(T* b, long int n);
00126 template<class T>
00127 void free(T* b, unsigned int n);
00134 template<class T>
00135 void free(T* b, int n);
00147 template<class T>
00148 T* realloc(T* b, long unsigned int n, long unsigned int m);
00160 template<class T>
00161 T* realloc(T* b, long int n, long int m);
00173 template<class T>
00174 T* realloc(T* b, unsigned int n, unsigned int m);
00186 template<class T>
00187 T* realloc(T* b, int n, int m);
00195 template<class T>
00196 T** realloc(T** b, long unsigned int n, long unsigned int m);
00204 template<class T>
00205 T** realloc(T** b, long int n, long int m);
00213 template<class T>
00214 T** realloc(T** b, unsigned int n, unsigned int m);
00222 template<class T>
00223 T** realloc(T** b, int n, int m);
00232 template<class T>
00233 static T* copy(T* d, const T* s, long unsigned int n);
00242 template<class T>
00243 static T* copy(T* d, const T* s, long int n);
00252 template<class T>
00253 static T* copy(T* d, const T* s, unsigned int n);
00262 template<class T>
00263 static T* copy(T* d, const T* s, int n);
00271 template<class T>
00272 static T** copy(T** d, const T** s, long unsigned int n);
00280 template<class T>
00281 static T** copy(T** d, const T** s, long int n);
00289 template<class T>
00290 static T** copy(T** d, const T** s, unsigned int n);
00298 template<class T>
00299 static T** copy(T** d, const T** s, int n);
00301
00302
00303
00304 void* ralloc(size_t s);
00306 void rfree(void* p);
00308 void rfree(void* p, size_t s);
00310 void* rrealloc(void* p, size_t s);
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 Heap(const Heap&) {}
00320 const Heap& operator =(const Heap&) { return *this; }
00321 #ifdef GECODE_PEAKHEAP
00322
00323 Support::FastMutex _m;
00325 size_t _peak;
00327 size_t _cur;
00328 public:
00329 size_t peak(void);
00330 #endif
00331 };
00332
00337 extern GECODE_SUPPORT_EXPORT
00338 Heap heap;
00339
00344 class GECODE_SUPPORT_EXPORT HeapAllocated {
00345 public:
00347
00348
00349 static void* operator new(size_t s);
00351 static void operator delete(void* p);
00353 };
00354
00355
00356
00357
00358
00359
00360 forceinline void*
00361 Heap::ralloc(size_t s) {
00362 void* p = Support::allocator.alloc(s);
00363 #ifdef GECODE_PEAKHEAP
00364 _m.acquire();
00365 _cur += GECODE_MSIZE(p);
00366 _peak = std::max(_peak,_cur);
00367 _m.release();
00368 #endif
00369 if (p != NULL)
00370 return p;
00371 throw MemoryExhausted();
00372 }
00373
00374 forceinline void
00375 Heap::rfree(void* p) {
00376 #ifdef GECODE_PEAKHEAP
00377 _m.acquire();
00378 _cur -= GECODE_MSIZE(p);
00379 _m.release();
00380 #endif
00381 Support::allocator.free(p);
00382 }
00383
00384 forceinline void
00385 Heap::rfree(void* p, size_t) {
00386 #ifdef GECODE_PEAKHEAP
00387 _m.acquire();
00388 _cur -= GECODE_MSIZE(p);
00389 _m.release();
00390 #endif
00391 Support::allocator.free(p);
00392 }
00393
00394 forceinline void*
00395 Heap::rrealloc(void* p, size_t s) {
00396 #ifdef GECODE_PEAKHEAP
00397 _m.acquire();
00398 _cur -= GECODE_MSIZE(p);
00399 _m.release();
00400 #endif
00401 p = Support::allocator.realloc(p,s);
00402 #ifdef GECODE_PEAKHEAP
00403 _m.acquire();
00404 _cur += GECODE_MSIZE(p);
00405 _peak = std::max(_peak,_cur);
00406 _m.release();
00407 #endif
00408 if (p != NULL || s == 0)
00409 return p;
00410 throw MemoryExhausted();
00411 }
00412
00413
00414
00415
00416
00417
00418 forceinline void*
00419 HeapAllocated::operator new(size_t s) {
00420 return heap.ralloc(s);
00421 }
00422 forceinline void
00423 HeapAllocated::operator delete(void* p) {
00424 heap.rfree(p);
00425 }
00426
00427
00428
00429
00430
00431
00432
00433 template<class T>
00434 forceinline T*
00435 Heap::alloc(long unsigned int n) {
00436 T* p = static_cast<T*>(ralloc(sizeof(T)*n));
00437 for (long unsigned int i=n; i--; )
00438 (void) new (p+i) T();
00439 return p;
00440 }
00441 template<class T>
00442 forceinline T*
00443 Heap::alloc(long int n) {
00444 assert(n >= 0);
00445 return alloc<T>(static_cast<long unsigned int>(n));
00446 }
00447 template<class T>
00448 forceinline T*
00449 Heap::alloc(unsigned int n) {
00450 return alloc<T>(static_cast<long unsigned int>(n));
00451 }
00452 template<class T>
00453 forceinline T*
00454 Heap::alloc(int n) {
00455 assert(n >= 0);
00456 return alloc<T>(static_cast<long unsigned int>(n));
00457 }
00458
00459 template<class T>
00460 forceinline void
00461 Heap::free(T* b, long unsigned int n) {
00462 for (long unsigned int i=n; i--; )
00463 b[i].~T();
00464 rfree(b);
00465 }
00466 template<class T>
00467 forceinline void
00468 Heap::free(T* b, long int n) {
00469 assert(n >= 0);
00470 free<T>(b, static_cast<long unsigned int>(n));
00471 }
00472 template<class T>
00473 forceinline void
00474 Heap::free(T* b, unsigned int n) {
00475 free<T>(b, static_cast<long unsigned int>(n));
00476 }
00477 template<class T>
00478 forceinline void
00479 Heap::free(T* b, int n) {
00480 assert(n >= 0);
00481 free<T>(b, static_cast<long unsigned int>(n));
00482 }
00483
00484 template<class T>
00485 forceinline T*
00486 Heap::realloc(T* b, long unsigned int n, long unsigned int m) {
00487 if (n == m)
00488 return b;
00489 T* p = static_cast<T*>(ralloc(sizeof(T)*m));
00490 for (long unsigned int i=std::min(n,m); i--; )
00491 (void) new (p+i) T(b[i]);
00492 for (long unsigned int i=n; i<m; i++)
00493 (void) new (p+i) T();
00494 free<T>(b,n);
00495 return p;
00496 }
00497 template<class T>
00498 forceinline T*
00499 Heap::realloc(T* b, long int n, long int m) {
00500 assert((n >= 0) && (m >= 0));
00501 return realloc<T>(b,static_cast<long unsigned int>(n),
00502 static_cast<long unsigned int>(m));
00503 }
00504 template<class T>
00505 forceinline T*
00506 Heap::realloc(T* b, unsigned int n, unsigned int m) {
00507 return realloc<T>(b,static_cast<long unsigned int>(n),
00508 static_cast<long unsigned int>(m));
00509 }
00510 template<class T>
00511 forceinline T*
00512 Heap::realloc(T* b, int n, int m) {
00513 assert((n >= 0) && (m >= 0));
00514 return realloc<T>(b,static_cast<long unsigned int>(n),
00515 static_cast<long unsigned int>(m));
00516 }
00517
00518 #define GECODE_SUPPORT_REALLOC(T) \
00519 template<> \
00520 forceinline T* \
00521 Heap::realloc<T>(T* b, long unsigned int, long unsigned int m) { \
00522 return static_cast<T*>(rrealloc(b,m*sizeof(T))); \
00523 } \
00524 template<> \
00525 forceinline T* \
00526 Heap::realloc<T>(T* b, long int n, long int m) { \
00527 assert((n >= 0) && (m >= 0)); \
00528 return realloc<T>(b,static_cast<long unsigned int>(n), \
00529 static_cast<long unsigned int>(m)); \
00530 } \
00531 template<> \
00532 forceinline T* \
00533 Heap::realloc<T>(T* b, unsigned int n, unsigned int m) { \
00534 return realloc<T>(b,static_cast<long unsigned int>(n), \
00535 static_cast<long unsigned int>(m)); \
00536 } \
00537 template<> \
00538 forceinline T* \
00539 Heap::realloc<T>(T* b, int n, int m) { \
00540 assert((n >= 0) && (m >= 0)); \
00541 return realloc<T>(b,static_cast<long unsigned int>(n), \
00542 static_cast<long unsigned int>(m)); \
00543 }
00544
00545 GECODE_SUPPORT_REALLOC(bool)
00546 GECODE_SUPPORT_REALLOC(signed char)
00547 GECODE_SUPPORT_REALLOC(unsigned char)
00548 GECODE_SUPPORT_REALLOC(signed short int)
00549 GECODE_SUPPORT_REALLOC(unsigned short int)
00550 GECODE_SUPPORT_REALLOC(signed int)
00551 GECODE_SUPPORT_REALLOC(unsigned int)
00552 GECODE_SUPPORT_REALLOC(signed long int)
00553 GECODE_SUPPORT_REALLOC(unsigned long int)
00554 GECODE_SUPPORT_REALLOC(float)
00555 GECODE_SUPPORT_REALLOC(double)
00556
00557 #undef GECODE_SUPPORT_REALLOC
00558
00559 template<class T>
00560 forceinline T**
00561 Heap::realloc(T** b, long unsigned int, long unsigned int m) {
00562 return static_cast<T**>(rrealloc(b,m*sizeof(T*)));
00563 }
00564 template<class T>
00565 forceinline T**
00566 Heap::realloc(T** b, long int n, long int m) {
00567 assert((n >= 0) && (m >= 0));
00568 return realloc<T*>(b,static_cast<long unsigned int>(n),
00569 static_cast<long unsigned int>(m));
00570 }
00571 template<class T>
00572 forceinline T**
00573 Heap::realloc(T** b, unsigned int n, unsigned int m) {
00574 return realloc<T*>(b,static_cast<long unsigned int>(n),
00575 static_cast<long unsigned int>(m));
00576 }
00577 template<class T>
00578 forceinline T**
00579 Heap::realloc(T** b, int n, int m) {
00580 assert((n >= 0) && (m >= 0));
00581 return realloc<T*>(b,static_cast<long unsigned int>(n),
00582 static_cast<long unsigned int>(m));
00583 }
00584
00585 template<class T>
00586 forceinline T*
00587 Heap::copy(T* d, const T* s, long unsigned int n) {
00588 for (long unsigned int i=n; i--; )
00589 d[i]=s[i];
00590 return d;
00591 }
00592 template<class T>
00593 forceinline T*
00594 Heap::copy(T* d, const T* s, long int n) {
00595 assert(n >= 0);
00596 return copy<T>(d,s,static_cast<long unsigned int>(n));
00597 }
00598 template<class T>
00599 forceinline T*
00600 Heap::copy(T* d, const T* s, unsigned int n) {
00601 return copy<T>(d,s,static_cast<long unsigned int>(n));
00602 }
00603 template<class T>
00604 forceinline T*
00605 Heap::copy(T* d, const T* s, int n) {
00606 assert(n >= 0);
00607 return copy<T>(d,s,static_cast<long unsigned int>(n));
00608 }
00609
00610 #define GECODE_SUPPORT_COPY(T) \
00611 template<> \
00612 forceinline T* \
00613 Heap::copy(T* d, const T* s, long unsigned int n) { \
00614 return static_cast<T*>(Support::allocator.memcpy(d,s,n*sizeof(T))); \
00615 } \
00616 template<> \
00617 forceinline T* \
00618 Heap::copy(T* d, const T* s, long int n) { \
00619 assert(n >= 0); \
00620 return copy<T>(d,s,static_cast<long unsigned int>(n)); \
00621 } \
00622 template<> \
00623 forceinline T* \
00624 Heap::copy(T* d, const T* s, unsigned int n) { \
00625 return copy<T>(d,s,static_cast<long unsigned int>(n)); \
00626 } \
00627 template<> \
00628 forceinline T* \
00629 Heap::copy(T* d, const T* s, int n) { \
00630 assert(n >= 0); \
00631 return copy<T>(d,s,static_cast<long unsigned int>(n)); \
00632 }
00633
00634 GECODE_SUPPORT_COPY(bool)
00635 GECODE_SUPPORT_COPY(signed char)
00636 GECODE_SUPPORT_COPY(unsigned char)
00637 GECODE_SUPPORT_COPY(signed short int)
00638 GECODE_SUPPORT_COPY(unsigned short int)
00639 GECODE_SUPPORT_COPY(signed int)
00640 GECODE_SUPPORT_COPY(unsigned int)
00641 GECODE_SUPPORT_COPY(signed long int)
00642 GECODE_SUPPORT_COPY(unsigned long int)
00643 GECODE_SUPPORT_COPY(float)
00644 GECODE_SUPPORT_COPY(double)
00645
00646 #undef GECODE_SUPPORT_COPY
00647
00648 template<class T>
00649 forceinline T**
00650 Heap::copy(T** d, const T** s, long unsigned int n) {
00651 return static_cast<T**>(Support::allocator.memcpy(d,s,n*sizeof(T*)));
00652 }
00653 template<class T>
00654 forceinline T**
00655 Heap::copy(T** d, const T** s, long int n) {
00656 assert(n >= 0);
00657 return copy<T*>(d,s,static_cast<long unsigned int>(n));
00658 }
00659 template<class T>
00660 forceinline T**
00661 Heap::copy(T** d, const T** s, unsigned int n) {
00662 return copy<T*>(d,s,static_cast<long unsigned int>(n));
00663 }
00664 template<class T>
00665 forceinline T**
00666 Heap::copy(T** d, const T** s, int n) {
00667 assert(n >= 0);
00668 return copy<T*>(d,s,static_cast<long unsigned int>(n));
00669 }
00670
00671 #ifdef GECODE_PEAKHEAP
00672 forceinline size_t
00673 Heap::peak(void) {
00674 _m.acquire();
00675 size_t ret = _peak;
00676 _m.release();
00677 return ret;
00678 }
00679 #endif
00680
00681 }
00682
00683