7 #include <boost/memory/alignment.hpp> 8 #include <boost/utils/literals.hpp> 13 namespace boost {
namespace memory {
15 template <
typename bitmapped_block_type>
16 inline bitmapped_block_helper<bitmapped_block_type>::bitmapped_block_helper(bitmapped_block_type& instance) noexcept
23 template <
typename bitmapped_block_type>
24 inline auto& bitmapped_block_helper<bitmapped_block_type>::get_allocator() noexcept
26 return instance_.allocator_;
29 template <
typename bitmapped_block_type>
30 inline auto& bitmapped_block_helper<bitmapped_block_type>::get_bitmap() noexcept
32 return *instance_.bitmap_;
41 template <
typename bitmap_type>
42 inline bitmap_helper<bitmap_type>::bitmap_helper(bitmap_type& instance) noexcept
49 template <
typename bitmap_type>
50 inline std::uint8_t& bitmap_helper<bitmap_type>::get_flag(std::size_t index)
52 return instance_.flags_[index];
55 template <
typename bitmap_type>
56 inline constexpr std::size_t bitmap_helper<bitmap_type>::flags_count() const noexcept
58 return sizeof(instance_.flags_);
66 std::size_t alignment>
69 inline void bitmapped_block<
74 alignment>::bitmap<size>::set(std::size_t index)
76 auto& flag = flags_[index / 8ul];
77 flag |= flag_mask(index % 8ul);
85 std::size_t alignment>
88 inline void bitmapped_block<
93 alignment>::bitmap<size>::reset(std::size_t index)
95 auto& flag = flags_[index / 8ul];
96 flag &= ~flag_mask(index % 8ul);
103 std::size_t capacity,
104 std::size_t alignment>
107 inline void bitmapped_block<
112 alignment>::bitmap<size>::reset_all()
114 std::memset(flags_, 0, size);
121 std::size_t capacity,
122 std::size_t alignment>
125 inline bool bitmapped_block<
130 alignment>::bitmap<size>::is_set(std::size_t index)
132 auto& flag = flags_[index / 8ul];
133 return (flag & flag_mask(index % 8ul)) != 0_ui8;
140 std::size_t capacity,
141 std::size_t alignment>
144 inline bool bitmapped_block<
149 alignment>::bitmap<size>::claim(std::size_t& index)
151 for (
auto i = 0ul; i < size; i++)
153 auto& flag = flags_[i];
154 if ((flag & all_mask) != all_mask)
156 for (
auto j = 0_ui8; j < 8_ui8; j++)
158 auto mask = flag_mask(j);
159 if ((flag & mask) == 0_ui8)
177 std::size_t capacity,
178 std::size_t alignment>
179 inline memory_block bitmapped_block<
184 alignment>::allocate(std::size_t size)
186 if (size < min || max < size)
189 if (allocated_block_ ==
nullptr)
191 auto allocation_size =
sizeof(bitmap_type)
192 + aligned_max_size * capacity
193 + (alignment > NO_ALIGNMENT ? alignment : 0ul);
194 allocated_block_ = allocator_.allocate(allocation_size);
196 bitmap_ =
reinterpret_cast<bitmap_type*
>(allocated_block_.address);
197 bitmap_->reset_all();
201 if (bitmap_->claim(index) && index < capacity)
203 auto first_address = align_forward<alignment>(allocated_block_ +
sizeof(bitmap_type));
204 auto claimed_address = first_address + aligned_max_size * index;
206 return { claimed_address, aligned_max_size };
218 std::size_t capacity,
219 std::size_t alignment>
220 inline void bitmapped_block<
225 alignment>::deallocate(memory_block& block)
229 auto first_address = align_forward<alignment>(allocated_block_ +
sizeof(bitmap_type));
230 auto offset = block - first_address;
231 auto index = offset / aligned_max_size;
233 bitmap_->reset(index);
242 std::size_t capacity,
243 std::size_t alignment>
244 inline bool bitmapped_block<
249 alignment>::owns(memory_block& block)
251 if (allocated_block_ ==
nullptr)
254 auto start_address = align_forward<alignment>(allocated_block_ +
sizeof(bitmap_type));
255 if (block < start_address)
258 auto allocation_size =
sizeof(bitmap_type)
259 + aligned_max_size * capacity
261 auto end_address = allocated_block_ + allocation_size;
262 if (end_address < block)
265 auto offset = block - start_address;
266 return offset % aligned_max_size == 0ul;