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