1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: fnd_UnitHeap.h
4
5 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Rev: 16565 $
14 *---------------------------------------------------------------------------*/
15
16 #ifndef NN_FND_FND_WAITABLEUNITHEAP_H_
17 #define NN_FND_FND_WAITABLEUNITHEAP_H_
18
19 #include <nn/os.h>
20 #include <nn/fnd/fnd_UnitHeap.h>
21
22 #ifdef __cplusplus
23
24 namespace nn { namespace fnd {
25
26 // not documented
27 // 未テスト
28 template <class LockPolicy = nn::os::LockPolicy::Object<nn::os::CriticalSection>, class Semaphore = nn::os::LightSemaphore>
29 class WaitableUnitHeap : private UnitHeapTemplate<LockPolicy>
30 {
31 private:
32
33 typedef UnitHeapTemplate<LockPolicy> Base;
34 Semaphore m_Semaphore;
35
36 public:
37
38 using Base::GetRequiredHeapSize;
39
WaitableUnitHeap()40 WaitableUnitHeap() {}
41
42 WaitableUnitHeap(size_t unit, uptr addr, size_t size, s32 alignment = Base::DEFAULT_ALIGNMENT, bit32 option = 0)
43 {
44 Initialize(unit, addr, size, alignment, option);
45 }
46
47 template <class MemoryBlock>
48 explicit WaitableUnitHeap(size_t unit, const MemoryBlock& block, s32 alignment = Base::DEFAULT_ALIGNMENT, bit32 option = 0)
49 {
50 Initialize(unit, block.GetAddress(), block.GetSize(), alignment, option);
51 }
52
53 void Initialize(size_t unit, uptr addr, size_t size, s32 alignment = Base::DEFAULT_ALIGNMENT, bit32 option = 0)
54 {
55 Base::Initialize(unit, addr, size, alignment, option);
56 s32 maxCount = Base::GetTotalSize() / Base::GetUnitSize();
57 this->m_Semaphore.Initialize(maxCount, maxCount);
58 }
59
60 using Base::Invalidate;
61
62 /*!
63 @brief 終了処理
64 */
Finalize()65 void Finalize()
66 {
67 m_Semaphore.Finalize();
68 Base::Finalize();
69 }
70
71 /*!
72 @brief ヒープからユニットに基づいてメモリを確保します。
73
74 @return メモリへのポインタを返します。確保できるメモリがない場合は 0 を返します。
75 */
TryAllocate()76 void* TryAllocate()
77 {
78 if (m_Semaphore.TryAcquire())
79 {
80 void* ret = Base::Allocate();
81 NN_TASSERT_(ret);
82 return ret;
83 }
84 else
85 {
86 return 0;
87 }
88 }
89
90 /*!
91 @brief ヒープからユニットに基づいてメモリを確保します。
92 確保できるメモリがない場合は、確保できるようになるまで待機します。
93
94 @return メモリへのポインタを返します。
95 */
Allocate()96 void* Allocate()
97 {
98 m_Semaphore.Acquire();
99 void* ret = Base::Allocate();
100 NN_TASSERT_(ret);
101 return ret;
102 }
103
104 /*!
105 @brief ヒープにメモリを解放します。
106
107 @param[in] p 解放するメモリへのポインタ
108 */
Free(void * p)109 void Free(void* p)
110 {
111 Base::Free(p);
112 m_Semaphore.Release();
113 }
114
115 /*!
116 @brief このヒープから確保したメモリを解放します。
117
118 仮想メンバ関数であるため、HeapBaseから解放できます。
119
120 @param[in] p メモリへのポインタを指定します。
121 */
FreeV(void * p)122 virtual void FreeV(void* p) { Free(p); }
123
124 using Base::GetUnitSize;
125
126 using Base::GetAllocatableCount;
127
128 /*!
129 @brief ユニットヒープのメモリ領域の開始アドレスを取得します。
130
131 @return ユニットヒープのメモリ領域の開始アドレスをを返します。
132 */
GetStartAddress()133 virtual void* GetStartAddress() const { return Base::GetStartAddress(); }
134
135 /*!
136 @brief ユニットヒープに割り当てられているメモリサイズを取得します。
137
138 @return ユニットヒープに割り当てられているメモリサイズを返します。
139 */
GetTotalSize()140 virtual size_t GetTotalSize() const { return Base::GetTotalSize(); }
141
142 /*!
143 @brief ヒープ内部の情報を表示します。(デバッグ用)
144 */
Dump()145 virtual void Dump() const { Base::Dump(); }
146
147 /*!
148 @brief 指定したアドレスがヒープに含まれているか調べます。
149
150 @param[in] addr 調べたいアドレスを指定します。
151
152 @return ヒープに含まれていれば true を返し、含まれていなければ false を返します。
153 */
HasAddress(const void * addr)154 virtual bool HasAddress(const void* addr) const { return Base::HasAddress(addr); }
155
156 class Allocator;
157
158 };
159
160 template <class LockPolicy, class Semaphore>
161 class WaitableUnitHeap<LockPolicy, Semaphore>::Allocator : public IAllocator
162 {
163 public:
164
Allocator(WaitableUnitHeap & heap)165 Allocator(WaitableUnitHeap& heap) : m_Heap(&heap) {}
166
Allocator()167 Allocator() : m_Heap(0) {}
168
Initialize(WaitableUnitHeap & heap)169 void Initialize(WaitableUnitHeap& heap) { m_Heap = &heap; }
170
GetHeap()171 WaitableUnitHeap* GetHeap() { return m_Heap; }
172
GetHeap()173 const WaitableUnitHeap* GetHeap() const { return m_Heap; }
174
175 virtual void* Allocate(size_t size, s32 alignment);
176
Free(void * p)177 virtual void Free(void* p) { m_Heap->Free(p); }
178
179 private:
180 WaitableUnitHeap* m_Heap;
181 };
182
183 template <class LockPolicy, class Semaphore>
Allocate(size_t size,s32 alignment)184 inline void* WaitableUnitHeap<LockPolicy, Semaphore>::Allocator::Allocate(size_t size, s32 alignment)
185 {
186 if (size == m_Heap->GetUnitSize() && alignment >= 0 && m_Heap->GetUnitSize() % alignment == 0)
187 {
188 return m_Heap->Allocate();
189 }
190 else
191 {
192 return 0;
193 }
194 }
195
196 }}
197
198 #endif
199
200 #endif
201