Generated on Thu Apr 11 13:59:16 2019 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 #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    * Implementation
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    * Typed allocation routines
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    * Region construction support
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 // STATISTICS: kernel-memory