/*---------------------------------------------------------------------------* Project: NintendoWare File: demo_Memory.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 24950 $ *---------------------------------------------------------------------------*/ #ifndef NW_DEMO_MEMORY_H_ #define NW_DEMO_MEMORY_H_ #include #include #include #include namespace nw { namespace demo { class DemoAllocator; // デモではデバイスメモリから全てのメモリを確保するようになっています。 // デモで使用するメモリサイズです。 const size_t DEMO_MEMORY_SIZE = 0x1000000; // パーティクル用のメモリサイズです。 const size_t DEMO_PARTICLE_MEMORY_SIZE = 0x100000; //===================== //! @name メモリアロケーター //@{ //! @brief 与えられたデモアロケータを初期化します。 //! //! @param[in] allocator 初期化するデモアロケータです。 //! @param[in] size アロケータで管理するメモリサイズです。 //! @param[in] option 拡張ヒープのオプションです。 //! void InitializeDemoAllocator(DemoAllocator* allocator, size_t size, bit32 option = 0 ); //! @brief 与えられたデモアロケータを解放します。 //! //! @param[in] allocator 解放するデモアロケータです。 //! void FinalizeDemoAllocator(DemoAllocator* allocator); //--------------------------------------------------------------------------- //! @brief デモ用にメモリを初期化します。 //! //! 明示的に呼ばれなかった場合には、初回のアロケート実行時に実行されます。 //--------------------------------------------------------------------------- void InitializeDemoMemory(); //--------------------------------------------------------------------------- //! @brief アライメントされたメモリを確保したアドレスへ戻します。 //! //! @param[in] memory アラインされたメモリのポインタです。 //! //! @return アライン前のアドレスを返します。 //--------------------------------------------------------------------------- void* UnAlignMemory( void* memory ); //--------------------------------------------------------------------------- //! @brief メインメモリからメモリ領域を確保します。 //! //! @param[in] size 確保するメモリサイズです。 //! @param[in] alignment 確保するメモリのアライメント値です。 //! //! @return 確保したメモリアドレスです。 //--------------------------------------------------------------------------- void* Alloc(size_t size, u8 alignment = 4); //--------------------------------------------------------------------------- //! @brief ヒープへメモリ領域を解放します。 //! //! @param[in] memory 解放するメモリ領域です。 //--------------------------------------------------------------------------- void Free(void* memory); //--------------------------------------------------------------------------- //! @brief メインメモリの状態を表示します。 //--------------------------------------------------------------------------- void Dump(); //@} //--------------------------------------------------------------------------- //! @brief デモ用のメインメモリアロケータです。 //--------------------------------------------------------------------------- class DemoAllocator : public nw::os::IAllocator { public: //! @brief コンストラクタです。 DemoAllocator() : m_StartAddress(0), m_BreakAllocAddress(NULL), m_BreakAllocSize(0), m_BreakFreeAddress(NULL), m_BreakFreeSize(0) {} //===================== //! @name 作成/破棄 //@{ //! @brief デモ用のアロケータを初期化します。 //! 内部で拡張ヒープを初期化します。 //! //! @param[in] startAddress 先頭アドレスです。 //! @param[in] size アロケートできるサイズです。 //! @param[in] option 拡張ヒープのオプションです。 //! void Initialize(uptr startAddress, size_t size, bit32 option = 0); //! @brief デモ用のアロケータを破棄します。 //! void Finalize(); //@} //! @brief 初期化時に指定した先頭アドレスを取得します。 //! //! @return 先頭アドレスです。 uptr GetStartAddress() const { return m_StartAddress; } //===================== //! @name メモリの確保と解放 //@{ //! @brief メインメモリからメモリを確保します。 //! //! @param[in] size 確保するメモリサイズです。 //! @param[in] alignment アライメントです。 //! //! @return 確保したメモリアドレスを返します。 virtual void* Alloc(size_t size, u8 alignment) { NW_ASSERT(size != 0); void* memory = m_Heap.Allocate(size, alignment); #if defined(NW_DEBUG_TRAP_ALLOCATOR) if (memory != NULL) { void* unalignMemory = UnAlignMemory(memory); if (unalignMemory == m_BreakAllocAddress && (m_BreakAllocSize == 0 || GetMemoryBlockSize(unalignMemory) == m_BreakAllocSize)) { NW_DEV_LOG("Alloc(): Specified memory block allocated\n"); #if defined(NW_DEBUG_BREAK_ALLOCATOR) nn::dbg::Break(nn::dbg::BREAK_REASON_USER); #endif } } #endif return memory; } using nw::os::IAllocator::Alloc; //! @brief メインメモリにメモリを返却します。 //! //! @param[in] memory 返却するメモリアドレスです。 virtual void Free(void* memory) { #if defined(NW_DEBUG_TRAP_ALLOCATOR) void* unalignMemory = UnAlignMemory(memory); if (unalignMemory == m_BreakFreeAddress && (m_BreakFreeSize == 0 || GetMemoryBlockSize(unalignMemory) == m_BreakFreeSize)) { NW_DEV_LOG("Free(): Specified memory block freed\n"); #if defined(NW_DEBUG_BREAK_ALLOCATOR) nn::dbg::Break(nn::dbg::BREAK_REASON_USER); #endif } #endif m_Heap.Free(memory); } //@} //===================== //! @name デバッグ //@{ //--------------------------------------------------------------------------- //! @brief 空きメモリサイズを返します。 //! //! @return 空きメモリサイズです。 //--------------------------------------------------------------------------- size_t GetFreeSize(); //--------------------------------------------------------------------------- //! @brief 確保されたメモリブロックのサイズを返します。 //! //! @param[in] address メモリブロックの先頭アドレスを指定します。 //! //! @return 指定されたブロックのサイズです。 //--------------------------------------------------------------------------- size_t GetMemoryBlockSize(void* address); //! @brief メインメモリの状態を表示します。 void Dump(); //! @brief メモリ確保時の停止条件を設定します。 //! //! 指定したアドレスとサイズのメモリ確保が行われるときにプログラムを強制的に一時停止するように設定します。 //! NW_DEBUG_TRAP_ALLOCATOR マクロと NW_DEBUG_BREAK_ALLOCATOR マクロを定義することでこの機能は有効になります。 //! NW_DEBUG_TRAP_ALLOCATOR マクロのみを定義した場合はメッセージ出力のみを行います。 //! サイズに 0 を指定するとアドレスのみを条件とします。 //! //! アドレス、サイズともに Dump() で表示される数値(実際に確保されたアドレスとサイズ)を指定します。 //! //! @param address ブレーク条件のアドレスです。 //! @param size ブレーク条件のサイズです。 void SetBreakAlloc(int address, size_t size) { #if defined(NW_DEBUG_TRAP_ALLOCATOR) m_BreakAllocAddress = reinterpret_cast(address); m_BreakAllocSize = size; #else NW_UNUSED_VARIABLE(address); NW_UNUSED_VARIABLE(size); #endif } //! @brief メモリ解放時の停止条件を設定します。 //! //! 指定したアドレスとサイズのメモリが解放されるときにプログラムを強制的に一時停止するように設定します。 //! NW_DEBUG_TRAP_ALLOCATOR マクロと NW_DEBUG_BREAK_ALLOCATOR マクロを定義することでこの機能は有効になります。 //! NW_DEBUG_TRAP_ALLOCATOR マクロのみを定義した場合はメッセージ出力のみを行います。 //! サイズに 0 を指定するとアドレスのみを条件とします。 //! //! アドレス、サイズともに Dump() で表示される数値(実際に確保されたアドレスとサイズ)を指定します。 //! //! @param address ブレーク条件のアドレスです。 //! @param size ブレーク条件のサイズです。 void SetBreakFree(int address, size_t size) { #if defined(NW_DEBUG_TRAP_ALLOCATOR) m_BreakFreeAddress = reinterpret_cast(address); m_BreakFreeSize = size; #else NW_UNUSED_VARIABLE(address); NW_UNUSED_VARIABLE(size); #endif } //@} private: uptr m_StartAddress; void* m_BreakAllocAddress; size_t m_BreakAllocSize; void* m_BreakFreeAddress; size_t m_BreakFreeSize; nn::fnd::ExpHeap m_Heap; }; } // namespace demo } // namespace nw /* NW_DEMO_MEMORY_H_ */ #endif