3#ifndef DUNE_DEBUG_ALLOCATOR_HH 
    4#define DUNE_DEBUG_ALLOCATOR_HH 
   15#if HAVE_SYS_MMAN_H && HAVE_MPROTECT 
   18enum DummyProtFlags { PROT_NONE, PROT_WRITE, PROT_READ };
 
   30    extern const std::ptrdiff_t page_size;
 
   32    struct AllocationManager
 
   34      typedef std::size_t size_type;
 
   35      typedef std::ptrdiff_t difference_type;
 
   36      typedef void* pointer;
 
   39      static void allocation_error(
const char* msg);
 
   41      struct AllocationInfo;
 
   42      friend struct AllocationInfo;
 
   44#define ALLOCATION_ASSERT(A) { if (!(A))                            \ 
   45                               { allocation_error("Assertion " # A " failed");\
 
   51        AllocationInfo(
const std::type_info & t) : type(&t) {}
 
   52        const std::type_info * type;
 
   62      typedef MallocAllocator<AllocationInfo> Alloc;
 
   63      typedef std::vector<AllocationInfo, Alloc> AllocationList;
 
   64      AllocationList allocation_list;
 
   67      void memprotect(
void* from, difference_type len, 
int prot)
 
   69#if HAVE_SYS_MMAN_H && HAVE_MPROTECT 
   70        int result = mprotect(from, len, prot);
 
   74          std::cerr << 
"ERROR: (" << result << 
": " << strerror(result) << 
")" << std::endl;
 
   75          std::cerr << 
" Failed to ";
 
   76          if (prot == PROT_NONE)
 
   77            std::cerr << 
"protect ";
 
   79            std::cerr << 
"unprotect ";
 
   80          std::cerr << 
"memory range: " 
   82                    << 
static_cast<void*
>(
 
   83            static_cast<char*
>(from) + len)
 
   91        std::cerr << 
"WARNING: memory protection not available" << std::endl;
 
   99        AllocationList::iterator it;
 
  101        for (it=allocation_list.begin(); it!=allocation_list.end(); it++)
 
  105            std::cerr << 
"ERROR: found memory chunk still in use: " <<
 
  106            it->capacity << 
" bytes at " << it->ptr << std::endl;
 
  109          munmap(it->page_ptr, it->pages * page_size);
 
  112          allocation_error(
"lost allocations");
 
  116      T* allocate(size_type n) 
throw(std::bad_alloc)
 
  119        AllocationInfo ai(
typeid(T));
 
  121        ai.capacity = n * 
sizeof(T);
 
  122        ai.pages = (ai.capacity) / page_size + 2;
 
  124        size_type overlap = ai.capacity % page_size;
 
  125        ai.page_ptr = mmap(NULL, ai.pages * page_size,
 
  126                           PROT_READ | PROT_WRITE,
 
  128                           MAP_ANON | MAP_PRIVATE,
 
  130                           MAP_ANONYMOUS | MAP_PRIVATE,
 
  133        if (MAP_FAILED == ai.page_ptr)
 
  135          throw std::bad_alloc();
 
  137        ai.ptr = 
static_cast<char*
>(ai.page_ptr) + page_size - overlap;
 
  139        memprotect(
static_cast<char*
>(ai.page_ptr) + (ai.pages-1) * page_size,
 
  143        allocation_list.push_back(ai);
 
  145        return static_cast<T*
>(ai.ptr);
 
  149      void deallocate(T* ptr, size_type n = 0) throw()
 
  154            (
char*)(ptr) - ((std::uintptr_t)(ptr) % page_size));
 
  156        AllocationList::iterator it;
 
  158        for (it=allocation_list.begin(); it!=allocation_list.end(); it++, i++)
 
  160          if (it->page_ptr == page_ptr)
 
  165              ALLOCATION_ASSERT(n == it->size);
 
  166            ALLOCATION_ASSERT(ptr == it->ptr);
 
  167            ALLOCATION_ASSERT(
true == it->not_free);
 
  168            ALLOCATION_ASSERT(
typeid(T) == *(it->type));
 
  170            it->not_free = 
false;
 
  171#if DEBUG_ALLOCATOR_KEEP 
  173            memprotect(it->page_ptr,
 
  174                       (it->pages) * page_size,
 
  178            memprotect(it->page_ptr,
 
  179                       (it->pages) * page_size,
 
  180                       PROT_READ | PROT_WRITE);
 
  181            munmap(it->page_ptr, it->pages * page_size);
 
  183            allocation_list.erase(it);
 
  188        allocation_error(
"memory block not found");
 
  191#undef ALLOCATION_ASSERT 
  193    extern AllocationManager alloc_man;
 
  198  class DebugAllocator;
 
  202  class DebugAllocator<void> {
 
  204    typedef void* pointer;
 
  205    typedef const void* const_pointer;
 
  207    typedef void value_type;
 
  208    template <
class U> 
struct rebind {
 
  209      typedef DebugAllocator<U> other;
 
  235    typedef std::size_t size_type;
 
  236    typedef std::ptrdiff_t difference_type;
 
  238    typedef const T* const_pointer;
 
  239    typedef T& reference;
 
  240    typedef const T& const_reference;
 
  241    typedef T value_type;
 
  242    template <
class U> 
struct rebind {
 
  254    pointer address(reference x)
 const 
  258    const_pointer address(const_reference x)
 const 
  265                     DebugAllocator<void>::const_pointer hint = 0)
 
  268      return DebugMemory::alloc_man.allocate<T>(n);
 
  274      DebugMemory::alloc_man.deallocate<T>(p,n);
 
  280      return size_type(-1) / 
sizeof(T);
 
  286      ::new((
void*)p)T(val);
 
  290    template<
typename ... _Args>
 
  293      ::new((
void *)p)T(std::forward<_Args>(__args) ...);
 
  304#ifdef DEBUG_NEW_DELETE 
  305void * 
operator new(
size_t size) 
throw(std::bad_alloc)
 
  308  void *p = Dune::DebugMemory::alloc_man.allocate<
char>(size);
 
  309#if DEBUG_NEW_DELETE > 2 
  310  std::cout << 
"NEW " << size
 
  317void operator delete(
void * p) 
throw()
 
  319#if DEBUG_NEW_DELETE > 2 
  320  std::cout << 
"FREE " << p << std::endl;
 
  322  Dune::DebugMemory::alloc_man.deallocate<
char>(
static_cast<char*
>(p));
 
Allocators implementation which performs different kind of memory checks.
Definition: debugallocator.hh:233
 
void destroy(pointer p)
destroy an object of type T (i.e. call the destructor)
Definition: debugallocator.hh:297
 
~DebugAllocator()
cleanup this allocator
Definition: debugallocator.hh:252
 
size_type max_size() const
max size for allocate
Definition: debugallocator.hh:278
 
void deallocate(pointer p, size_type n)
deallocate n objects of type T at address p
Definition: debugallocator.hh:272
 
DebugAllocator(const DebugAllocator< U > &)
copy construct from an other DebugAllocator, possibly for a different result type
Definition: debugallocator.hh:250
 
void construct(pointer p, _Args &&... __args)
construct an object of type T from variadic parameters
Definition: debugallocator.hh:291
 
void construct(pointer p, const T &val)
copy-construct an object of type T (i.e. make a placement new on p)
Definition: debugallocator.hh:284
 
DebugAllocator()
create a new DebugAllocator
Definition: debugallocator.hh:247
 
pointer allocate(size_type n, DebugAllocator< void >::const_pointer hint=0)
allocate n objects of type T
Definition: debugallocator.hh:264
 
Allocators that use malloc/free.
 
Dune namespace.
Definition: alignment.hh:10
 
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
 
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentional unused function parameters with.
Definition: unused.hh:18