1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_WaitableUnitHeap.h
4 
5   Copyright (C)2009-2012 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: 46347 $
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 // Untested
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     /* Please see man pages for details
63 
64     */
Finalize()65     void Finalize()
66     {
67         m_Semaphore.Finalize();
68         Base::Finalize();
69     }
70 
71     /* Please see man pages for details
72 
73 
74 
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     /* Please see man pages for details
91 
92 
93 
94 
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     /* Please see man pages for details
105 
106 
107 
108     */
Free(void * p)109     void Free(void* p)
110     {
111         Base::Free(p);
112         m_Semaphore.Release();
113     }
114 
115     /* Please see man pages for details
116 
117 
118 
119 
120 
121 	*/
FreeV(void * p)122     virtual void FreeV(void* p) { Free(p); }
123 
124     using Base::GetUnitSize;
125 
126     using Base::GetAllocatableCount;
127 
128     /* Please see man pages for details
129 
130 
131 
132      */
GetStartAddress()133     virtual void* GetStartAddress() const { return Base::GetStartAddress(); }
134 
135     /* Please see man pages for details
136 
137 
138 
139      */
GetTotalSize()140     virtual size_t GetTotalSize() const { return Base::GetTotalSize(); }
141 
142     /* Please see man pages for details
143 
144     */
Dump()145     virtual void Dump() const { Base::Dump(); }
146 
147     /* Please see man pages for details
148 
149 
150 
151 
152 
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