25 #ifndef __TPIE_MEMORY_H__
26 #define __TPIE_MEMORY_H__
28 #include <tpie/config.h>
30 #include <tpie/resource_manager.h>
33 #include <unordered_map>
34 #include <type_traits>
58 void register_allocation(
size_t bytes) {
59 register_increased_usage(bytes);
62 void register_deallocation(
size_t bytes) {
63 register_decreased_usage(bytes);
66 std::string amount_with_unit(
size_t amount)
const override {
67 return bits::pretty_print::size_type(amount);
73 void register_pointer(
void * p,
size_t size,
const std::type_info & t);
74 void unregister_pointer(
void * p,
size_t size,
const std::type_info & t);
75 void assert_tpie_ptr(
void * p);
76 void complain_about_unfreed_memory();
80 void throw_out_of_resource_error(
const std::string & s)
override;
87 void __register_pointer(
void * p,
size_t size,
const std::type_info & t);
88 void __unregister_pointer(
void * p,
size_t size,
const std::type_info & t);
89 void __assert_tpie_ptr(
void * p);
90 void __complain_about_unfreed_memory();
92 std::unordered_map<void *, std::pair<size_t, const std::type_info *> > m_pointers;
155 template <
typename T,
159 bool x=std::is_polymorphic<T>::value
161 struct __object_addr {
162 void * operator()(T * o) {
return const_cast<void*
>(
static_cast<const void*
>(o));}
168 template <
typename T>
169 struct __object_addr<T, true> {
170 void * operator()(T * o) {
return const_cast<void*
>(
dynamic_cast<const void *
>(o));}
181 template <
typename D,
typename T>
182 inline D
ptr_cast(T * t) {
return reinterpret_cast<D
>(__object_addr<T>()(t)); }
185 template <
typename T>
186 inline T * __allocate() {
187 if(!std::is_polymorphic<T>::value)
return reinterpret_cast<T *
>(
new uint8_t[
sizeof(T)]);
188 uint8_t * x =
new uint8_t[
sizeof(T)+
sizeof(
size_t)];
189 *
reinterpret_cast<size_t*
>(x) =
sizeof(T);
190 return reinterpret_cast<T*
>(x +
sizeof(size_t));
193 template <
typename T>
194 inline size_t tpie_size(T * p) {
195 if(!std::is_polymorphic<T>::value)
return sizeof(T);
196 uint8_t * x =
ptr_cast<uint8_t *>(p);
197 return *
reinterpret_cast<size_t *
>(x -
sizeof(size_t));
205 template <
typename T>
236 template <
typename T>
244 deregister =
sizeof(T);
245 data = __allocate<T>();
259 delete[]
reinterpret_cast<uint8_t*
>(data);
269 template <
typename T>
289 template <
typename T,
typename ... Args>
292 new(m.allocate()) T(std::forward<Args>(args)...);
300 template <
typename T>
304 uint8_t * pp =
ptr_cast<uint8_t *>(p);
307 if(!std::is_polymorphic<T>::value)
310 delete[] (pp -
sizeof(size_t));
318 template <
typename T>
327 template <
typename T>
328 void operator()(T * t) {
337 template <
typename T>
344 template <
typename T,
typename ... TT>
356 std::atomic_size_t count;
369 explicit operator bool()
const noexcept {
return bucket !=
nullptr;}
375 const memory_bucket & operator*()
const noexcept {
return *bucket;}
377 const memory_bucket * operator->()
const noexcept {
return bucket;}
392 typedef std::allocator<T> a_t;
397 typedef typename a_t::size_type size_type;
398 typedef typename a_t::difference_type difference_type;
399 typedef typename a_t::pointer pointer;
400 typedef typename a_t::const_pointer const_pointer;
401 typedef typename a_t::reference reference;
402 typedef typename a_t::const_reference const_reference;
403 typedef typename a_t::value_type value_type;
405 typedef std::true_type propagate_on_container_copy_assignment;
406 typedef std::true_type propagate_on_container_move_assignment;
407 typedef std::true_type propagate_on_container_swap;
412 template <
typename T2>
417 T * allocate(
size_t size,
const void * hint=0) {
419 if (bucket) bucket->count += size *
sizeof(T);
420 T * res = a.allocate(size, hint);
425 void deallocate(T * p,
size_t n) {
427 if (bucket) bucket->count -= n *
sizeof(T);
430 return a.deallocate(p, n);
432 size_t max_size() const noexcept {
return a.max_size();}
434 template <
typename U,
typename ...TT>
435 void construct(U * p, TT &&...x) {a.construct(p, std::forward<TT>(x)...);}
441 template <
typename U>
442 void destroy(U * p) {
445 pointer address(reference x)
const noexcept {
return &x;}
446 const_pointer address(const_reference x)
const noexcept {
return &x;}
449 friend bool operator==(
const allocator & l,
const allocator & r) noexcept {
return l.bucket == r.bucket;}
450 friend bool operator!=(
const allocator & l,
const allocator & r) noexcept {
return l.bucket != r.bucket;}
452 template <
typename U>
453 friend class allocator;
466 #endif //__TPIE_MEMORY_H__
size_t consecutive_memory_available(size_t granularity=5 *1024 *1024)
Find the largest amount of memory that can be allocated as a single chunk.
Resource management object used to track resource usage.
void __register_pointer(void *p, size_t size, const std::type_info &t)
void unused(const T &x)
Declare that a variable is unused on purpose.
unique_ptr< T > make_unique(TT &&...tt)
Create a new unique object using tpie::new.
void __unregister_pointer(void *p, size_t size, const std::type_info &t)
T * tpie_new_array(size_t size)
Allocate a new array and register its memory usage.
A allocator object usable in STL containers, using the TPIE memory manager.
Class storring a reference to a memory bucket.
memory_manager & get_memory_manager()
Return a reference to the memory manager.
Bucket used for memory counting.
Miscellaneous utility functions.
void finish_memory_manager()
Used by tpie_finish to deinitialize the memory manager.
pretty_class for formatting quantities with binary prefixes
Memory management object used to track memory usage.
std::unique_ptr< T, tpie_deleter > unique_ptr
like std::unique_ptr, but delete the object with tpie_delete.
void tpie_delete(T *p)
Delete an object allocated with tpie_new.
void assert_tpie_ptr(void *p)
In a debug build, assert that a given pointer has been allocated with tpie_new.
std::pair< uint8_t *, size_t > __allocate_consecutive(size_t upper_bound, size_t granularity)
void init_memory_manager()
Used by tpie_init to initialize the memory manager.
T * tpie_new(Args &&...args)
Allocate an element of the type given as template parameter, and register its memory usage with TPIE...
void tpie_delete_array(T *a, size_t size)
Delete an array allocated with tpie_new_array.
D ptr_cast(T *t)
Cast between pointer types.