3 #ifndef DUNE_DEBUG_ALLOCATOR_HH
4 #define DUNE_DEBUG_ALLOCATOR_HH
15 #if HAVE_SYS_MMAN_H && HAVE_MPROTECT
26 #ifndef DOXYGEN // hide implementation details from doxygen
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 ";
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,
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,
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;
208 template <
class U>
struct rebind {
268 return DebugMemory::alloc_man.allocate<T>(n);
274 DebugMemory::alloc_man.deallocate<T>(p,n);
286 ::new((
void*)p)T(val);
290 template<
typename ... _Args>
293 ::new((
void *)p)T(std::forward<_Args>(__args) ...);
304 #ifdef DEBUG_NEW_DELETE
305 void *
operator new(
size_t size)
308 void *p = Dune::DebugMemory::alloc_man.allocate<
char>(
size);
309 #if DEBUG_NEW_DELETE > 2
310 std::cout <<
"NEW " <<
size
317 void 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));
325 #endif // DEBUG_NEW_DELETE
327 #endif // DUNE_DEBUG_ALLOCATOR_HH
Definition: debugallocator.hh:18
T & reference
Definition: debugallocator.hh:239
DebugAllocator()
create a new DebugAllocator
Definition: debugallocator.hh:247
T value_type
Definition: debugallocator.hh:241
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
DebugAllocator< U > other
Definition: debugallocator.hh:243
const void * const_pointer
Definition: debugallocator.hh:205
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
pointer allocate(size_type n, DebugAllocator< void >::const_pointer hint=0)
allocate n objects of type T
Definition: debugallocator.hh:264
std::ptrdiff_t difference_type
Definition: debugallocator.hh:236
void deallocate(pointer p, size_type n)
deallocate n objects of type T at address p
Definition: debugallocator.hh:272
void value_type
Definition: debugallocator.hh:207
void construct(pointer p, _Args &&...__args)
construct an object of type T from variadic parameters
Definition: debugallocator.hh:291
const T & const_reference
Definition: debugallocator.hh:240
Definition: debugallocator.hh:242
T * pointer
Definition: debugallocator.hh:237
void * pointer
Definition: debugallocator.hh:204
const_pointer address(const_reference x) const
Definition: debugallocator.hh:258
DebugAllocator(const DebugAllocator< U > &)
copy construct from an other DebugAllocator, possibly for a different result type ...
Definition: debugallocator.hh:250
std::size_t size_type
Definition: debugallocator.hh:235
void destroy(pointer p)
destroy an object of type T (i.e. call the destructor)
Definition: debugallocator.hh:297
constexpr auto size(const Dune::FieldVector< T, i > *, const PriorityTag< 5 > &) -> decltype(std::integral_constant< std::size_t, i >())
Definition: hybridutilities.hh:22
Definition: debugallocator.hh:18
Definition: debugallocator.hh:18
DummyProtFlags
Definition: debugallocator.hh:18
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition: unused.hh:18
Allocators that use malloc/free.
pointer address(reference x) const
Definition: debugallocator.hh:254
size_type max_size() const
max size for allocate
Definition: debugallocator.hh:278
Allocators implementation which performs different kind of memory checks.
Definition: debugallocator.hh:198
const T * const_pointer
Definition: debugallocator.hh:238
~DebugAllocator()
cleanup this allocator
Definition: debugallocator.hh:252
DebugAllocator< U > other
Definition: debugallocator.hh:209