A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
FrameHeap.cc
1#include "FrameHeap.hh"
2
3namespace Kinoko::Abstract::Memory {
4
5MEMiFrmHeapHead::MEMiFrmHeapHead(void *end, u16 opt)
6 : MEMiHeapHead(FRM_HEAP_SIGNATURE, AddOffset(this, sizeof(MEMiFrmHeapHead)), end, opt) {
7 m_headAllocator = getHeapStart();
8 m_tailAllocator = getHeapEnd();
9}
10
12MEMiFrmHeapHead::~MEMiFrmHeapHead() = default;
13
15MEMiFrmHeapHead *MEMiFrmHeapHead::create(void *startAddress, size_t size, u16 flag) {
16 void *endAddress = AddOffset(startAddress, size);
17
18 startAddress = RoundUp(startAddress, 4);
19 endAddress = RoundDown(endAddress, 4);
20
21 uintptr_t startAddrNum = GetAddrNum(startAddress);
22 uintptr_t endAddrNum = GetAddrNum(endAddress);
23
24 if (startAddrNum > endAddrNum) {
25 return nullptr;
26 }
27
28 if (endAddrNum - startAddrNum < sizeof(MEMiFrmHeapHead) + 4) {
29 return nullptr;
30 }
31
32 return new (startAddress) MEMiFrmHeapHead(endAddress, flag);
33}
34
35void MEMiFrmHeapHead::destroy() {
36 this->~MEMiFrmHeapHead();
37}
38
40void *MEMiFrmHeapHead::alloc(size_t size, s32 align) {
41 if (size == 0) {
42 size = 1;
43 }
44 size = RoundUp(size, 4);
45
46 void *block = nullptr;
47 if (align >= 0) {
48 block = allocFromHead(size, align);
49 } else {
50 block = allocFromTail(size, -align);
51 }
52
53 return block;
54}
55
57u32 MEMiFrmHeapHead::getAllocatableSize(s32 align) const {
58 // Doesn't matter which direction it can be allocated from, take absolute value
59 align = std::abs(align);
60 void *block = RoundUp(m_headAllocator, align);
61 return block > m_tailAllocator ? 0 : GetAddrNum(SubOffset(m_tailAllocator, GetAddrNum(block)));
62}
63
64void *MEMiFrmHeapHead::calcUsedEnd() {
65 return m_tailAllocator == getHeapEnd() ? m_headAllocator : getHeapEnd();
66}
67
68void *MEMiFrmHeapHead::allocFromHead(size_t size, s32 alignment) {
69 void *start = RoundUp(m_headAllocator, alignment);
70 void *end = AddOffset(start, size);
71
72 if (end > m_tailAllocator) {
73 return nullptr;
74 }
75
76 fillAllocMemory(start, size);
77 m_headAllocator = end;
78 return start;
79}
80
81void *MEMiFrmHeapHead::allocFromTail(size_t size, s32 alignment) {
82 void *start = RoundDown(SubOffset(m_tailAllocator, size), alignment);
83
84 if (start < m_headAllocator) {
85 return nullptr;
86 }
87
88 fillAllocMemory(start, size);
89 m_tailAllocator = start;
90 return start;
91}
92
93} // namespace Kinoko::Abstract::Memory
A low-level representation of a memory heap for managing dynamic memory allocation....
Definition HeapCommon.hh:21