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: 29622 $
14  *---------------------------------------------------------------------------*/
15 
16 /*! @file
17   @brief    拡張ヒープに関するAPIの宣言
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 /*!
45     @brief    拡張ヒープのベースクラスです。
46 
47               このクラスのインスタンスを直接作成することはできません。
48  */
49 class ExpHeapBase : public HeapBase
50 {
51 public:
52 
53     /*!
54         @brief メモリブロック確保のモードです。
55      */
56     enum AllocationMode
57     {
58         /*!
59             @brief 確保しようとしているメモリブロックのサイズ以上の大きさを持つ、最初に見つかった空き領域からメモリブロックを確保します。
60          */
61         ALLOCATION_MODE_FIRST_FIT = NN_FND_EXPHEAP_ALLOCATION_MODE_FIRST_FIT,
62         /*!
63             @brief 確保しようとしているメモリブロックのサイズに一番近いサイズの空き領域を探し、その空き領域からメモリブロックを確保します。
64          */
65         ALLOCATION_MODE_BEST_FIT  = NN_FND_EXPHEAP_ALLOCATION_MODE_BEST_FIT
66     };
67 
68     /*!
69         @brief メモリブロック確保の方向を指定するための定数です。
70      */
71     enum AllocationDirection
72     {
73         /*!
74             @brief メモリブロックの確保時に、ヒープの空き領域の前方から確保します。
75          */
76         ALLOCATION_DIRECTION_FRONT = NN_FND_EXPHEAP_ALLOCATION_DIRECTION_FRONT,
77         /*!
78             @brief メモリブロックの確保時に、ヒープの空き領域の後方から確保します。
79          */
80         ALLOCATION_DIRECTION_REAR  = NN_FND_EXPHEAP_ALLOCATION_DIRECTION_REAR
81     };
82 
83     /*!
84         @brief ブロックを巡るときに呼び出されるコールバック関数の型です。
85     */
86     typedef void (*BlockVisitor)(void* pBlock, const ExpHeapBase* heap, uptr param);
87 
88     /*!
89         @brief 拡張ヒープから確保したメモリブロックのサイズを取得します。
90 
91         @param[in] pBlock メモリブロックの先頭アドレスを指定します。
92 
93         @return 拡張ヒープから確保したメモリブロックのサイズを返します。ここで返される値は、アラインメントなどの制約により、確保時のサイズより大きい値を返すことがあります。
94      */
95     size_t GetSizeOf(const void* pBlock) const;
96 
97     /*!
98         @brief 拡張ヒープから確保したメモリブロックのグループIDを取得します。
99 
100         @param[in] pBlock メモリブロックの先頭アドレスを指定します。
101 
102         @return 拡張ヒープから確保したメモリブロックのグループIDを返します。
103      */
104     bit8 GetGroupIdOf(const void* pBlock) const;
105 
106     /*!
107         @brief 拡張ヒープから確保したメモリブロックのメモリ確保の方向を取得します。
108 
109         @param[in] pBlock メモリブロックの先頭アドレスを指定します。
110 
111         @return 拡張ヒープから確保したメモリブロックのメモリ確保の方向を返します。
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 /*!
171     @brief    拡張ヒープのためのクラステンプレートです。
172 
173               このクラステンプレートを実体化したクラスでは、
174               指定したロックポリシーによって、排他制御が行われます。
175               ロックポリシーは @ref nn::os::LockPolicy クラスの内部で宣言される
176               クラスもしくはクラステンプレートを実体化したクラスを指定することができます。
177               上述のクラス以外を LockPolicy に指定した場合の動作・互換性は保障されません。
178 
179               ロックされるのは、ヒープ内の操作に対してのみであり、
180               ヒープの階層化に対する操作などを行う場合は、適切な排他処理などが別途必要となります。
181 
182     @tparam   LockPolicy ヒープに対する操作を行うときのロックポリシーを指定します。
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     /*!
194         :overload NotInitialize
195 
196         @brief コンストラクタです。
197 
198         初期化は行いません。
199      */
ExpHeapTemplate()200     ExpHeapTemplate() {}
201 
202     /*!
203         :overload WithMemoryBlock
204 
205         @brief コンストラクタです。
206 
207         @param[in] block    ヒープに割り当てるメモリブロックを指定します。
208         @param[in] option   オプションを指定します。
209 
210         ヒープの初期化を行います。
211 
212         Bug: option パラメータは未実装です。
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     /*!
221         :overload WithAddress
222 
223         @brief コンストラクタです。
224 
225         @param[in] addr     ヒープに割り当てるメモリブロックの先頭アドレスを指定します。
226         @param[in] size     ヒープに割り当てるメモリブロックのサイズを指定します。
227         @param[in] option   オプションを指定します。
228 
229         ヒープの初期化を行います。
230 
231         Bug: option パラメータは未実装です。
232      */
233     ExpHeapTemplate(uptr addr, size_t size, bit32 option = 0)
234     {
235         Initialize(addr, size, option);
236     }
237 
238     /*!
239         @brief ヒープの初期化を行います。
240 
241         @param[in] addr     ヒープに割り当てるメモリブロックの先頭アドレスを指定します。
242         @param[in] size     ヒープに割り当てるメモリブロックのサイズを指定します。
243         @param[in] option   オプションを指定します。
244 
245         Bug: option パラメータは未実装です。
246 
247         @return 無し。
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     /*!
256         @brief  ヒープ内に拡張ヒープを作成します。
257 
258                 この関数で作成したヒープは @ref HeapBase::Destroy により破壊してください。
259 
260                 ExpHeap自身をaddrとsizeで指定した領域内に作成します。
261                 このため、指定した領域の大きさから sizeof(ExpHeap) の大きさだけ少ない領域をヒープとして割り当てます。
262 
263                 placementによりExpHeapオブジェクト自身の配置場所を指定します。
264                 placementに HEAP_INFOPLACEMENT_HEAD を指定すると領域の先頭(addr から addr+sizeof(ExpHeap) までの領域)にExpHeapオブジェクト自身を配置します。
265                 placementに HEAP_INFOPLACEMENT_TAIL を指定すると領域の末尾(addr+size-sizeof(ExpHeap) から addr+size までの領域)にExpHeapオブジェクト自身を配置します。
266 
267         @param[in] parent       addr を領域内に持つ親のヒープを指定します。
268         @param[in] addr         ヒープに割り当てるメモリブロックの先頭アドレスを指定します。
269         @param[in] size         ヒープに割り当てるメモリブロックのサイズを指定します。
270         @param[in] option       オプションを指定します。
271         @param[in] placement    管理領域(ExpHeapオブジェクト)の配置場所を指定します。
272     */
273     static ExpHeapTemplate* Create(HeapBase* parent, void* addr, size_t size, bit32 option = 0, bit32 placement = HEAP_INFOPLACEMENT_HEAD);
274 
275     /*!
276         @brief ヒープを無効にします。
277 
278         @return 無し。
279      */
Invalidate()280     void Invalidate() { Base::Invalidate(); }
281 
282     /*!
283         @brief ヒープが有効ならば破棄します。
284 
285         @return 無し。
286      */
Finalize()287     void Finalize()
288     {
289         LockObject::Finalize();
290         Base::Finalize();
291     }
292 
293     /*!
294         @brief デストラクタです。内部でFinalize()を呼びます。
295 
296         @return 無し。
297      */
~ExpHeapTemplate()298     virtual ~ExpHeapTemplate() {}
299 
300     /*!
301         @brief 拡張ヒープからメモリを確保します。
302 
303         alignment に指定可能な値は、-128, -64, -32, -16, -8, -4, 4, 8, 16, 32, 64, 128 のいずれかの値です。
304 
305         alignment に正の値を指定すると、ヒープ領域の先頭から探索して見つけた空き領域を確保して、負の値を指定すると、ヒープ領域の後方から探索して見つけた空き領域を確保します。
306 
307         @param[in] byteSize         確保するメモリブロックのサイズ(バイト)を指定します。
308         @param[in] alignment        アラインメントを指定します。-128 <= alignment <= 128 の範囲で絶対数が4以上の2のべき乗になる値を指定できます。
309         @param[in] groupId          グループIDを指定します。
310         @param[in] mode             メモリブロック確保のモードを指定します。
311         @param[in] reuse            アラインメントの際に発生する隙間の領域を再利用するかどうかを指定します。
312 
313         @return 確保したメモリブロックの先頭アドレスを返します。
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     /*!
322         @brief 拡張ヒープから確保したメモリブロックを解放します。
323 
324         @param[in] p    解放するメモリブロックの先頭アドレスを指定します。
325 
326         @return 無し。
327      */
Free(void * p)328     void Free(void* p)
329     {
330         ScopedLock lk(*this);
331         Base::Free(p);
332     }
333 
334     /*!
335         @brief          拡張ヒープから確保したメモリブロックを解放します。
336 
337                         仮想メンバ関数であるため、HeapBaseから解放できます。
338 
339         @param[in] p    解放するメモリブロックの先頭アドレスを指定します。
340 
341         @return         無し。
342     */
FreeV(void * p)343     virtual void FreeV(void* p) { Free(p); }
344 
345     /*!
346         @brief 拡張ヒープから確保したメモリブロックのサイズを変更します。
347 
348         @param[in] p        サイズを変更するメモリブロックの先頭アドレスを指定します。
349         @param[in] newSize  変更後のメモリブロックのサイズ(バイト)を指定します。
350 
351         @return 関数が成功した場合、変更後のメモリブロックのサイズ(バイト)を返します。 関数が失敗した場合、0 を返します。
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     /*!
360         @brief 拡張ヒープから確保した全てのメモリブロックに対し、ユーザが指定した関数 visitor を呼びます。
361 
362         @param[in] visitor  各メモリブロックに対して呼ぶ関数を指定します。
363         @param[in] param    visitor関数に渡す引数を指定します。
364 
365         @return 無し。
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     /*!
374         @brief 拡張ヒープのメモリ領域の開始アドレスを取得します。
375 
376         @return 拡張ヒープのメモリ領域の開始アドレスをを返します。
377      */
GetStartAddress()378     virtual void* GetStartAddress() const
379     {
380         ScopedLock lk(*this);
381         return Base::GetStartAddress();
382     }
383 
384     /*!
385         @brief 拡張ヒープに割り当てられているメモリサイズを取得します。
386 
387         @return 拡張ヒープに割り当てられているメモリサイズを返します。
388      */
GetTotalSize()389     virtual size_t GetTotalSize() const
390     {
391         ScopedLock lk(*this);
392         return Base::GetTotalSize();
393     }
394 
395     /*!
396         @brief 拡張ヒープの空きメモリサイズを取得します。
397 
398         @return 拡張ヒープの空きメモリの合計を返します。
399      */
GetTotalFreeSize()400     size_t GetTotalFreeSize() const
401     {
402         ScopedLock lk(*this);
403         return Base::GetTotalFreeSize();
404     }
405 
406     /*!
407         @brief 拡張ヒープから確保可能なメモリブロックのサイズを取得します。
408 
409         @param[in] alignment    アラインメントを指定します。
410 
411         @return 拡張ヒープから確保可能なメモリブロックのサイズを返します。
412      */
413     size_t GetAllocatableSize(s32 alignment = DEFAULT_ALIGNMENT) const
414     {
415         ScopedLock lk(*this);
416         return Base::GetAllocatableSize(alignment);
417     }
418 
419     /*!
420         :overload deprecated
421 
422         @brief  この関数の使用は推奨されません。拡張ヒープの末尾側の空き領域を開放し、拡張ヒープが使用するメモリを縮小します。
423 
424                 この関数の戻り値は、Adjust に失敗した場合の0と、何も Allocate されていないために、
425                 縮小後のヒープのサイズが0になった場合を区別できません。
426 
427         @return 関数が成功した場合は縮小後の拡張ヒープの全体サイズを、失敗した場合は 0 を返します。
428      */
Adjust()429     u32 Adjust()
430     {
431         ScopedLock lk(*this);
432         return Base::Adjust();
433     }
434 
435     /*!
436         :overload withmode
437 
438         @brief              拡張ヒープの空き領域を開放し、拡張ヒープが使用するメモリを縮小します。
439 
440         @param[in] mode     末尾(HEAP_ADJUST_TAIL)から縮小するか、先頭(HEAP_ADJUST_HEAD)から縮小するかを指定します。
441 
442         @return             ヒープが縮小されることにより空いたメモリ領域の範囲を返します。
443                             縮小できない場合の戻り値のMemoryRangeの大きさは0になります。
444      */
Adjust(HeapAdjustMode mode)445     MemoryRange Adjust(HeapAdjustMode mode)
446     {
447         ScopedLock lk(*this);
448         return Base::Adjust(mode);
449     }
450 
451     /*!
452         @brief 拡張ヒープが破壊されていないかどうかをチェックします。
453 
454         @param[in] option   オプションを指定します。
455 
456         @return チェックが成功するとtrue、失敗するとfalseを返します。
457      */
458     bool CheckHeap(bit32 option = OPTION_ERROR_PRINT) const
459     {
460         ScopedLock lk(*this);
461         return Base::CheckHeap(option);
462     }
463 
464     /*!
465         @brief 拡張ヒープから確保したメモリブロックのチェックを行います。
466 
467         @param[in] p        メモリブロックの先頭アドレスを指定します。
468         @param[in] option   オプションを指定します。
469 
470         @return チェックが成功するとtrue、失敗するとfalseを返します。
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     /*!
479         @brief  指定したアドレスがヒープに含まれているか調べます。
480 
481         @param[in]  addr    調べたいアドレスを指定します。
482 
483         @return ヒープに含まれていれば true を返し、含まれていなければ false を返します。
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     /*!
492         @brief ヒープ内部の情報を表示します。(デバッグ用)
493 
494         @return 無し。
495      */
Dump()496     virtual void Dump() const
497     {
498         ScopedLock lk(*this);
499         Base::Dump();
500     }
501 
502     class Allocator;
503 
504 };
505 
506 /*!
507     @brief 拡張ヒープ用のアロケータクラスです。
508  */
509 template <class LockPolicy>
510 class ExpHeapTemplate<LockPolicy>::Allocator : public IAllocator
511 {
512 public:
513 
514     /*!
515         @brief 拡張ヒープとアロケートオプションを指定したコンストラクタです。
516 
517         @param[in] heap             拡張ヒープを指定します。
518         @param[in] groupId          グループ ID を指定します。
519         @param[in] mode             メモリブロック確保のモードを指定します。
520         @param[in] reuse            アラインメントの際に発生する隙間の領域を再利用するかどうかを指定します。
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     /*!
525         @brief 初期化をしないコンストラクタです。
526      */
Allocator()527     Allocator() : m_Heap(0) {}
528 
529     /*!
530         @brief 初期化されていないアロケータを初期化します。
531 
532         @param[in] heap             拡張ヒープを指定します。
533         @param[in] groupId          グループ ID を指定します。
534         @param[in] mode             メモリブロック確保のモードを指定します。
535         @param[in] reuse            アラインメントの際に発生する隙間の領域を再利用するかどうかを指定します。
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     /*!
547         @brief アロケータにセットされている拡張ヒープを返します。
548         @return アロケータにセットされている拡張ヒープ
549      */
GetHeap()550     ExpHeapTemplate<LockPolicy>* GetHeap() { return m_Heap; }
551 
552     /*!
553         @brief アロケータにセットされている拡張ヒープを返します。
554         @return アロケータにセットされている拡張ヒープ
555      */
GetHeap()556     const ExpHeapTemplate<LockPolicy>* GetHeap() const { return m_Heap; }
557 
558     /*!
559         @brief 指定したサイズとアラインメントでメモリ領域を確保します。
560 
561         @param[in] size 確保するメモリのサイズ
562         @param[in] alignment 確保するメモリのアラインメント
563 
564         @return 確保したメモリ領域の先頭へのポインタ
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     /*!
569         @brief メモリ領域を解放します。
570         @param[in] p 確保されているメモリ領域の先頭へのポインタ
571     */
Free(void * p)572     virtual void Free(void* p) { m_Heap->Free(p); }
573 
574     /*!
575         @brief メモリ確保時のグループ ID を取得します。
576         @return メモリ確保時のグループ ID
577      */
GetGroupId()578     bit8 GetGroupId() const { return m_GroupId; }
579 
580     /*!
581         @brief メモリ確保時のグループ ID を設定します。
582         @param[in] groupId グループ ID を指定します。
583      */
SetGroupId(bit8 groupId)584     void SetGroupId(bit8 groupId) { this->m_GroupId = groupId; }
585 
586     /*!
587         @brief メモリ確保時のモードを取得します。
588         @return メモリ確保時のモード
589      */
GetAllocationMode()590     AllocationMode GetAllocationMode() const { return m_AllocationMode; }
591 
592     /*!
593         @brief メモリ確保時のモードを設定します。
594         @param[in] allocationMode メモリ確保時のモード
595      */
SetAllocationMode(AllocationMode allocationMode)596     void SetAllocationMode(AllocationMode allocationMode) { this->m_AllocationMode = allocationMode; }
597 
598     /*!
599         @brief メモリ確保の際に、アラインメントの際に発生する隙間の領域を再利用するかどうかを指定します。
600         @return アラインメントの際に発生する隙間の領域を再利用するなら ture 、しないなら false
601      */
GetUseMarginOfAlignment()602     bool GetUseMarginOfAlignment() const { return m_Reuse; }
603 
604     /*!
605         @brief アラインメントの際に発生する隙間の領域を再利用するかどうかを設定します。
606         @param[in] reuse アラインメントの際に発生する隙間の領域を再利用するかどうか
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 /*!
619     @brief ロック操作をしないスレッドアンセーフな拡張ヒープを表す型です。
620 */
621 typedef ExpHeapTemplate<nn::os::LockPolicy::NoLock> ExpHeap;
622 
623 /*!
624     @brief ヒープごとに用意されるクリティカルセクションで保護された、スレッドセーフな拡張ヒープを表す型です。
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