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