1#pragma once
2
3#include "heap/seadHeap.h"
4#include "heap/seadMemBlock.h"
5#include "prim/seadSizedEnum.h"
6
7namespace sead
8{
9class ExpHeap : public Heap
10{
11 SEAD_RTTI_OVERRIDE(ExpHeap, Heap)
12public:
13 enum class AllocMode
14 {
15 FirstFit = 0,
16 BestFit = 1,
17 };
18
19 enum class FindFreeBlockMode
20 {
21 Auto = 0,
22 FromFreeList = 1,
23 ByIteratingMemBlock = 2,
24 };
25
26 // FIXME: incomplete
27 enum class FindMode
28 {
29 };
30
31 static ExpHeap* create(size_t size, const SafeString& name, Heap* parent, s32 alignment,
32 HeapDirection direction, bool);
33 static ExpHeap* create(void* address, size_t size, const SafeString& name, bool);
34
35 static ExpHeap* tryCreate(size_t size, const SafeString& name, Heap* parent, s32 alignment,
36 HeapDirection direction, bool);
37 static ExpHeap* tryCreate(void* address, size_t size, const SafeString& name, bool);
38
39 static size_t getManagementAreaSize(s32);
40
41 void destroy() override;
42 size_t adjust() override;
43 void* tryAlloc(size_t size, s32 alignment) override;
44 void free(void* ptr) override;
45 void* resizeFront(void* p_void, size_t size) override;
46 void* resizeBack(void* p_void, size_t size) override;
47 void* tryRealloc(void* ptr, size_t size, s32 alignment) override;
48 void freeAll() override;
49 uintptr_t getStartAddress() const override;
50 uintptr_t getEndAddress() const override;
51 size_t getSize() const override;
52 size_t getFreeSize() const override;
53 size_t getMaxAllocatableSize(int alignment) const override;
54 bool isInclude(const void* p_void) const override;
55 bool isEmpty() const override;
56 bool isFreeable() const override;
57 bool isResizable() const override;
58 bool isAdjustable() const override;
59 void dump() const override;
60 void dumpYAML(WriteStream& stream, int i) const override;
61 void genInformation_(hostio::Context* context) override;
62
63 virtual s32 destroyAndGetAllocatableSize(s32);
64 virtual void setFindFreeBlockMode(FindFreeBlockMode mode);
65
66 AllocMode getAllocMode() const { return mAllocMode; }
67 void setAllocMode(AllocMode mode) { mAllocMode = mode; }
68
69 // XXX: this isn't const-correct...
70 size_t getAllocatedSize(void* object);
71
72 void dumpFreeList() const;
73 void dumpUseList() const;
74
75 void checkFreeList() const;
76 bool tryCheckFreeList() const;
77 void checkUseList() const;
78 bool tryCheckUseList() const;
79
80protected:
81 ExpHeap(const SafeString& name, Heap* parent, void* address, size_t size,
82 HeapDirection direction, bool);
83 ~ExpHeap() override;
84
85 static void doCreate(ExpHeap*, Heap*);
86
87 static void createMaxSizeFreeMemBlock_(ExpHeap*);
88 MemBlock* findFreeMemBlockFromHead_(size_t, FindMode) const;
89 MemBlock* findFreeMemBlockFromHead_(size_t, s32, FindMode) const;
90 MemBlock* findFreeMemBlockFromTail_(size_t, FindMode) const;
91 MemBlock* findFreeMemBlockFromTail_(size_t, s32, FindMode) const;
92 MemBlock* findLastMemBlockIfFree_();
93 MemBlock* findFirstMemBlockIfFree_();
94
95 void pushToUseList_(MemBlock*);
96 void pushToFreeList_(MemBlock*);
97
98 size_t adjustBack_();
99 size_t adjustFront_();
100
101 MemBlock* allocFromHead_(size_t);
102 MemBlock* allocFromHead_(size_t, s32);
103 MemBlock* allocFromTail_(size_t);
104 MemBlock* allocFromTail_(size_t, s32);
105
106 static s32 compareMemBlockAddr_(const MemBlock*, const MemBlock*);
107
108 SizedEnum<AllocMode, u8> mAllocMode;
109 SizedEnum<FindFreeBlockMode, u8> mFindFreeBlockMode;
110 MemBlockList mFreeList;
111 MemBlockList mUseList;
112};
113} // namespace sead
114