|
31 | 31 | #pragma once |
32 | 32 |
|
33 | 33 | #include "core/error/error_macros.h" |
34 | | -#include "core/templates/safe_refcount.h" |
35 | 34 |
|
36 | 35 | #include <new> // IWYU pragma: keep // `new` operators. |
37 | 36 | #include <type_traits> |
38 | 37 |
|
39 | | -class Memory { |
40 | | -#ifdef DEBUG_ENABLED |
41 | | - static SafeNumeric<uint64_t> mem_usage; |
42 | | - static SafeNumeric<uint64_t> max_usage; |
43 | | -#endif |
44 | | - |
45 | | -public: |
46 | | - // Alignment: ↓ max_align_t ↓ uint64_t ↓ max_align_t |
47 | | - // ┌─────────────────┬──┬────────────────┬──┬───────────... |
48 | | - // │ uint64_t │░░│ uint64_t │░░│ T[] |
49 | | - // │ alloc size │░░│ element count │░░│ data |
50 | | - // └─────────────────┴──┴────────────────┴──┴───────────... |
51 | | - // Offset: ↑ SIZE_OFFSET ↑ ELEMENT_OFFSET ↑ DATA_OFFSET |
52 | | - |
53 | | - static const size_t SIZE_OFFSET; |
54 | | - static const size_t ELEMENT_OFFSET; |
55 | | - static const size_t DATA_OFFSET; |
56 | | - |
57 | | - template <bool p_ensure_zero = false> |
58 | | - static void *alloc_static(size_t p_bytes, bool p_pad_align = false); |
59 | | - _FORCE_INLINE_ static void *alloc_static_zeroed(size_t p_bytes, bool p_pad_align = false) { return alloc_static<true>(p_bytes, p_pad_align); } |
60 | | - static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false); |
61 | | - static void free_static(void *p_ptr, bool p_pad_align = false); |
62 | | - |
63 | | - // ↓ return value of alloc_aligned_static |
64 | | - // ┌─────────────────┬─────────┬─────────┬──────────────────┐ |
65 | | - // │ padding (up to │ uint32_t│ void* │ padding (up to │ |
66 | | - // │ p_alignment - 1)│ offset │ p_bytes │ p_alignment - 1) │ |
67 | | - // └─────────────────┴─────────┴─────────┴──────────────────┘ |
68 | | - // |
69 | | - // alloc_aligned_static will allocate p_bytes + p_alignment - 1 + sizeof(uint32_t) and |
70 | | - // then offset the pointer until alignment is satisfied. |
71 | | - // |
72 | | - // This offset is stored before the start of the returned ptr so we can retrieve the original/real |
73 | | - // start of the ptr in order to free it. |
74 | | - // |
75 | | - // The rest is wasted as padding in the beginning and end of the ptr. The sum of padding at |
76 | | - // both start and end of the block must add exactly to p_alignment - 1. |
77 | | - // |
78 | | - // p_alignment MUST be a power of 2. |
79 | | - static void *alloc_aligned_static(size_t p_bytes, size_t p_alignment); |
80 | | - static void *realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment); |
81 | | - // Pass the ptr returned by alloc_aligned_static to free it. |
82 | | - // e.g. |
83 | | - // void *data = realloc_aligned_static( bytes, 16 ); |
84 | | - // free_aligned_static( data ); |
85 | | - static void free_aligned_static(void *p_memory); |
86 | | - |
87 | | - static uint64_t get_mem_available(); |
88 | | - static uint64_t get_mem_usage(); |
89 | | - static uint64_t get_mem_max_usage(); |
90 | | - |
91 | | - static constexpr size_t get_aligned_address(size_t p_address, size_t p_alignment); |
92 | | -}; |
93 | | - |
94 | | -constexpr size_t Memory::get_aligned_address(size_t p_address, size_t p_alignment) { |
| 38 | +namespace Memory { |
| 39 | +constexpr size_t get_aligned_address(size_t p_address, size_t p_alignment) { |
95 | 40 | const size_t n_bytes_unaligned = p_address % p_alignment; |
96 | 41 | return (n_bytes_unaligned == 0) ? p_address : (p_address + p_alignment - n_bytes_unaligned); |
97 | 42 | } |
98 | 43 |
|
99 | | -inline constexpr size_t Memory::SIZE_OFFSET = 0; |
100 | | -inline constexpr size_t Memory::ELEMENT_OFFSET = get_aligned_address(SIZE_OFFSET + sizeof(uint64_t), alignof(uint64_t)); |
101 | | -inline constexpr size_t Memory::DATA_OFFSET = get_aligned_address(ELEMENT_OFFSET + sizeof(uint64_t), alignof(max_align_t)); |
| 44 | +// Alignment: ↓ max_align_t ↓ uint64_t ↓ max_align_t |
| 45 | +// ┌─────────────────┬──┬────────────────┬──┬───────────... |
| 46 | +// │ uint64_t │░░│ uint64_t │░░│ T[] |
| 47 | +// │ alloc size │░░│ element count │░░│ data |
| 48 | +// └─────────────────┴──┴────────────────┴──┴───────────... |
| 49 | +// Offset: ↑ SIZE_OFFSET ↑ ELEMENT_OFFSET ↑ DATA_OFFSET |
| 50 | + |
| 51 | +inline constexpr size_t SIZE_OFFSET = 0; |
| 52 | +inline constexpr size_t ELEMENT_OFFSET = get_aligned_address(SIZE_OFFSET + sizeof(uint64_t), alignof(uint64_t)); |
| 53 | +inline constexpr size_t DATA_OFFSET = get_aligned_address(ELEMENT_OFFSET + sizeof(uint64_t), alignof(max_align_t)); |
| 54 | + |
| 55 | +template <bool p_ensure_zero = false> |
| 56 | +void *alloc_static(size_t p_bytes, bool p_pad_align = false); |
| 57 | +_FORCE_INLINE_ static void *alloc_static_zeroed(size_t p_bytes, bool p_pad_align = false) { |
| 58 | + return alloc_static<true>(p_bytes, p_pad_align); |
| 59 | +} |
| 60 | +void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false); |
| 61 | +void free_static(void *p_ptr, bool p_pad_align = false); |
| 62 | + |
| 63 | +// ↓ return value of alloc_aligned_static |
| 64 | +// ┌─────────────────┬─────────┬─────────┬──────────────────┐ |
| 65 | +// │ padding (up to │ uint32_t│ void* │ padding (up to │ |
| 66 | +// │ p_alignment - 1)│ offset │ p_bytes │ p_alignment - 1) │ |
| 67 | +// └─────────────────┴─────────┴─────────┴──────────────────┘ |
| 68 | +// |
| 69 | +// alloc_aligned_static will allocate p_bytes + p_alignment - 1 + sizeof(uint32_t) and |
| 70 | +// then offset the pointer until alignment is satisfied. |
| 71 | +// |
| 72 | +// This offset is stored before the start of the returned ptr so we can retrieve the original/real |
| 73 | +// start of the ptr in order to free it. |
| 74 | +// |
| 75 | +// The rest is wasted as padding in the beginning and end of the ptr. The sum of padding at |
| 76 | +// both start and end of the block must add exactly to p_alignment - 1. |
| 77 | +// |
| 78 | +// p_alignment MUST be a power of 2. |
| 79 | +void *alloc_aligned_static(size_t p_bytes, size_t p_alignment); |
| 80 | +void *realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment); |
| 81 | +// Pass the ptr returned by alloc_aligned_static to free it. |
| 82 | +// e.g. |
| 83 | +// void *data = realloc_aligned_static( bytes, 16 ); |
| 84 | +// free_aligned_static( data ); |
| 85 | +void free_aligned_static(void *p_memory); |
| 86 | + |
| 87 | +uint64_t get_mem_available(); |
| 88 | +uint64_t get_mem_usage(); |
| 89 | +uint64_t get_mem_max_usage(); |
| 90 | +}; //namespace Memory |
102 | 91 |
|
103 | 92 | class DefaultAllocator { |
104 | 93 | public: |
|
0 commit comments