libhatchet
Loading...
Searching...
No Matches
hxmemory_manager.h
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: © 2017-2026 Adrian Johnston.
3// SPDX-License-Identifier: MIT
4// This file is licensed under the MIT license found in the LICENSE.md file.
5
50
51#if !LIBHATCHET_VER
52#error #include <hx/libhatchet.h> instead.
53#endif
54
55#if HX_CPLUSPLUS
56#if HX_USE_LIBCXX
57#include <new>
58#endif
59
60extern "C" {
61#endif
62
64typedef unsigned int hxalignment_t;
65
66#if HX_CPLUSPLUS >= 202002L
69inline constexpr hxalignment_t hxalignment = static_cast<hxalignment_t>(alignof(max_align_t ));
70#elif HX_CPLUSPLUS
71#define hxalignment static_cast<hxalignment_t>(alignof(max_align_t ))
72#else
73#define hxalignment (hxalignment_t)_Alignof(max_align_t )
74#endif
75
78
79enum {
91};
92
97
111
118void* hxmalloc_ext(size_t size_, hxsystem_allocator_t allocator_,
120
127char* hxstring_duplicate(const char* string_,
128 hxsystem_allocator_t allocator_ /*=hxsystem_allocator_current*/)
130
131#if HX_CPLUSPLUS
132} // extern "C"
133
137hxinline void* hxmalloc( size_t size_, hxsystem_allocator_t allocator_, hxalignment_t alignment_=hxalignment) {
138 return hxmalloc_ext(size_, allocator_, alignment_);
139}
140
144hxinline char* hxstring_duplicate(const char* s_) {
146}
147
148// Memory Manager C++ API
149
150#if !(HX_USE_LIBCXX)
151// Declare placement new. These are not built into the compiler.
152// HX_PROVIDE_NEW_DELETE is concerned with the other versions of new and delete.
153#if HX_CPLUSPLUS >= 202002L
154constexpr void* operator new(size_t, void* ptr_) noexcept { return ptr_; }
155constexpr void* operator new[](size_t, void* ptr_) noexcept { return ptr_; }
156#else
157hxinline void* operator new(size_t, void* ptr_) noexcept { return ptr_; }
158hxinline void* operator new[](size_t, void* ptr_) noexcept { return ptr_; }
159#endif
160
161#if (HX_PROVIDE_NEW_DELETE) != -1
162// Provide these for constant evaluation/consteval. Link errors may still result.
163// Use HX_PROVIDE_NEW_DELETE=-1 when compiling a module to prevent declaration.
164void* operator new(size_t size_) hxattr_nodiscard;
165void* operator new[](size_t size_) hxattr_nodiscard;
166void operator delete(void* ptr_) noexcept;
167void operator delete[](void* ptr_) noexcept;
168#endif
169#endif
170
171HX_NS_BEGIN_
172
182{
183public:
188
192
198
203
205 hxattr_nodiscard size_t get_initial_allocation_count(void) const { return m_initial_allocation_count_; }
206
208 hxattr_nodiscard size_t get_initial_bytes_allocated(void) const { return m_initial_bytes_allocated_; }
209
210private:
211 // The hxsystem_allocator_* classes are responsible for setting
212 // m_initial_allocation_count_ and m_initial_bytes_allocated_.
213 // This avoids a number of potential cache misses.
215 size_t allocation_count_, size_t bytes_allocated_);
216
217 // Deleted copy constructor to prevent copying.
219
220 // Deleted assignment operator to prevent copying.
221 void operator=(const hxsystem_allocator_scope&) = delete;
222
223 hxsystem_allocator_t m_this_allocator_;
224 hxsystem_allocator_t m_initial_allocator_;
225 size_t m_initial_allocation_count_;
226 size_t m_initial_bytes_allocated_;
227};
228
234template <typename T_, hxsystem_allocator_t allocator_=hxsystem_allocator_current, hxalignment_t align_=hxalignment, typename... Args_>
235T_* hxnew(Args_&&... args_) noexcept {
236 // Implements hxforward.
237 return ::new(hxmalloc_ext(sizeof(T_), allocator_, align_)) T_(static_cast<Args_&&>(args_)...);
238}
239
243template <typename T_>
244void hxdelete(T_* t_) noexcept {
245 if(t_) {
246 t_->~T_();
247 hxfree(t_);
248 }
249}
250
255public:
257 template <typename T_>
258 void operator()(T_* t_) const { hxdelete(t_); }
259
261 operator bool(void) const { return true; }
262};
263
268public:
270 template <typename T_>
271 void operator()(T_*) const { }
272
274 operator bool(void) const { return false; }
275};
276
277#if HX_CPLUSPLUS >= 201402L
282public:
283 // GCOVR_EXCL_START. No coverage at compile time.
285 template <typename T_>
286 constexpr void operator()(T_* t_) const { ::delete t_; }
287
289 constexpr operator bool(void) const { return true; }
290 // GCOVR_EXCL_STOP
291};
292#endif
294
295// `hxmemory_manager_init_` - WARNING: Not intended for direct use. This is
296// called by hxinit(). Initializes the memory manager. Must be called before
297// using any memory manager functions.
298void hxmemory_manager_init_(void) hxattr_cold;
299
300// `hxmemory_manager_shut_down_` - WARNING: Not intended for direct use. Shuts
301// down the memory manager. Frees any remaining resources.
302void hxmemory_manager_shut_down_(void) hxattr_cold;
304
311void hxmemory_manager_allocate_stacks(const size_t* sizes_, size_t stack_count_) hxattr_cold;
312
314template<size_t stack_count_>
315void hxmemory_manager_allocate_stacks(const size_t(&list_)[stack_count_]) {
316 hxmemory_manager_allocate_stacks(list_, stack_count_);
317}
318
327
333
334HX_NS_END_
335#endif // HX_CPLUSPLUS
hxconsteval_delete - A constexpr-compatible deleter that uses delete.
Definition hxmemory_manager.h:281
constexpr void operator()(T *t_) const
Deletes the object using delete.
Definition hxmemory_manager.h:286
hxdefault_delete - A callable that deletes objects of type T using hxdelete.
Definition hxmemory_manager.h:254
void operator()(T *t_) const
Deletes the object using hxdelete.
Definition hxmemory_manager.h:258
hxdo_not_delete - A version of hxdefault_delete that does not delete the object.
Definition hxmemory_manager.h:267
void operator()(T *) const
Does not delete the object.
Definition hxmemory_manager.h:271
hxmemory_manager_stats - The utilization statistics reported by hxmemory_manager_utilization.
Definition hxmemory_manager.h:321
size_t allocator_overflows
Definition hxmemory_manager.h:325
size_t allocations_outstanding
Definition hxmemory_manager.h:323
size_t bytes_outstanding
Definition hxmemory_manager.h:324
friend hxinline void hxsystem_allocator_scope_init_(hxsystem_allocator_scope *scope_, size_t allocation_count_, size_t bytes_allocated_)
hxattr_nodiscard size_t get_initial_bytes_allocated(void) const
Gets the number of bytes allocated when this scope was entered.
Definition hxmemory_manager.h:208
hxattr_nodiscard size_t get_current_bytes_allocated(void) const
Gets the total number of bytes allocated outstanding for this memory allocator.
hxattr_nodiscard size_t get_initial_allocation_count(void) const
Gets the number of allocations made when this scope was entered.
Definition hxmemory_manager.h:205
hxattr_nodiscard size_t get_current_allocation_count(void) const
Gets the total number of allocations outstanding for this memory allocator.
hxsystem_allocator_scope(hxsystem_allocator_t allocator_) hxattr_noexcept
Constructor: Sets the current memory allocator to the specified ID.
~hxsystem_allocator_scope(void) hxattr_noexcept
Destructor restores the stored previous memory manager allocator ID.
@ hxsystem_allocator_stack_0
hxsystem_allocator_stack_0 - Temporary stacks.
Definition hxmemory_manager.h:90
@ hxsystem_allocator_heap
hxsystem_allocator_heap - OS heap with alignment.
Definition hxmemory_manager.h:84
@ hxsystem_allocator_current
hxsystem_allocator_current - Use current allocation scope.
Definition hxmemory_manager.h:82
@ hxsystem_allocator_permanent
hxsystem_allocator_permanent - Contiguous allocations that must not be freed.
Definition hxmemory_manager.h:87
int hxsystem_allocator_t
hxsystem_allocator_t - This is extendable by the application.
Definition hxmemory_manager.h:77
void hxfree(void *ptr_) hxattr_noexcept hxattr_hot
hxfree - Frees memory previously allocated with hxmalloc or hxmalloc_ext.
void hxdelete(T *t_) noexcept
hxdelete - Deletes an object of type T and frees its memory using the memory manager.
Definition hxmemory_manager.h:244
unsigned int hxalignment_t
hxalignment_t - A positive integer power of 2 for aligning allocations.
Definition hxmemory_manager.h:64
T * hxnew(Args_ &&... args_) noexcept
hxnew<T, allocator, align>(...) - Allocates and constructs an object of type T using an optional memo...
Definition hxmemory_manager.h:235
void hxmemory_manager_allocate_stacks(const size_t *sizes_, size_t stack_count_) hxattr_cold
hxmemory_manager_allocate_stacks - Allocates the runtime temporary stacks.
void * hxmalloc_ext(size_t size_, hxsystem_allocator_t allocator_, hxalignment_t alignment_) hxattr_noexcept hxattr_allocator(hxfree) hxattr_hot
hxmalloc_ext - Allocates memory of the specified size with a specific memory manager and alignment.
char * hxstring_duplicate(const char *string_, hxsystem_allocator_t allocator_) hxattr_noexcept hxattr_allocator(hxfree) hxattr_nonnull(1) hxattr_hot
hxstring_duplicate - Allocates a copy of a string using the specified memory manager.
void * hxmalloc(size_t size_) hxattr_allocator(hxfree) hxattr_noexcept hxattr_hot
hxmalloc - Allocates memory of the specified size using the default memory manager.
constexpr hxalignment_t hxalignment
hxalignment - The default alignment.
Definition hxmemory_manager.h:69
hxmemory_manager_stats hxmemory_manager_utilization(bool stacks_only_, bool log_) hxattr_cold
hxmemory_manager_utilization - Returns the utilization statistics of the memory manager.
#define hxinline
hxinline - Force a function to be inlined into its callers.
Definition hxsettings.h:120
#define hxattr_noexcept
hxattr_noexcept - Use gcc/clang nothrow attribute.
Definition hxsettings.h:93
#define hxattr_allocator(...)
hxattr_allocator - Mark allocator/deallocator pairs for static analysis.
Definition hxsettings.h:71
#define hxattr_nonnull(...)
hxattr_nonnull - Indicates that a function has args that should not be null.
Definition hxsettings.h:97
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:89
#define hxattr_cold
hxattr_cold - Optimize a function for size.
Definition hxsettings.h:78
#define hxattr_hot
hxattr_hot - Optimize a function more aggressively.
Definition hxsettings.h:86