region.hpp
Go to the documentation of this file.
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Christian Schulte <schulte@gecode.org>
*
* Copyright:
* Christian Schulte, 2008
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <cstddef>
namespace Gecode {
class Region {
private:
class Chunk : public HeapAllocated {
public:
size_t free;
alignas((alignof(std::max_align_t) > GECODE_MEMORY_ALIGNMENT) ?
alignof(std::max_align_t) : GECODE_MEMORY_ALIGNMENT)
double area[Kernel::MemoryConfig::region_area_size / sizeof(double)];
Chunk* next;
bool alloc(size_t s, void*& p);
void reset(void);
};
Chunk* chunk;
class GECODE_KERNEL_EXPORT Pool {
protected:
Chunk* c;
unsigned int n_c;
Support::Mutex m;
public:
Pool(void);
Chunk* chunk(void);
void chunk(Chunk* u);
~Pool(void);
};
GECODE_KERNEL_EXPORT static Pool& pool();
class HeapInfo {
public:
unsigned int n;
unsigned int size;
void* blocks[1];
};
void* hi;
GECODE_KERNEL_EXPORT void* heap_alloc(size_t s);
GECODE_KERNEL_EXPORT void heap_free(void);
public:
Region(void);
void free(void);
template<class T>
T* alloc(long unsigned int n);
template<class T>
T* alloc(long int n);
template<class T>
T* alloc(unsigned int n);
template<class T>
T* alloc(int n);
template<class T>
void free(T* b, long unsigned int n);
template<class T>
void free(T* b, long int n);
template<class T>
void free(T* b, unsigned int n);
template<class T>
void free(T* b, int n);
template<class T>
T* realloc(T* b, long unsigned int n, long unsigned int m);
template<class T>
T* realloc(T* b, long int n, long int m);
template<class T>
T* realloc(T* b, unsigned int n, unsigned int m);
template<class T>
T* realloc(T* b, int n, int m);
void* ralloc(size_t s);
void rfree(void* p, size_t s);
template<class T>
T& construct(void);
template<class T, typename A1>
T& construct(A1 const& a1);
template<class T, typename A1, typename A2>
T& construct(A1 const& a1, A2 const& a2);
template<class T, typename A1, typename A2, typename A3>
T& construct(A1 const& a1, A2 const& a2, A3 const& a3);
template<class T, typename A1, typename A2, typename A3, typename A4>
T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4);
template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5);
~Region(void);
private:
static void* operator new(size_t s) throw() { (void) s; return NULL; }
static void operator delete(void* p) { (void) p; };
Region(const Region&) {}
const Region& operator =(const Region&) { return *this; }
};
/*
* Implementation
*
*/
forceinline bool
Region::Chunk::alloc(size_t s, void*& p) {
Kernel::MemoryConfig::align
(s,((alignof(std::max_align_t) > GECODE_MEMORY_ALIGNMENT) ?
alignof(std::max_align_t) : GECODE_MEMORY_ALIGNMENT));
if (s > free)
return false;
free -= s;
p = ptr_cast<char*>(&area[0]) + free;
return true;
}
forceinline void
Region::Chunk::reset(void) {
free = Kernel::MemoryConfig::region_area_size;
}
forceinline
Region::Region(void)
: chunk(pool().chunk()), hi(0) {}
forceinline void
Region::free(void) {
chunk->reset();
}
forceinline void*
Region::ralloc(size_t s) {
void* p;
if (chunk->alloc(s,p))
return p;
else
return heap_alloc(s);
}
forceinline void
Region::rfree(void*, size_t) {}
forceinline
Region::~Region(void) {
pool().chunk(chunk);
if (hi != NULL)
heap_free();
}
/*
* Typed allocation routines
*
*/
template<class T>
forceinline T*
Region::alloc(long unsigned int n) {
T* p = static_cast<T*>(ralloc(sizeof(T)*n));
for (long unsigned int i=0U; i<n; i++)
(void) new (p+i) T();
return p;
}
template<class T>
forceinline T*
Region::alloc(long int n) {
assert(n >= 0);
return alloc<T>(static_cast<long unsigned int>(n));
}
template<class T>
forceinline T*
Region::alloc(unsigned int n) {
return alloc<T>(static_cast<long unsigned int>(n));
}
template<class T>
forceinline T*
Region::alloc(int n) {
assert(n >= 0);
return alloc<T>(static_cast<long unsigned int>(n));
}
template<class T>
forceinline void
Region::free(T* b, long unsigned int n) {
for (long unsigned int i=0U; i<n; i++)
b[i].~T();
rfree(b,n*sizeof(T));
}
template<class T>
forceinline void
Region::free(T* b, long int n) {
assert(n >= 0);
free<T>(b,static_cast<long unsigned int>(n));
}
template<class T>
forceinline void
Region::free(T* b, unsigned int n) {
free<T>(b,static_cast<long unsigned int>(n));
}
template<class T>
forceinline void
Region::free(T* b, int n) {
assert(n >= 0);
free<T>(b,static_cast<long unsigned int>(n));
}
template<class T>
forceinline T*
Region::realloc(T* b, long unsigned int n, long unsigned int m) {
if (n < m) {
T* p = static_cast<T*>(ralloc(sizeof(T)*m));
for (long unsigned int i=0U; i<n; i++)
(void) new (p+i) T(b[i]);
for (long unsigned int i=n; i<m; i++)
(void) new (p+i) T();
free<T>(b,n);
return p;
} else {
free<T>(b+m,m-n);
return b;
}
}
template<class T>
forceinline T*
Region::realloc(T* b, long int n, long int m) {
assert((n >= 0) && (m >= 0));
return realloc<T>(b,static_cast<long unsigned int>(n),
static_cast<long unsigned int>(m));
}
template<class T>
forceinline T*
Region::realloc(T* b, unsigned int n, unsigned int m) {
return realloc<T>(b,static_cast<long unsigned int>(n),
static_cast<long unsigned int>(m));
}
template<class T>
forceinline T*
Region::realloc(T* b, int n, int m) {
assert((n >= 0) && (m >= 0));
return realloc<T>(b,static_cast<long unsigned int>(n),
static_cast<long unsigned int>(m));
}
/*
* Region construction support
*
*/
template<class T>
forceinline T&
Region::construct(void) {
return alloc<T>(1);
}
template<class T, typename A1>
forceinline T&
Region::construct(A1 const& a1) {
T& t = *static_cast<T*>(ralloc(sizeof(T)));
new (&t) T(a1);
return t;
}
template<class T, typename A1, typename A2>
forceinline T&
Region::construct(A1 const& a1, A2 const& a2) {
T& t = *static_cast<T*>(ralloc(sizeof(T)));
new (&t) T(a1,a2);
return t;
}
template<class T, typename A1, typename A2, typename A3>
forceinline T&
Region::construct(A1 const& a1, A2 const& a2, A3 const& a3) {
T& t = *static_cast<T*>(ralloc(sizeof(T)));
new (&t) T(a1,a2,a3);
return t;
}
template<class T, typename A1, typename A2, typename A3, typename A4>
forceinline T&
Region::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) {
T& t = *static_cast<T*>(ralloc(sizeof(T)));
new (&t) T(a1,a2,a3,a4);
return t;
}
template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
forceinline T&
Region::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) {
T& t = *static_cast<T*>(ralloc(sizeof(T)));
new (&t) T(a1,a2,a3,a4,a5);
return t;
}
}
// STATISTICS: kernel-memory
Gecode::HeapAllocated
Base class for heap allocated objects.
Definition heap.hpp:340
Gecode::Region::ralloc
void * ralloc(size_t s)
Allocate memory from region.
Definition region.hpp:361
Gecode::Region::free
void free(void)
Free allocate memory.
Definition region.hpp:356
Gecode::Region::construct
T & construct(void)
Constructs a single object of type T from region using the default constructor.
Definition region.hpp:478
Gecode::Region::Region
Region(void)
Initialize region.
Definition region.hpp:352
Gecode::Region::realloc
T * realloc(T *b, long unsigned int n, long unsigned int m)
Reallocate block of n objects starting at b to m objects of type T from the region.
Definition region.hpp:437
Gecode::Region::~Region
~Region(void)
Return memory.
Definition region.hpp:373
Gecode::Region::rfree
void rfree(void *p, size_t s)
Free memory previously allocated.
Definition region.hpp:370
Gecode::Region::alloc
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition region.hpp:386
Gecode::Support::Mutex
A mutex for mutual exclausion among several threads.
Definition thread.hpp:96
GECODE_MEMORY_ALIGNMENT
#define GECODE_MEMORY_ALIGNMENT
Memory alignment.
Definition config.hpp:125
GECODE_KERNEL_EXPORT
#define GECODE_KERNEL_EXPORT
Definition kernel.hh:70
Gecode::Kernel::MemoryConfig::align
void align(size_t &s, size_t a=GECODE_MEMORY_ALIGNMENT)
Align size s to the required alignment a.
Definition config.hpp:144
Gecode::Kernel::MemoryConfig::region_area_size
const size_t region_area_size
Size of region area.
Definition config.hpp:134
Gecode
Gecode toplevel namespace
Gecode::ptr_cast
T ptr_cast(void *p)
Cast p into pointer of type T.
Definition cast.hpp:42
forceinline
#define forceinline
Definition config.hpp:187