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