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