Generated on Tue May 22 09:40:09 2018 for Gecode by doxygen 1.6.3

region.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  *  This file is part of Gecode, the generic constraint
00010  *  development environment:
00011  *     http://www.gecode.org
00012  *
00013  *  Permission is hereby granted, free of charge, to any person obtaining
00014  *  a copy of this software and associated documentation files (the
00015  *  "Software"), to deal in the Software without restriction, including
00016  *  without limitation the rights to use, copy, modify, merge, publish,
00017  *  distribute, sublicense, and/or sell copies of the Software, and to
00018  *  permit persons to whom the Software is furnished to do so, subject to
00019  *  the following conditions:
00020  *
00021  *  The above copyright notice and this permission notice shall be
00022  *  included in all copies or substantial portions of the Software.
00023  *
00024  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00028  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00029  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00030  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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    * Implementation
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    * Typed allocation routines
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    * Region construction support
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 // STATISTICS: kernel-memory