1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: demo_Memory.h 4 5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain proprietary 8 information of Nintendo and/or its licensed developers and are protected by 9 national and international copyright laws. They may not be disclosed to third 10 parties or copied or duplicated in any form, in whole or in part, without the 11 prior written consent of Nintendo. 12 13 The content herein is highly confidential and should be handled accordingly. 14 15 $Revision: 31311 $ 16 *---------------------------------------------------------------------------*/ 17 18 #ifndef NW_DEMO_MEMORY_H_ 19 #define NW_DEMO_MEMORY_H_ 20 21 #include <nw/types.h> 22 #include <nw/os/os_Memory.h> 23 #include <nn/dbg.h> 24 #include <nn/fnd.h> 25 26 namespace nw { 27 namespace demo { 28 29 class DemoAllocator; 30 31 // デモではデバイスメモリから全てのメモリを確保するようになっています。 32 33 // デモで使用するメモリサイズです。 34 const size_t DEMO_MEMORY_SIZE = 0x1000000; 35 36 // パーティクル用のメモリサイズです。 37 const size_t DEMO_PARTICLE_MEMORY_SIZE = 0x100000; 38 39 //===================== 40 //! @name メモリアロケーター 41 //@{ 42 43 //! @brief 与えられたデモアロケータを初期化します。 44 //! 45 //! @param[in] allocator 初期化するデモアロケータです。 46 //! @param[in] size アロケータで管理するメモリサイズです。 47 //! @param[in] option 拡張ヒープのオプションです。 48 //! 49 void InitializeDemoAllocator(DemoAllocator* allocator, size_t size, bit32 option = 0 ); 50 51 //! @brief 与えられたデモアロケータを解放します。 52 //! 53 //! @param[in] allocator 解放するデモアロケータです。 54 //! 55 void FinalizeDemoAllocator(DemoAllocator* allocator); 56 57 //--------------------------------------------------------------------------- 58 //! @brief デモ用にメモリを初期化します。 59 //! 60 //! 明示的に呼ばれなかった場合には、初回のアロケート実行時に実行されます。 61 //--------------------------------------------------------------------------- 62 void InitializeDemoMemory(); 63 64 //--------------------------------------------------------------------------- 65 //! @brief アライメントされたメモリを確保したアドレスへ戻します。 66 //! 67 //! @param[in] memory アラインされたメモリのポインタです。 68 //! 69 //! @return アライン前のアドレスを返します。 70 //--------------------------------------------------------------------------- 71 void* UnAlignMemory( void* memory ); 72 73 //--------------------------------------------------------------------------- 74 //! @brief メインメモリからメモリ領域を確保します。 75 //! 76 //! @param[in] size 確保するメモリサイズです。 77 //! @param[in] alignment 確保するメモリのアライメント値です。 78 //! 79 //! @return 確保したメモリアドレスです。 80 //--------------------------------------------------------------------------- 81 void* Alloc(size_t size, u8 alignment = 4); 82 83 //--------------------------------------------------------------------------- 84 //! @brief ヒープへメモリ領域を解放します。 85 //! 86 //! @param[in] memory 解放するメモリ領域です。 87 //--------------------------------------------------------------------------- 88 void Free(void* memory); 89 90 //--------------------------------------------------------------------------- 91 //! @brief メインメモリの状態を表示します。 92 //--------------------------------------------------------------------------- 93 void Dump(); 94 95 //@} 96 97 //--------------------------------------------------------------------------- 98 //! @brief デモ用のメインメモリアロケータです。 99 //! 100 //! 内部で CTR-SDK の拡張ヒープを使用しています。 101 //--------------------------------------------------------------------------- 102 class DemoAllocator : public nw::os::IAllocator 103 { 104 public: 105 //! @brief コンストラクタです。 DemoAllocator()106 DemoAllocator() 107 : m_StartAddress(0), 108 m_BreakAllocAddress(NULL), 109 m_BreakAllocSize(0), 110 m_BreakFreeAddress(NULL), 111 m_BreakFreeSize(0) 112 {} 113 114 //===================== 115 //! @name 作成/破棄 116 //@{ 117 118 //! @brief デモ用のアロケータを初期化します。 119 //! 120 //! 内部で拡張ヒープを初期化します。 121 //! 122 //! @param[in] startAddress 先頭アドレスです。 123 //! @param[in] size アロケートできるサイズです。 124 //! @param[in] option 拡張ヒープのオプションです。 125 //! 126 void Initialize(uptr startAddress, size_t size, bit32 option = 0); 127 128 //! @brief デモ用のアロケータを破棄します。 129 //! 130 void Finalize(); 131 132 //@} 133 134 135 //! @brief 初期化時に指定した先頭アドレスを取得します。 136 //! 137 //! @return 先頭アドレスです。 GetStartAddress()138 uptr GetStartAddress() const { return m_StartAddress; } 139 140 //===================== 141 //! @name メモリの確保と解放 142 //@{ 143 144 //! @brief メインメモリからメモリを確保します。 145 //! 146 //! @param[in] size 確保するメモリサイズです。 147 //! @param[in] alignment アライメントです。 148 //! 149 //! @return 確保したメモリアドレスを返します。 Alloc(size_t size,u8 alignment)150 virtual void* Alloc(size_t size, u8 alignment) 151 { 152 NW_ASSERT(size != 0); 153 154 void* memory = m_Heap.Allocate(size, alignment); 155 156 #if defined(NW_DEBUG_TRAP_ALLOCATOR) 157 if (memory != NULL) 158 { 159 void* unalignMemory = UnAlignMemory(memory); 160 if (unalignMemory == m_BreakAllocAddress && 161 (m_BreakAllocSize == 0 || GetMemoryBlockSize(unalignMemory) == m_BreakAllocSize)) 162 { 163 NW_DEV_LOG("Alloc(): Specified memory block allocated\n"); 164 #if defined(NW_DEBUG_BREAK_ALLOCATOR) 165 nn::dbg::Break(nn::dbg::BREAK_REASON_USER); 166 #endif 167 } 168 } 169 #endif 170 171 return memory; 172 } 173 174 using nw::os::IAllocator::Alloc; 175 176 //! @brief メインメモリにメモリを返却します。 177 //! 178 //! @param[in] memory 返却するメモリアドレスです。 Free(void * memory)179 virtual void Free(void* memory) 180 { 181 #if defined(NW_DEBUG_TRAP_ALLOCATOR) 182 void* unalignMemory = UnAlignMemory(memory); 183 if (unalignMemory == m_BreakFreeAddress && 184 (m_BreakFreeSize == 0 || GetMemoryBlockSize(unalignMemory) == m_BreakFreeSize)) 185 { 186 NW_DEV_LOG("Free(): Specified memory block freed\n"); 187 #if defined(NW_DEBUG_BREAK_ALLOCATOR) 188 nn::dbg::Break(nn::dbg::BREAK_REASON_USER); 189 #endif 190 } 191 #endif 192 193 m_Heap.Free(memory); 194 } 195 196 //@} 197 //===================== 198 //! @name デバッグ 199 //@{ 200 201 202 203 //--------------------------------------------------------------------------- 204 //! @brief 空きメモリサイズを返します。 205 //! 206 //! @return 空きメモリサイズです。 207 //--------------------------------------------------------------------------- 208 size_t GetFreeSize(); 209 210 //--------------------------------------------------------------------------- 211 //! @brief 割り当てられたメモリサイズを返します。 212 //! 213 //! @return 割り当てられたメモリサイズです。 214 //--------------------------------------------------------------------------- 215 size_t GetTotalSize(); 216 217 //--------------------------------------------------------------------------- 218 //! @brief 確保されたメモリブロックのサイズを返します。 219 //! 220 //! @param[in] address メモリブロックの先頭アドレスを指定します。 221 //! 222 //! @return 指定されたブロックのサイズです。 223 //--------------------------------------------------------------------------- 224 size_t GetMemoryBlockSize(void* address); 225 226 227 //! @brief メインメモリの状態を表示します。 228 void Dump(); 229 230 //! @brief メモリ確保時の停止条件を設定します。 231 //! 232 //! 指定したアドレスとサイズのメモリ確保が行われるときにプログラムを強制的に一時停止するように設定します。 233 //! NW_DEBUG_TRAP_ALLOCATOR マクロと NW_DEBUG_BREAK_ALLOCATOR マクロを定義することでこの機能は有効になります。 234 //! NW_DEBUG_TRAP_ALLOCATOR マクロのみを定義した場合はメッセージ出力のみを行います。 235 //! サイズに 0 を指定するとアドレスのみを条件とします。 236 //! 237 //! アドレス、サイズともに Dump() で表示される数値(実際に確保されたアドレスとサイズ)を指定します。 238 //! 239 //! @param address ブレーク条件のアドレスです。 240 //! @param size ブレーク条件のサイズです。 SetBreakAlloc(int address,size_t size)241 void SetBreakAlloc(int address, size_t size) 242 { 243 #if defined(NW_DEBUG_TRAP_ALLOCATOR) 244 m_BreakAllocAddress = reinterpret_cast<void *>(address); 245 m_BreakAllocSize = size; 246 #else 247 NW_UNUSED_VARIABLE(address); 248 NW_UNUSED_VARIABLE(size); 249 #endif 250 } 251 252 //! @brief メモリ解放時の停止条件を設定します。 253 //! 254 //! 指定したアドレスとサイズのメモリが解放されるときにプログラムを強制的に一時停止するように設定します。 255 //! NW_DEBUG_TRAP_ALLOCATOR マクロと NW_DEBUG_BREAK_ALLOCATOR マクロを定義することでこの機能は有効になります。 256 //! NW_DEBUG_TRAP_ALLOCATOR マクロのみを定義した場合はメッセージ出力のみを行います。 257 //! サイズに 0 を指定するとアドレスのみを条件とします。 258 //! 259 //! アドレス、サイズともに Dump() で表示される数値(実際に確保されたアドレスとサイズ)を指定します。 260 //! 261 //! @param address ブレーク条件のアドレスです。 262 //! @param size ブレーク条件のサイズです。 SetBreakFree(int address,size_t size)263 void SetBreakFree(int address, size_t size) 264 { 265 #if defined(NW_DEBUG_TRAP_ALLOCATOR) 266 m_BreakFreeAddress = reinterpret_cast<void *>(address); 267 m_BreakFreeSize = size; 268 #else 269 NW_UNUSED_VARIABLE(address); 270 NW_UNUSED_VARIABLE(size); 271 #endif 272 } 273 274 //@} 275 276 277 278 private: 279 uptr m_StartAddress; 280 281 void* m_BreakAllocAddress; 282 size_t m_BreakAllocSize; 283 284 void* m_BreakFreeAddress; 285 size_t m_BreakFreeSize; 286 287 nn::fnd::ExpHeap m_Heap; 288 }; 289 290 291 //--------------------------------------------------------------------------- 292 //! @brief デモ用のフレームヒープアロケータです。 293 //! 294 //! 内部で CTR-SDK のフレームヒープを使用しています。 295 //--------------------------------------------------------------------------- 296 class FrameHeapAllocator : public nw::os::IAllocator 297 { 298 public: 299 //! @brief コンストラクタです。 FrameHeapAllocator()300 FrameHeapAllocator() 301 : m_StartAddress(0) 302 {} 303 304 //! @brief コンストラクタです。 305 //! 306 //! フレームヒープの初期化も行ないます。 307 //! 308 //! @param[in] startAddress 先頭アドレスです。 309 //! @param[in] size アロケートできるサイズです。 310 //! @param[in] option フレームヒープのオプションです。 311 //! 312 FrameHeapAllocator(uptr startAddress, size_t size, bit32 option = 0) m_StartAddress(startAddress)313 : m_StartAddress(startAddress) 314 { 315 Initialize(startAddress, size, option); 316 } 317 318 //===================== 319 //! @name 作成/破棄 320 //@{ 321 322 //! @brief デモ用のフレームヒープアロケータを初期化します。 323 //! 324 //! 内部でフレームヒープを初期化します。 325 //! 326 //! @param[in] startAddress 先頭アドレスです。 327 //! @param[in] size アロケートできるサイズです。 328 //! @param[in] option フレームヒープのオプションです。 329 //! 330 void Initialize(uptr startAddress, size_t size, bit32 option = 0); 331 332 //! @brief デモ用のフレームヒープアロケータを破棄します。 333 //! 334 void Finalize(); 335 336 //@} 337 338 //! @brief 初期化時に指定した先頭アドレスを取得します。 339 //! 340 //! @return 先頭アドレスです。 GetStartAddress()341 uptr GetStartAddress() const { return m_StartAddress; } 342 343 //===================== 344 //! @name メモリの確保と解放 345 //@{ 346 347 //! @brief フレームヒープからメモリを確保します。 348 //! 349 //! @param[in] size 確保するメモリサイズです。 350 //! @param[in] alignment アライメントです。 351 //! 352 //! @return 確保したメモリアドレスを返します。 Alloc(size_t size,u8 alignment)353 virtual void* Alloc(size_t size, u8 alignment) 354 { 355 NW_ASSERT(size != 0); 356 357 return m_FrameHeap.Allocate(size, alignment); 358 } 359 360 //! @brief IAllocator の実装としてこの関数が用意されていますが、呼び出しても何も起きません。 Free(void *)361 virtual void Free(void*) 362 { 363 // フレームヒープは全部解放しかできないため、何もしない。 364 } 365 366 //! @brief 確保されたすべてのメモリを解放します。 FreeAll()367 void FreeAll() 368 { 369 m_FrameHeap.Free(); 370 } 371 372 //@} 373 374 private: 375 uptr m_StartAddress; 376 377 nn::fnd::FrameHeap m_FrameHeap; 378 }; 379 380 381 } // namespace demo 382 } // namespace nw 383 384 /* NW_DEMO_MEMORY_H_ */ 385 #endif 386 387