Thrill  0.1
allocator_base.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * thrill/mem/allocator_base.hpp
3  *
4  * Part of Project Thrill - http://project-thrill.org
5  *
6  * Copyright (C) 2015 Timo Bingmann <[email protected]>
7  *
8  * All rights reserved. Published under the BSD-2 license in the LICENSE file.
9  ******************************************************************************/
10 
11 #pragma once
12 #ifndef THRILL_MEM_ALLOCATOR_BASE_HEADER
13 #define THRILL_MEM_ALLOCATOR_BASE_HEADER
14 
15 #include <thrill/common/string.hpp>
17 #include <thrill/mem/manager.hpp>
18 #include <tlx/allocator_base.hpp>
20 
21 #include <atomic>
22 #include <cassert>
23 #include <deque>
24 #include <iosfwd>
25 #include <new>
26 #include <string>
27 #include <type_traits>
28 #include <vector>
29 
30 namespace thrill {
31 namespace mem {
32 
33 /******************************************************************************/
34 // FixedAllocator
35 
36 template <typename Type, Manager& manager_>
37 class FixedAllocator : public tlx::AllocatorBase<Type>
38 {
39  static constexpr bool debug = false;
40 
41 public:
42  using value_type = Type;
43  using pointer = Type *;
44  using const_pointer = const Type *;
45  using reference = Type&;
46  using const_reference = const Type&;
47  using size_type = std::size_t;
48  using difference_type = std::ptrdiff_t;
49 
50  //! C++11 type flag
51  using is_always_equal = std::true_type;
52 
53  //! Return allocator for different type.
54  template <typename U>
56 
57  //! default constructor
58  FixedAllocator() noexcept = default;
59 
60  //! copy-constructor
61  FixedAllocator(const FixedAllocator&) noexcept = default;
62 
63  //! copy-constructor from a rebound allocator
64  template <typename OtherType>
66  { }
67 
68 #if !defined(_MSC_VER)
69  //! copy-assignment operator: default
70  FixedAllocator& operator = (FixedAllocator&) noexcept = default;
71 
72  //! move-assignment operator: default
73  FixedAllocator& operator = (FixedAllocator&&) noexcept = default;
74 #endif
75 
76  //! Attempts to allocate a block of storage with a size large enough to
77  //! contain n elements of member type value_type, and returns a pointer to
78  //! the first element.
79  pointer allocate(size_type n, const void* /* hint */ = nullptr) {
80  if (n > this->max_size())
81  throw std::bad_alloc();
82 
83  const size_t size = n * sizeof(Type);
84  manager_.add(size);
85 
86  if (debug) {
87  printf("allocate() n=%zu sizeof(T)=%zu total=%zu\n",
88  n, sizeof(Type), manager_.total());
89  }
90 
91  Type* r = static_cast<Type*>(bypass_malloc(size));
92  while (r == nullptr)
93  {
94  // If malloc fails and there is a std::new_handler, call it to try
95  // free up memory.
96  std::new_handler nh = std::get_new_handler();
97  if (!nh)
98  throw std::bad_alloc();
99  nh();
100  r = static_cast<Type*>(bypass_malloc(size));
101  }
102  return r;
103  }
104 
105  //! Releases a block of storage previously allocated with member allocate
106  //! and not yet released.
107  void deallocate(pointer p, size_type n) const noexcept {
108 
109  manager_.subtract(n * sizeof(Type));
110 
111  if (debug) {
112  printf("deallocate() n=%zu sizeof(T)=%zu total=%zu\n",
113  n, sizeof(Type), manager_.total());
114  }
115 
116  bypass_free(p, n * sizeof(Type));
117  }
118 
119  //! Compare to another allocator of same type
120  template <typename Other>
121  bool operator == (const FixedAllocator<Other, manager_>&) const noexcept {
122  return true;
123  }
124 
125  //! Compare to another allocator of same type
126  template <typename Other>
127  bool operator != (const FixedAllocator<Other, manager_>&) const noexcept {
128  return true;
129  }
130 };
131 
132 template <Manager& manager_>
133 class FixedAllocator<void, manager_>
134 {
135 public:
136  using pointer = void*;
137  using const_pointer = const void*;
138  using value_type = void;
139 
140  template <typename U>
141  struct rebind { using other = FixedAllocator<U, manager_>; };
142 };
143 
144 /******************************************************************************/
145 // BypassAllocator
146 
147 //! global bypass memory manager
149 
150 //! instantiate FixedAllocator as BypassAllocator
151 template <typename Type>
153 
154 //! operator new with our Allocator
155 template <typename T, typename... Args>
156 T * by_new(Args&& ... args) {
157  BypassAllocator<T> allocator;
158  T* value = allocator.allocate(1);
159  allocator.construct(value, std::forward<Args>(args) ...);
160  return value;
161 }
162 
163 //! operator delete with our Allocator
164 template <typename T>
165 void by_delete(T* value) {
166  BypassAllocator<T> allocator;
167  allocator.destroy(value);
168  allocator.deallocate(value, 1);
169 }
170 
171 /******************************************************************************/
172 // template aliases with BypassAllocator
173 
174 //! string without malloc tracking
175 using by_string = std::basic_string<
176  char, std::char_traits<char>, BypassAllocator<char> >;
177 
178 //! stringbuf without malloc tracking
179 using by_stringbuf = std::basic_stringbuf<
180  char, std::char_traits<char>, BypassAllocator<char> >;
181 
182 //! vector without malloc tracking
183 template <typename T>
184 using by_vector = std::vector<T, BypassAllocator<T> >;
185 
186 //! deque without malloc tracking
187 template <typename T>
188 using by_deque = std::deque<T, BypassAllocator<T> >;
189 
190 //! convert to string
191 static inline by_string to_string(int val) {
192  return tlx::ssnprintf_generic<by_string>(4 * sizeof(int), "%d", val);
193 }
194 
195 //! convert to string
196 static inline by_string to_string(unsigned val) {
197  return tlx::ssnprintf_generic<by_string>(4 * sizeof(int), "%u", val);
198 }
199 
200 //! convert to string
201 static inline by_string to_string(long val) {
202  return tlx::ssnprintf_generic<by_string>(4 * sizeof(long), "%ld", val);
203 }
204 
205 //! convert to string
206 static inline by_string to_string(unsigned long val) {
207  return tlx::ssnprintf_generic<by_string>(4 * sizeof(long), "%lu", val);
208 }
209 
210 //! convert to string
211 static inline by_string to_string(long long val) {
212  return tlx::ssnprintf_generic<by_string>(4 * sizeof(long long), "%lld", val);
213 }
214 
215 //! convert to string
216 static inline by_string to_string(unsigned long long val) {
217  return tlx::ssnprintf_generic<by_string>(4 * sizeof(long long), "%llu", val);
218 }
219 
220 } // namespace mem
221 } // namespace thrill
222 
223 #endif // !THRILL_MEM_ALLOCATOR_BASE_HEADER
224 
225 /******************************************************************************/
FixedAllocator() noexcept=default
default constructor
void destroy(pointer p) const noexcept
Destroys in-place the object pointed by p.
bool operator==(const FixedAllocator< Other, manager_ > &) const noexcept
Compare to another allocator of same type.
std::deque< T, BypassAllocator< T > > by_deque
deque without malloc tracking
double T
Type
VFS object type.
Definition: file_io.hpp:52
pointer allocate(size_type n, const void *=nullptr)
static constexpr bool debug
T * by_new(Args &&... args)
operator new with our Allocator
Manager g_bypass_manager
global bypass memory manager
void bypass_free(void *ptr, size_t size) noexcept
bypass malloc tracker and access free() directly
Return allocator for different type.
FixedAllocator(const FixedAllocator< OtherType, manager_ > &) noexcept
copy-constructor from a rebound allocator
static by_string to_string(int val)
convert to string
void construct(pointer p, const_reference value)
Constructs an element object on the location pointed by p.
void * bypass_malloc(size_t size) noexcept
bypass malloc tracker and access malloc() directly
int value
Definition: gen_data.py:41
std::basic_stringbuf< char, std::char_traits< char >, BypassAllocator< char > > by_stringbuf
stringbuf without malloc tracking
size_type max_size() const noexcept
Maximum size possible to allocate.
std::true_type is_always_equal
C++11 type flag.
void deallocate(pointer p, size_type n) const noexcept
Object shared by allocators and other classes to track memory allocations.
Definition: manager.hpp:28
std::basic_string< char, std::char_traits< char >, BypassAllocator< char > > by_string
string without malloc tracking
std::vector< T, BypassAllocator< T > > by_vector
vector without malloc tracking
bool operator!=(const FixedAllocator< Other, manager_ > &) const noexcept
Compare to another allocator of same type.
FixedAllocator & operator=(FixedAllocator &) noexcept=default
copy-assignment operator: default
void by_delete(T *value)
operator delete with our Allocator