Generated on Tue Apr 18 10:22:14 2017 for Gecode by doxygen 1.6.3

heap.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2008
00008  *
00009  *  Last modified:
00010  *     $Date: 2016-04-20 17:14:25 +0200 (Wed, 20 Apr 2016) $ by $Author: schulte $
00011  *     $Revision: 14972 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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    * Wrappers for raw allocation routines
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    * Heap allocated objects
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    * Typed allocation routines
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 // STATISTICS: support-any