IceShard 1
A personal game engine project, with development focused on 2D/2.5D games.
Loading...
Searching...
No Matches
mem_allocator.hxx
Go to the documentation of this file.
1
3
4#pragma once
5#include <ice/mem.hxx>
6#include <source_location>
7#include <atomic>
8
9namespace ice
10{
11
12 template<bool WithDebugInfo>
14 {
15 static constexpr ice::usize SizeNotTracked = { static_cast<ice::usize::base_type>(0xFFFFEEEE'EEEEFFFF) };
16 static constexpr ice::u32 CountNotTracked = 0xFFFF'FFFF;
17
18 static constexpr bool HasDebugInformation = WithDebugInfo;
19
20 AllocatorBase(std::source_location const&) noexcept { }
21 AllocatorBase(std::source_location const&, std::string_view) noexcept { }
22 AllocatorBase(std::source_location const&, AllocatorBase&) noexcept { }
23 AllocatorBase(std::source_location const&, AllocatorBase&, std::string_view) noexcept { }
24
26 {
27 return do_allocate(request);
28 }
29
30 auto allocate(ice::ChunkedAllocRequest const& request) noexcept -> ice::AllocResult
31 {
32 ice::AllocResult const result = do_allocate(request._request_meminfo);
33 request.finalize(result);
34 return result;
35 }
36
37 template<typename T> requires std::is_trivial_v<T>
38 auto allocate(ice::u64 count = 1) noexcept -> T*
39 {
40 return reinterpret_cast<T*>(allocate(AllocRequest{ ice::meminfo_of<T> *count }).memory);
41 }
42
43 void deallocate(void* pointer) noexcept
44 {
45 if (pointer == nullptr) return;
46 return do_deallocate(pointer);
47 }
48
49 void deallocate(ice::Memory result) noexcept
50 {
51 return deallocate(result.location);
52 }
53
54 template<typename T, typename... Args>
55 auto create(Args&&... args) noexcept -> T*
56 {
58 return new (mem.memory) T{ ice::forward<Args>(args)... };
59 }
60
61 template<typename T>
62 void destroy(T* object) noexcept
63 {
64 object->~T();
65 return deallocate(object);
66 }
67
68 auto allocation_count() const noexcept -> ice::u32
69 {
70 return CountNotTracked;
71 }
72
73 auto allocation_total_count() const noexcept -> ice::u32
74 {
75 return CountNotTracked;
76 }
77
78 auto allocation_size_inuse() const noexcept -> ice::usize
79 {
80 return SizeNotTracked;
81 }
82
83 auto allocation_size_watermark() const noexcept -> ice::usize
84 {
85 return SizeNotTracked;
86 }
87
88 virtual auto allocation_size(void* ptr) const noexcept -> ice::usize
89 {
90 return SizeNotTracked;
91 }
92
96 auto debug_info() const noexcept -> ice::AllocatorDebugInfo const&;
97
98 protected:
99 virtual ~AllocatorBase() noexcept = default;
100
101 virtual auto do_allocate(ice::AllocRequest request) noexcept -> ice::AllocResult = 0;
102 virtual void do_deallocate(void* pointer) noexcept = 0;
103 };
104
106 {
107 public:
109 std::source_location src_loc,
110 std::string_view name
111 ) noexcept;
112
114 std::source_location const& src_loc,
115 std::string_view name,
117 ) noexcept;
118
119 virtual ~AllocatorDebugInfo() noexcept;
120
121 auto location() const noexcept -> std::source_location
122 {
123 return _source_location;
124 }
125
126 auto name() const noexcept -> std::string_view
127 {
128 return _name;
129 }
130
131 auto allocation_count() const noexcept -> ice::u32
132 {
133 return _alloc_count.load(std::memory_order_relaxed);
134 }
135
136 auto allocation_total_count() const noexcept -> ice::u32
137 {
138 return _alloc_total_count.load(std::memory_order_relaxed);
139 }
140
141 auto allocation_size_inuse() const noexcept -> ice::usize;
142
143 auto allocation_size_watermark() const noexcept -> ice::usize;
144
147
148 auto parent_allocator() const noexcept -> ice::AllocatorDebugInfo const*;
149 auto child_allocator() const noexcept -> ice::AllocatorDebugInfo const*;
150 auto next_sibling() const noexcept -> ice::AllocatorDebugInfo const*;
151
152 protected:
153 void dbg_count_add() noexcept;
154 void dbg_count_sub() noexcept;
155
156 protected:
157 std::source_location const _source_location;
158 std::string_view const _name;
159
164
165 std::atomic<ice::u32> _alloc_count;
167
168 struct Internal;
169 Internal* _internal;
170 };
171
172 template<>
174 {
177 static constexpr bool HasDebugInformation = true;
178
179 AllocatorBase(std::source_location const& src_loc) noexcept;
180 AllocatorBase(std::source_location const& src_loc, std::string_view name) noexcept;
181 AllocatorBase(std::source_location const& src_loc, AllocatorBase& parent) noexcept;
182 AllocatorBase(std::source_location const& src_loc, AllocatorBase& parent, std::string_view name) noexcept;
183
184 auto allocate(ice::AllocRequest request) noexcept -> ice::AllocResult;
185 auto allocate(ice::ChunkedAllocRequest const& request) noexcept -> ice::AllocResult;
186
187 template<typename T> requires std::is_trivial_v<T>
188 auto allocate(ice::u64 count = 1) noexcept -> T*
189 {
190 return reinterpret_cast<T*>(allocate(AllocRequest{ ice::meminfo_of<T> * count }).memory);
191 }
192
193 void deallocate(void* pointer) noexcept;
194 void deallocate(ice::Memory memory) noexcept
195 {
196 if (memory.location == nullptr) return;
197 return deallocate(memory.location);
198 }
199
200 template<typename T, typename... Args>
201 auto create(Args&&... args) noexcept -> T*
202 {
204 return new (mem.memory) T{ ice::forward<Args>(args)... };
205 }
206
207 template<typename T> requires (std::is_const_v<T> == false)
208 void destroy(T* object) noexcept
209 {
210 object->~T();
211 return deallocate(object);
212 }
213
217
218 virtual auto allocation_size(void* ptr) const noexcept -> ice::usize
219 {
221 }
222
224 auto debug_info() const noexcept -> ice::AllocatorDebugInfo const&;
225
226 protected:
227 virtual ~AllocatorBase() noexcept;
228
229 virtual auto do_allocate(ice::AllocRequest request) noexcept -> ice::AllocResult = 0;
230 virtual void do_deallocate(void* pointer) noexcept = 0;
231 };
232
233} // namespace ice
Definition mem_allocator.hxx:106
std::string_view const _name
Definition mem_allocator.hxx:158
auto next_sibling() const noexcept -> ice::AllocatorDebugInfo const *
auto allocation_count() const noexcept -> ice::u32
Definition mem_allocator.hxx:131
std::atomic< ice::u32 > _alloc_count
Definition mem_allocator.hxx:165
void dbg_count_add() noexcept
ice::AllocatorDebugInfo * _next_sibling
Definition mem_allocator.hxx:162
void dbg_count_sub() noexcept
auto allocation_size_inuse() const noexcept -> ice::usize
Internal * _internal
Definition mem_allocator.hxx:169
ice::AllocatorDebugInfo * _prev_sibling
Definition mem_allocator.hxx:163
std::atomic< ice::u32 > _alloc_total_count
Definition mem_allocator.hxx:166
auto name() const noexcept -> std::string_view
Definition mem_allocator.hxx:126
void remove_child(ice::AllocatorDebugInfo *child_allocator) noexcept
void track_child(ice::AllocatorDebugInfo *child_allocator) noexcept
auto child_allocator() const noexcept -> ice::AllocatorDebugInfo const *
auto parent_allocator() const noexcept -> ice::AllocatorDebugInfo const *
ice::AllocatorDebugInfo * _children
Definition mem_allocator.hxx:161
AllocatorDebugInfo(std::source_location const &src_loc, std::string_view name, ice::AllocatorDebugInfo &parent) noexcept
AllocatorDebugInfo(std::source_location src_loc, std::string_view name) noexcept
auto allocation_total_count() const noexcept -> ice::u32
Definition mem_allocator.hxx:136
auto location() const noexcept -> std::source_location
Definition mem_allocator.hxx:121
std::source_location const _source_location
Definition mem_allocator.hxx:157
virtual ~AllocatorDebugInfo() noexcept
auto allocation_size_watermark() const noexcept -> ice::usize
ice::AllocatorDebugInfo *const _parent
Definition mem_allocator.hxx:160
SPDX-License-Identifier: MIT.
Definition array.hxx:12
std::uint64_t u64
Definition types.hxx:27
constexpr auto count(T const (&)[Size]) noexcept -> ice::u32
Definition base.hxx:43
std::uint32_t u32
Definition types.hxx:26
constexpr ice::meminfo meminfo_of
Definition mem_info.hxx:18
Definition mem.hxx:16
Definition mem.hxx:44
void * memory
Definition mem.hxx:45
static constexpr ice::usize SizeNotTracked
Definition mem_allocator.hxx:175
AllocatorBase(std::source_location const &src_loc, AllocatorBase &parent) noexcept
auto allocate(ice::AllocRequest request) noexcept -> ice::AllocResult
auto create(Args &&... args) noexcept -> T *
Definition mem_allocator.hxx:201
virtual auto do_allocate(ice::AllocRequest request) noexcept -> ice::AllocResult=0
void destroy(T *object) noexcept
Definition mem_allocator.hxx:208
auto allocate(ice::u64 count=1) noexcept -> T *
Definition mem_allocator.hxx:188
AllocatorBase(std::source_location const &src_loc, std::string_view name) noexcept
static constexpr bool HasDebugInformation
Definition mem_allocator.hxx:177
AllocatorBase(std::source_location const &src_loc) noexcept
auto debug_info() const noexcept -> ice::AllocatorDebugInfo const &
\copy AllocatorBase<false>::debug_info()
virtual void do_deallocate(void *pointer) noexcept=0
auto allocate(ice::ChunkedAllocRequest const &request) noexcept -> ice::AllocResult
void deallocate(ice::Memory memory) noexcept
Definition mem_allocator.hxx:194
void deallocate(void *pointer) noexcept
virtual auto allocation_size(void *ptr) const noexcept -> ice::usize
Definition mem_allocator.hxx:218
static constexpr ice::u32 CountNotTracked
Definition mem_allocator.hxx:176
AllocatorBase(std::source_location const &src_loc, AllocatorBase &parent, std::string_view name) noexcept
auto allocation_size_inuse() const noexcept -> ice::usize
Definition mem_allocator.hxx:78
void destroy(T *object) noexcept
Definition mem_allocator.hxx:62
auto allocate(ice::u64 count=1) noexcept -> T *
Definition mem_allocator.hxx:38
AllocatorBase(std::source_location const &, std::string_view) noexcept
Definition mem_allocator.hxx:21
auto allocation_count() const noexcept -> ice::u32
Definition mem_allocator.hxx:68
void deallocate(void *pointer) noexcept
Definition mem_allocator.hxx:43
AllocatorBase(std::source_location const &, AllocatorBase &) noexcept
Definition mem_allocator.hxx:22
static constexpr ice::u32 CountNotTracked
Definition mem_allocator.hxx:16
virtual void do_deallocate(void *pointer) noexcept=0
auto allocate(ice::ChunkedAllocRequest const &request) noexcept -> ice::AllocResult
Definition mem_allocator.hxx:30
AllocatorBase(std::source_location const &, AllocatorBase &, std::string_view) noexcept
Definition mem_allocator.hxx:23
AllocatorBase(std::source_location const &) noexcept
Definition mem_allocator.hxx:20
auto create(Args &&... args) noexcept -> T *
Definition mem_allocator.hxx:55
auto allocation_total_count() const noexcept -> ice::u32
Definition mem_allocator.hxx:73
static constexpr ice::usize SizeNotTracked
Definition mem_allocator.hxx:15
void deallocate(ice::Memory result) noexcept
Definition mem_allocator.hxx:49
auto allocation_size_watermark() const noexcept -> ice::usize
Definition mem_allocator.hxx:83
virtual auto allocation_size(void *ptr) const noexcept -> ice::usize
Definition mem_allocator.hxx:88
static constexpr bool HasDebugInformation
Definition mem_allocator.hxx:18
virtual auto do_allocate(ice::AllocRequest request) noexcept -> ice::AllocResult=0
auto debug_info() const noexcept -> ice::AllocatorDebugInfo const &
Gives access to debug information for an allocator.
auto allocate(ice::AllocRequest request) noexcept -> ice::AllocResult
Definition mem_allocator.hxx:25
Definition mem.hxx:29
Definition mem_memory.hxx:13
Represents a unsigned size value on the given platform.
Definition mem_size_types.hxx:26
std::size_t base_type
Definition mem_size_types.hxx:28