1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_ExpHeap.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: 31762 $
14  *---------------------------------------------------------------------------*/
15 
16 /* Please see man pages for details
17 
18 
19 */
20 
21 #ifndef NN_FND_FND_EXPHEAP_H_
22 #define NN_FND_FND_EXPHEAP_H_
23 
24 #include <nn/types.h>
25 #include <nn/fnd/fnd_HeapBase.h>
26 #include <nn/fnd/fnd_MemoryRange.h>
27 #include <nn/fnd/fnd_Allocator.h>
28 #include <nn/util/util_TypeTraits.h>
29 #include <nn/util/detail/util_CLibImpl.h>
30 #include <nn/util/util_SizedEnum.h>
31 #include <nn/fnd/detail/fnd_DetailHeapHead.h>
32 #include <nn/os.h>
33 
34 #define NN_FND_EXPHEAP_ALLOCATION_MODE_FIRST_FIT 0
35 #define NN_FND_EXPHEAP_ALLOCATION_MODE_BEST_FIT 1
36 
37 #define NN_FND_EXPHEAP_ALLOCATION_DIRECTION_FRONT 0
38 #define NN_FND_EXPHEAP_ALLOCATION_DIRECTION_REAR 1
39 
40 #ifdef __cplusplus
41 
42 namespace nn { namespace fnd {
43 
44 /* Please see man pages for details
45 
46 
47 
48  */
49 class ExpHeapBase : public HeapBase
50 {
51 public:
52 
53     /* Please see man pages for details
54 
55      */
56     enum AllocationMode
57     {
58         /* Please see man pages for details
59 
60          */
61         ALLOCATION_MODE_FIRST_FIT = NN_FND_EXPHEAP_ALLOCATION_MODE_FIRST_FIT,
62         /* Please see man pages for details
63 
64          */
65         ALLOCATION_MODE_BEST_FIT  = NN_FND_EXPHEAP_ALLOCATION_MODE_BEST_FIT
66     };
67 
68     /* Please see man pages for details
69 
70      */
71     enum AllocationDirection
72     {
73         /* Please see man pages for details
74 
75          */
76         ALLOCATION_DIRECTION_FRONT = NN_FND_EXPHEAP_ALLOCATION_DIRECTION_FRONT,
77         /* Please see man pages for details
78 
79          */
80         ALLOCATION_DIRECTION_REAR  = NN_FND_EXPHEAP_ALLOCATION_DIRECTION_REAR
81     };
82 
83     /* Please see man pages for details
84 
85     */
86     typedef void (*BlockVisitor)(void* pBlock, const ExpHeapBase* heap, uptr param);
87 
88     /* Please see man pages for details
89 
90 
91 
92 
93 
94      */
95     size_t GetSizeOf(const void* pBlock) const;
96 
97     /* Please see man pages for details
98 
99 
100 
101 
102 
103      */
104     bit8 GetGroupIdOf(const void* pBlock) const;
105 
106     /* Please see man pages for details
107 
108 
109 
110 
111 
112      */
113     AllocationDirection GetDirectionOf(const void* pBlock) const;
114 
115 protected:
116 
ExpHeapBase()117 	ExpHeapBase() : m_AllocCount(0) {}
118 
119     template <class MemoryBlock>
ExpHeapBase(const MemoryBlock & block,bit32 option)120     explicit ExpHeapBase(const MemoryBlock& block, bit32 option) { Initialize(block.GetAddress(), block.GetSize(), option); }
121 
ExpHeapBase(uptr addr,size_t size,bit32 option)122     ExpHeapBase(uptr addr, size_t size, bit32 option) { Initialize(addr, size, option); }
123 
124     void Initialize(uptr addr, size_t size, bit32 option);
125 
126     void Invalidate();
127 
128     void Finalize();
129 
~ExpHeapBase()130     virtual ~ExpHeapBase() { Finalize(); }
131 
132     void* Allocate(size_t byteSize, s32 alignment = DEFAULT_ALIGNMENT, bit8 groupId = 0, AllocationMode mode = ALLOCATION_MODE_FIRST_FIT, bool reuse = false);
133 
134     void Free(void* p);
135 
FreeV(void * p)136     virtual void FreeV(void* p) { Free(p); }
137 
138     size_t ResizeBlock(void* p, size_t newSize);
139 
140     void VisitAllBlocks(BlockVisitor visitor, uptr param);
141 
142     virtual void* GetStartAddress() const;
143 
144     virtual size_t GetTotalSize() const;
145 
146     size_t GetTotalFreeSize() const;
147 
148     size_t GetAllocatableSize(s32 alignment = DEFAULT_ALIGNMENT) const;
149 
150     u32 Adjust();
151 
152     MemoryRange Adjust(HeapAdjustMode mode);
153 
154     bool CheckHeap(bit32 option = OPTION_ERROR_PRINT) const;
155 
156     bool CheckBlock(const void* p, bit32 option = OPTION_ERROR_PRINT) const;
157 
158     virtual void Dump() const;
159 
160     virtual bool HasAddress(const void* addr) const;
161 
162 private:
163 
164     detail::ExpHeapImpl m_ExpHeapImpl;
165 
166     size_t m_AllocCount;
167 
168 };
169 
170 /* Please see man pages for details
171 
172 
173 
174 
175 
176 
177 
178 
179 
180 
181 
182 
183  */
184 template <class LockPolicy>
185 class ExpHeapTemplate : public ExpHeapBase, private LockPolicy::LockObject
186 {
187 private:
188     typedef ExpHeapBase Base;
189     typedef typename LockPolicy::LockObject LockObject;
190     typedef typename LockPolicy::ScopedLock ScopedLock;
191 public:
192 
193     /* Please see man pages for details
194 
195 
196 
197 
198 
199      */
ExpHeapTemplate()200     ExpHeapTemplate() {}
201 
202     /* Please see man pages for details
203 
204 
205 
206 
207 
208 
209 
210 
211 
212 
213      */
214     template <class MemoryBlock>
215     explicit ExpHeapTemplate(const MemoryBlock& block, bit32 option = 0)
216     {
217         Initialize(block.GetAddress(), block.GetSize(), option);
218     }
219 
220     /* Please see man pages for details
221 
222 
223 
224 
225 
226 
227 
228 
229 
230 
231 
232      */
233     ExpHeapTemplate(uptr addr, size_t size, bit32 option = 0)
234     {
235         Initialize(addr, size, option);
236     }
237 
238     /* Please see man pages for details
239 
240 
241 
242 
243 
244 
245 
246 
247 
248      */
249     void Initialize(uptr addr, size_t size, bit32 option = 0)
250     {
251         Base::Initialize(addr, size, option);
252         LockObject::Initialize();
253     }
254 
255     /* Please see man pages for details
256 
257 
258 
259 
260 
261 
262 
263 
264 
265 
266 
267 
268 
269 
270 
271 
272     */
273     static ExpHeapTemplate* Create(HeapBase* parent, void* addr, size_t size, bit32 option = 0, bit32 placement = HEAP_INFOPLACEMENT_HEAD);
274 
275     /* Please see man pages for details
276 
277 
278 
279      */
Invalidate()280     void Invalidate() { Base::Invalidate(); }
281 
282     /* Please see man pages for details
283 
284 
285 
286      */
Finalize()287     void Finalize()
288     {
289         LockObject::Finalize();
290         Base::Finalize();
291     }
292 
293     /* Please see man pages for details
294 
295 
296 
297      */
~ExpHeapTemplate()298     virtual ~ExpHeapTemplate() {}
299 
300     /* Please see man pages for details
301 
302 
303 
304 
305 
306 
307 
308 
309 
310 
311 
312 
313 
314      */
315     void* Allocate(size_t byteSize, s32 alignment = DEFAULT_ALIGNMENT, bit8 groupId = 0, AllocationMode mode = ALLOCATION_MODE_FIRST_FIT, bool reuse = false)
316     {
317         ScopedLock lk(*this);
318         return Base::Allocate(byteSize, alignment, groupId, mode, reuse);
319     }
320 
321     /* Please see man pages for details
322 
323 
324 
325 
326 
327      */
Free(void * p)328     void Free(void* p)
329     {
330         ScopedLock lk(*this);
331         Base::Free(p);
332     }
333 
334     /* Please see man pages for details
335 
336 
337 
338 
339 
340 
341 
342     */
FreeV(void * p)343     virtual void FreeV(void* p) { Free(p); }
344 
345     /* Please see man pages for details
346 
347 
348 
349 
350 
351 
352      */
ResizeBlock(void * p,size_t newSize)353     size_t ResizeBlock(void* p, size_t newSize)
354     {
355         ScopedLock lk(*this);
356         return Base::ResizeBlock(p, newSize);
357     }
358 
359     /* Please see man pages for details
360 
361 
362 
363 
364 
365 
366      */
VisitAllBlocks(BlockVisitor visitor,uptr param)367     void VisitAllBlocks(BlockVisitor visitor, uptr param)
368     {
369         ScopedLock lk(*this);
370         return Base::VisitAllBlocks(visitor, param);
371     }
372 
373     /* Please see man pages for details
374 
375 
376 
377      */
GetStartAddress()378     virtual void* GetStartAddress() const
379     {
380         ScopedLock lk(*this);
381         return Base::GetStartAddress();
382     }
383 
384     /* Please see man pages for details
385 
386 
387 
388      */
GetTotalSize()389     virtual size_t GetTotalSize() const
390     {
391         ScopedLock lk(*this);
392         return Base::GetTotalSize();
393     }
394 
395     /* Please see man pages for details
396 
397 
398 
399      */
GetTotalFreeSize()400     size_t GetTotalFreeSize() const
401     {
402         ScopedLock lk(*this);
403         return Base::GetTotalFreeSize();
404     }
405 
406     /* Please see man pages for details
407 
408 
409 
410 
411 
412      */
413     size_t GetAllocatableSize(s32 alignment = DEFAULT_ALIGNMENT) const
414     {
415         ScopedLock lk(*this);
416         return Base::GetAllocatableSize(alignment);
417     }
418 
419     /* Please see man pages for details
420 
421 
422 
423 
424 
425 
426 
427 
428      */
Adjust()429     u32 Adjust()
430     {
431         ScopedLock lk(*this);
432         return Base::Adjust();
433     }
434 
435     /* Please see man pages for details
436 
437 
438 
439 
440 
441 
442 
443 
444      */
Adjust(HeapAdjustMode mode)445     MemoryRange Adjust(HeapAdjustMode mode)
446     {
447         ScopedLock lk(*this);
448         return Base::Adjust(mode);
449     }
450 
451     /* Please see man pages for details
452 
453 
454 
455 
456 
457      */
458     bool CheckHeap(bit32 option = OPTION_ERROR_PRINT) const
459     {
460         ScopedLock lk(*this);
461         return Base::CheckHeap(option);
462     }
463 
464     /* Please see man pages for details
465 
466 
467 
468 
469 
470 
471      */
472     bool CheckBlock(const void* p, bit32 option = OPTION_ERROR_PRINT) const
473     {
474         ScopedLock lk(*this);
475         return Base::CheckBlock(p, option);
476     }
477 
478     /* Please see man pages for details
479 
480 
481 
482 
483 
484     */
HasAddress(const void * addr)485     virtual bool HasAddress(const void* addr) const
486     {
487         ScopedLock lk(*this);
488         return Base::HasAddress(addr);
489     }
490 
491     /* Please see man pages for details
492 
493 
494 
495      */
Dump()496     virtual void Dump() const
497     {
498         ScopedLock lk(*this);
499         Base::Dump();
500     }
501 
502     class Allocator;
503 
504 };
505 
506 /* Please see man pages for details
507 
508  */
509 template <class LockPolicy>
510 class ExpHeapTemplate<LockPolicy>::Allocator : public IAllocator
511 {
512 public:
513 
514     /* Please see man pages for details
515 
516 
517 
518 
519 
520 
521      */
522     Allocator(ExpHeapTemplate<LockPolicy>& heap, bit8 groupId = 0, AllocationMode mode = ExpHeapBase::ALLOCATION_MODE_FIRST_FIT, bool reuse = false) : m_Heap(0) { Initialize(heap, groupId, mode, reuse); }
523 
524     /* Please see man pages for details
525 
526      */
Allocator()527     Allocator() : m_Heap(0) {}
528 
529     /* Please see man pages for details
530 
531 
532 
533 
534 
535 
536      */
537     void Initialize(ExpHeapTemplate<LockPolicy>& heap, bit8 groupId = 0, AllocationMode mode = ExpHeapBase::ALLOCATION_MODE_FIRST_FIT, bool reuse = false)
538     {
539         NN_TASSERT_(!this->m_Heap);
540         this->m_Heap = &heap;
541         this->m_GroupId = groupId;
542         this->m_AllocationMode = mode;
543         this->m_Reuse = reuse;
544     }
545 
546     /* Please see man pages for details
547 
548 
549      */
GetHeap()550     ExpHeapTemplate<LockPolicy>* GetHeap() { return m_Heap; }
551 
552     /* Please see man pages for details
553 
554 
555      */
GetHeap()556     const ExpHeapTemplate<LockPolicy>* GetHeap() const { return m_Heap; }
557 
558     /* Please see man pages for details
559 
560 
561 
562 
563 
564 
565     */
Allocate(size_t size,s32 alignment)566     virtual void* Allocate(size_t size, s32 alignment) { return m_Heap->Allocate(size, alignment, m_GroupId, m_AllocationMode, m_Reuse); }
567 
568     /* Please see man pages for details
569 
570 
571     */
Free(void * p)572     virtual void Free(void* p) { m_Heap->Free(p); }
573 
574     /* Please see man pages for details
575 
576 
577      */
GetGroupId()578     bit8 GetGroupId() const { return m_GroupId; }
579 
580     /* Please see man pages for details
581 
582 
583      */
SetGroupId(bit8 groupId)584     void SetGroupId(bit8 groupId) { this->m_GroupId = groupId; }
585 
586     /* Please see man pages for details
587 
588 
589      */
GetAllocationMode()590     AllocationMode GetAllocationMode() const { return m_AllocationMode; }
591 
592     /* Please see man pages for details
593 
594 
595      */
SetAllocationMode(AllocationMode allocationMode)596     void SetAllocationMode(AllocationMode allocationMode) { this->m_AllocationMode = allocationMode; }
597 
598     /* Please see man pages for details
599 
600 
601      */
GetUseMarginOfAlignment()602     bool GetUseMarginOfAlignment() const { return m_Reuse; }
603 
604     /* Please see man pages for details
605 
606 
607      */
SetUseMarginOfAlignment(bool reuse)608     void SetUseMarginOfAlignment(bool reuse) { m_Reuse = reuse; }
609 
610 private:
611     ExpHeapTemplate<LockPolicy>* m_Heap;
612     bit8 m_GroupId;
613     nn::util::SizedEnum1<AllocationMode> m_AllocationMode;
614     bool m_Reuse;
615     NN_PADDING1;
616 };
617 
618 /* Please see man pages for details
619 
620 */
621 typedef ExpHeapTemplate<nn::os::LockPolicy::NoLock> ExpHeap;
622 
623 /* Please see man pages for details
624 
625 */
626 typedef ExpHeapTemplate<nn::os::LockPolicy::Object<nn::os::CriticalSection> > ThreadSafeExpHeap;
627 
628 template <class LockPolicy>
Create(HeapBase * parent,void * addr,size_t size,bit32 option,bit32 placement)629 ExpHeapTemplate<LockPolicy>* ExpHeapTemplate<LockPolicy>::Create(HeapBase* parent, void* addr, size_t size, bit32 option, bit32 placement)
630 {
631     ExpHeapTemplate* heap;
632 
633     if ( parent->FindHeap(addr) != parent ) return 0;
634 
635     if ( placement == HEAP_INFOPLACEMENT_HEAD )
636     {
637         heap = new (addr) ExpHeapTemplate(reinterpret_cast<uptr>(addr)+sizeof(ExpHeapTemplate), static_cast<size_t>(size - sizeof(ExpHeapTemplate)), option);
638     }
639     else if ( placement == HEAP_INFOPLACEMENT_TAIL )
640     {
641         void* placeaddr = reinterpret_cast<void*>(reinterpret_cast<uptr>(addr)+static_cast<size_t>(size - sizeof(ExpHeapTemplate)));
642         heap = new (placeaddr) ExpHeapTemplate(reinterpret_cast<uptr>(addr), static_cast<size_t>(size - sizeof(ExpHeapTemplate)), option);
643     }
644     else
645     {
646         return 0;
647     }
648 
649     heap->SetParent(parent);
650 
651     return heap;
652 }
653 
654 }}
655 
656 #endif
657 
658 #endif
659