dius 0.1.0
Loading...
Searching...
No Matches
allocate.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/assert/assert_bool.h"
4#include "di/container/allocator/allocation_result.h"
5#include "di/container/intrusive/forward_list.h"
6#include "di/container/intrusive/forward_list_node.h"
7#include "di/container/intrusive/list.h"
8#include "di/sync/dumb_spinlock.h"
9#include "di/sync/synchronized.h"
10#include "di/util/destroy_at.h"
11#include "di/vocab/array/array.h"
12#include "di/vocab/error/result.h"
13#include "di/vocab/tuple/tuple_forward_declaration.h"
14
15namespace dius::runtime {
16namespace detail {
17 struct SizedTag : di::IntrusiveListTag<SizedTag> {
18 template<typename U>
19 constexpr static auto is_sized(di::InPlaceType<U>) -> bool {
20 return true;
21 }
22 };
23
24 struct FreeListNode : di::IntrusiveForwardListNode<> {};
25
26 struct FreeList : di::IntrusiveListNode<SizedTag> {
27 auto take_node() -> void* {
28 ASSERT(!list.empty());
29
30 auto* node = &*list.pop_front();
31 di::destroy_at(node);
32 return static_cast<void*>(node);
33 }
34
35 void add_node(void* pointer) {
36 auto* node = static_cast<FreeListNode*>(pointer);
37 di::construct_at(node);
38 list.push_front(*node);
39 }
40
41 di::IntrusiveForwardList<FreeListNode> list;
42 };
43
45 public:
46 FreeListList() = default;
47
48 auto allocate(usize size, usize align) -> di::Result<di::AllocationResult<>>;
49 void deallocate(void* pointer);
50
51 private:
52 di::IntrusiveList<FreeList, SizedTag> m_list;
53 };
54}
55
56class Heap {
57public:
58 static auto the() -> Heap&;
59
60 auto allocate(usize size, usize align) -> di::Result<di::AllocationResult<>>;
61 void deallocate(void* pointer, usize size, usize align);
62
63private:
64 Heap() = default;
65
66 constexpr static auto block_sizes = di::Array {
67 di::Tuple { 64ZU, 64ZU }, di::Tuple { 128ZU, 128ZU }, di::Tuple { 256ZU, 256ZU },
68 di::Tuple { 512ZU, 512ZU }, di::Tuple { 1024ZU, 1024ZU }, di::Tuple { 2048ZU, 2048ZU },
69 di::Tuple { 4096ZU, 4096ZU }, di::Tuple { 16384ZU, 4096ZU },
70 };
71
72 constexpr static auto block_size_count = block_sizes.size();
73
74 constexpr static auto get_block_index(usize size, usize align) -> di::Optional<usize> {
75 for (auto i = 0ZU; i < block_size_count; ++i) {
76 auto [block_size, block_align] = block_sizes[i];
77 if (size <= block_size && align <= block_align) {
78 return i;
79 }
80 }
81
82 return {};
83 }
84
85 di::Synchronized<di::Array<detail::FreeListList, block_size_count>> m_blocks;
86};
87}
void deallocate(void *pointer, usize size, usize align)
auto allocate(usize size, usize align) -> di::Result< di::AllocationResult<> >
static auto the() -> Heap &
auto allocate(usize size, usize align) -> di::Result< di::AllocationResult<> >
Definition allocate.h:16
Definition allocate.h:15
Definition allocate.h:24
Definition allocate.h:26
di::IntrusiveForwardList< FreeListNode > list
Definition allocate.h:41
void add_node(void *pointer)
Definition allocate.h:35
auto take_node() -> void *
Definition allocate.h:27
Definition allocate.h:17
static constexpr auto is_sized(di::InPlaceType< U >) -> bool
Definition allocate.h:19