Sources Pipelines Documentation

Allocators  
free_list.ipp
1 // Copyright (c) 2016 Lukasz Laszko
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 #pragma once
6 
7 #include "memory_block.hpp"
8 #include "free_list.hpp"
9 
10 #include <cassert>
11 
12 
13 namespace boost { namespace memory {
14 
15 template <typename free_list_type>
16 inline free_list_helper<free_list_type>::free_list_helper(free_list_type& instance)
17  :
18  instance_(instance)
19 {
20 }
21 
22 template <typename free_list_type>
23 inline auto& free_list_helper<free_list_type>::get_allocator() noexcept
24 {
25  return instance_.allocator_;
26 }
27 
28 template <typename free_list_type>
29 inline typename free_list_helper<free_list_type>::iterator free_list_helper<free_list_type>::begin()
30 {
31  return iterator(instance_.head_);
32 }
33 
34 template <typename free_list_type>
35 inline typename free_list_helper<free_list_type>::iterator free_list_helper<free_list_type>::end()
36 {
37  return iterator(nullptr);
38 }
39 
40 template <typename free_list_type>
41 inline free_list_helper<free_list_type>::iterator::iterator(typename free_list_type::node* current)
42  :
43  current_(current)
44 {
45 }
46 
47 template <typename free_list_type>
48 inline bool free_list_helper<free_list_type>::iterator::operator ==(const free_list_helper<free_list_type>::iterator& other)
49 {
50  return current_ == other.current_;
51 }
52 
53 template <typename free_list_type>
54 inline bool free_list_helper<free_list_type>::iterator::operator !=(const free_list_helper<free_list_type>::iterator& other)
55 {
56  return current_ != other.current_;
57 }
58 
59 template <typename free_list_type>
60 inline typename free_list_helper<free_list_type>::iterator& free_list_helper<free_list_type>::iterator::operator ++()
61 {
62  current_ = current_ != nullptr ? current_->next_ : nullptr;
63  return *this;
64 }
65 
66 template <typename free_list_type>
67 inline typename free_list_helper<free_list_type>::iterator free_list_helper<free_list_type>::iterator::operator ++(int step) const
68 {
69  iterator advanced(current_);
70  for (auto i = 0; i < step && advanced.current_ != nullptr; i++)
71  advanced++;
72 
73  return advanced;
74 }
75 
76 template <typename free_list_type>
77 inline memory_block free_list_helper<free_list_type>::iterator::operator *() const
78 {
79  return current_->block_;
80 }
81 
82 template <
83  typename allocator,
84  std::size_t batch_size,
85  std::size_t min,
86  std::size_t max,
87  std::size_t capacity>
88 inline memory_block free_list<
89  allocator,
90  batch_size,
91  min,
92  max,
93  capacity>::allocate(std::size_t size)
94 {
95  if (min <= size && size <= max)
96  {
97  if (head_ != nullptr)
98  {
99  auto block = head_->block_;
100  head_ = head_->next_;
101 
102  return block;
103  }
104  else
105  {
106  memory_block first { nullptr, 0ul };
107 
108  for (auto i = 0ul; i < batch_size; i++)
109  {
110  if (allocations_count_++ == capacity)
111  break;
112 
113  auto node_with_block = allocator_.allocate(sizeof(node) + max);
114  auto current_node = reinterpret_cast<node*>(node_with_block.address);
115  current_node->block_ = { node_with_block + sizeof(node), max };
116 
117  if (i == 0ul)
118  {
119  first = current_node->block_;
120  }
121  else
122  {
123  current_node->next_ = head_;
124  head_ = current_node;
125  }
126  }
127 
128  return first;
129  }
130  }
131  else
132  {
133  return { nullptr, 0ul };
134  }
135 }
136 
137 template <
138  typename allocator,
139  std::size_t batch_size,
140  std::size_t min,
141  std::size_t max,
142  std::size_t capacity>
143 inline void free_list<
144  allocator,
145  batch_size,
146  min,
147  max,
148  capacity>::deallocate(memory_block& block)
149 {
150  if (owns(block))
151  {
152  auto current_node = reinterpret_cast<node*>(
153  reinterpret_cast<std::uint8_t*>(block.address) - sizeof(node));
154  current_node->next_ = head_;
155  head_ = current_node;
156 
157  block = null_block;
158  }
159 }
160 
161 template <
162  typename allocator,
163  std::size_t batch_size,
164  std::size_t min,
165  std::size_t max,
166  std::size_t capacity>
167 inline bool free_list<
168  allocator,
169  batch_size,
170  min,
171  max,
172  capacity>::owns(memory_block& block)
173 {
174  if (min <= block.size && block.size <= max)
175  {
176  return allocator_.owns(block);
177  }
178  else
179  {
180  return false;
181  }
182 }
183 
184 } }
185 
void deallocate(memory_block &block)
Deallocates the given memory_block.
Definition: free_list.ipp:148
bool owns(memory_block &block)
Determines if the list owns the block.
Definition: free_list.ipp:172
Provides mechanism for reusing deallocated memory blocks.
Definition: free_list.hpp:84
memory_block allocate(std::size_t size)
Allocates a memory_block from either the list or using the underlying allocator.
Definition: free_list.ipp:93
std::size_t size
Block&#39;s size.
Represents an allocated memory block.