libcopp  1.1.0
stack_allocator_memory.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include <assert.h>
3 #include <cstring>
4 #include <limits>
5 #include <numeric>
6 
10 
11 #if defined(LIBCOPP_MACRO_USE_VALGRIND)
12 #include <valgrind/valgrind.h>
13 #endif
14 
15 
16 #ifdef COPP_HAS_ABI_HEADERS
17 #include COPP_ABI_PREFIX
18 #endif
19 
20 namespace copp {
21  namespace allocator {
22 
23  stack_allocator_memory::stack_allocator_memory() UTIL_CONFIG_NOEXCEPT : start_ptr_(NULL), memory_size_(0), is_used_(false) {}
24 
25  stack_allocator_memory::stack_allocator_memory(void *start_ptr, std::size_t max_size) UTIL_CONFIG_NOEXCEPT : start_ptr_(start_ptr),
26  memory_size_(max_size),
27  is_used_(false) {}
28 
30  memory_size_(0),
31  is_used_(false) {
32  if (!other.is_used_) {
33  swap(other);
34  }
35  }
36 
37 #if defined(UTIL_CONFIG_COMPILER_CXX_RVALUE_REFERENCES) && UTIL_CONFIG_COMPILER_CXX_RVALUE_REFERENCES
39  memory_size_(0),
40  is_used_(false) {
41  if (!other.is_used_) {
42  swap(other);
43  }
44  }
45 #endif
46 
48 
50  if (!other.is_used_) {
51  swap(other);
52  }
53  return *this;
54  }
55 #if defined(UTIL_CONFIG_COMPILER_CXX_RVALUE_REFERENCES) && UTIL_CONFIG_COMPILER_CXX_RVALUE_REFERENCES
57  if (!other.is_used_) {
58  swap(other);
59  }
60  return *this;
61  }
62 #endif
63 
65  using std::swap;
66  swap(start_ptr_, other.start_ptr_);
68  swap(is_used_, other.is_used_);
69  }
70 
71  void stack_allocator_memory::attach(void *start_ptr, std::size_t max_size) UTIL_CONFIG_NOEXCEPT {
72  start_ptr_ = start_ptr;
73  memory_size_ = max_size;
74  is_used_ = false;
75  }
76 
77  void stack_allocator_memory::allocate(stack_context &ctx, std::size_t size) UTIL_CONFIG_NOEXCEPT {
78  if (NULL == start_ptr_ || is_used_) {
79  ctx.sp = NULL;
80  return;
81  }
82 
83  size = (std::max)(size, stack_traits::minimum_size());
84  size = (std::min)(size, stack_traits::maximum_size());
85  size = (std::min)(size, memory_size_);
86 
87  std::size_t size_ = stack_traits::round_to_page_size(size);
88  assert(size > 0 && size_ > 0 && size_ <= memory_size_);
89 
90  ctx.size = size_;
91  ctx.sp = static_cast<char *>(start_ptr_) + ctx.size; // stack down
92 
93 #if defined(LIBCOPP_MACRO_USE_VALGRIND)
94  ctx.valgrind_stack_id = VALGRIND_STACK_REGISTER(ctx.sp, start_ptr_);
95 #endif
96  is_used_ = true;
97  }
98 
99  void stack_allocator_memory::deallocate(stack_context &ctx) UTIL_CONFIG_NOEXCEPT {
100  assert(ctx.sp);
101  assert(stack_traits::minimum_size() <= ctx.size);
102  assert(stack_traits::is_unbounded() || (stack_traits::maximum_size() >= ctx.size));
103 
104 #if defined(LIBCOPP_MACRO_USE_VALGRIND)
105  VALGRIND_STACK_DEREGISTER(ctx.valgrind_stack_id);
106 #endif
107  is_used_ = false;
108  }
109  } // namespace allocator
110 } // namespace copp
111 
112 #ifdef COPP_HAS_ABI_HEADERS
113 #include COPP_ABI_SUFFIX
114 #endif
memory allocator this allocator will return address of specified memory section
void allocate(stack_context &ctx, std::size_t size) UTIL_CONFIG_NOEXCEPT
void deallocate(stack_context &ctx) UTIL_CONFIG_NOEXCEPT
static bool is_unbounded() COPP_MACRO_NOEXCEPT
static std::size_t maximum_size() COPP_MACRO_NOEXCEPT
static std::size_t minimum_size() COPP_MACRO_NOEXCEPT
static std::size_t round_to_page_size(std::size_t stacksize) COPP_MACRO_NOEXCEPT
void swap(stack_allocator_memory &other)
void attach(void *start_ptr, std::size_t max_size) UTIL_CONFIG_NOEXCEPT
stack_allocator_memory & operator=(stack_allocator_memory &other) UTIL_CONFIG_NOEXCEPT