1#ifndef SEAD_HEAP_H_
2#define SEAD_HEAP_H_
3
4#include <stddef.h>
5
6#include <basis/seadRawPrint.h>
7#include <basis/seadTypes.h>
8#include <container/seadOffsetList.h>
9#include <heap/seadDisposer.h>
10#include <hostio/seadHostIOReflexible.h>
11#include <prim/seadBitFlag.h>
12#include <prim/seadEnum.h>
13#include <prim/seadNamable.h>
14#include <prim/seadRuntimeTypeInfo.h>
15#include <prim/seadSafeString.h>
16#include <thread/seadCriticalSection.h>
17
18namespace sead
19{
20class Thread;
21class WriteStream;
22
23namespace hostio
24{
25class Context;
26class PropertyEvent;
27} // namespace hostio
28
29class Heap : public IDisposer, public INamable, public hostio::Reflexible
30{
31public:
32 SEAD_ENUM(Flag, cEnableLock, cDisposing, cEnableWarning, cEnableDebugFillSystem,
33 cEnableDebugFillUser)
34
35 enum HeapDirection
36 {
37 cHeapDirection_Forward = 1,
38 cHeapDirection_Reverse = -1
39 };
40
41 Heap(const SafeString& name, Heap* parent, void* address, size_t size, HeapDirection direction,
42 bool);
43 ~Heap() override;
44
45 SEAD_RTTI_BASE(Heap)
46
47 virtual void destroy() = 0;
48 virtual size_t adjust() = 0;
49 virtual void* tryAlloc(size_t size, s32 alignment) = 0;
50 virtual void free(void* ptr) = 0;
51 virtual void* resizeFront(void*, size_t) = 0;
52 virtual void* resizeBack(void*, size_t) = 0;
53 virtual void* tryRealloc(void* ptr, size_t size, s32 alignment);
54 virtual void freeAll() = 0;
55 virtual uintptr_t getStartAddress() const = 0;
56 virtual uintptr_t getEndAddress() const = 0;
57 virtual size_t getSize() const = 0;
58 virtual size_t getFreeSize() const = 0;
59 virtual size_t getMaxAllocatableSize(int alignment) const = 0;
60 virtual bool isInclude(const void*) const = 0;
61 virtual bool isEmpty() const = 0;
62 virtual bool isFreeable() const = 0;
63 virtual bool isResizable() const = 0;
64 virtual bool isAdjustable() const = 0;
65
66 virtual void dump() const {}
67 virtual void dumpYAML(WriteStream& stream, int) const;
68 void dumpTreeYAML(WriteStream& stream, int) const;
69
70#ifdef SEAD_DEBUG
71 void listenPropertyEvent(const hostio::PropertyEvent* event) override;
72 void genMessage(hostio::Context*) override;
73#endif
74 virtual void genInformation_(hostio::Context*);
75 virtual void makeMetaString_(BufferedSafeString*);
76
77 virtual void pushBackChild_(Heap* child);
78
79 void appendDisposer_(IDisposer* disposer);
80 void removeDisposer_(IDisposer* disposer);
81 Heap* findContainHeap_(const void* ptr);
82
83 void* alloc(size_t size, s32 alignment = sizeof(void*))
84 {
85 void* ptr = tryAlloc(size, alignment);
86 SEAD_ASSERT_MSG(ptr,
87 "alloc failed. size: %zu, allocatable size: %zu, alignment: %d, heap: %s",
88 size, getMaxAllocatableSize(alignment), alignment, getName().cstr());
89 return ptr;
90 }
91
92 void enableLock(bool on) { mFlag.changeBit(bit: Flag::cEnableLock, on); }
93 void enableWarning(bool on) { mFlag.changeBit(bit: Flag::cEnableWarning, on); }
94 void enableDebugFillSystem(bool on) { mFlag.changeBit(bit: Flag::cEnableDebugFillSystem, on); }
95 void enableDebugFillUser(bool on) { mFlag.changeBit(bit: Flag::cEnableDebugFillUser, on); }
96
97 bool isLockEnabled() const { return mFlag.isOnBit(bit: Flag::cEnableLock); }
98 bool isWarningEnabled() const { return mFlag.isOnBit(bit: Flag::cEnableWarning); }
99 bool isDebugFillSystemEnabled() const { return mFlag.isOnBit(bit: Flag::cEnableDebugFillSystem); }
100 bool isDebugFillUserEnabled() const { return mFlag.isOnBit(bit: Flag::cEnableDebugFillUser); }
101
102 sead::CriticalSection& getCriticalSection() { return mCS; }
103
104 using HeapList = OffsetList<Heap>;
105 using DisposerList = OffsetList<IDisposer>;
106
107 void* mStart;
108 size_t mSize;
109 Heap* mParent;
110 HeapList mChildren;
111 ListNode mListNode;
112 DisposerList mDisposerList;
113 HeapDirection mDirection;
114 CriticalSection mCS;
115 BitFlag16 mFlag;
116 u16 mHeapCheckTag;
117#ifdef SEAD_DEBUG
118 sead::Thread* mAccessThread;
119#endif
120};
121
122inline void* Heap::tryRealloc(void*, size_t, s32)
123{
124 SEAD_ASSERT_MSG(false, "tryRealloc is not implement.");
125 return nullptr;
126}
127
128} // namespace sead
129
130#endif // SEAD_HEAP_H_
131