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