1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: os_SimpleAutoStackManagerBase.cpp 4 5 Copyright (C)2009-2012 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:$ 14 *---------------------------------------------------------------------------*/ 15 16 #include <nn/config.h> 17 #if NN_PLATFORM_HAS_MMU 18 19 #include <nn/os.h> 20 #include <nn/fnd.h> 21 #include <nn/math.h> 22 23 namespace nn { namespace os { 24 25 namespace 26 { 27 struct DataOnStack 28 { 29 void* pHead; 30 }; 31 } 32 ~SimpleAutoStackManagerBase()33 SimpleAutoStackManagerBase::~SimpleAutoStackManagerBase() 34 { 35 Finalize(); 36 } 37 Initialize(fnd::IAllocator * pAllocator,uptr stackBottom)38 void SimpleAutoStackManagerBase::Initialize(fnd::IAllocator* pAllocator, uptr stackBottom) 39 { 40 NN_TASSERT_( ! IsInitialized()); 41 NN_POINTER_TASSERT_(pAllocator); 42 43 m_pAllocator = pAllocator; 44 m_DestructorStackBottom = stackBottom; 45 m_DestructorMutex.Initialize(); 46 } 47 Finalize()48 uptr SimpleAutoStackManagerBase::Finalize() 49 { 50 uptr stackBottom = m_DestructorStackBottom; 51 52 if( IsInitialized() ) 53 { 54 m_DestructorStackBottom = NULL; 55 m_DestructorMutex.Finalize(); 56 } 57 58 return stackBottom; 59 } 60 61 DestructImpl(void * pStackBottom,uptr returnAddress,bool isError)62 void SimpleAutoStackManagerBase::DestructImpl(void* pStackBottom, uptr returnAddress, bool isError) 63 { 64 NN_TASSERT_(IsInitialized()); 65 66 if( isError ) 67 { 68 FreeStack(pStackBottom); 69 } 70 else 71 { 72 // Lock so that multiple threads do not simultaneously execute a process that clears the stack. 73 m_DestructorMutex.Lock(); 74 75 // Destroy the thread stack 76 CallFreeStackOnOtherStack( 77 pStackBottom, 78 math::RoundDown(m_DestructorStackBottom, 8), 79 returnAddress ); 80 } 81 } 82 CallFreeStackOnOtherStack(void * pStackBottom NN_IS_UNUSED_VAR,uptr stackBottom NN_IS_UNUSED_VAR,uptr returnAddress NN_IS_UNUSED_VAR)83 asm void SimpleAutoStackManagerBase::CallFreeStackOnOtherStack( 84 void* pStackBottom NN_IS_UNUSED_VAR, 85 uptr stackBottom NN_IS_UNUSED_VAR, 86 uptr returnAddress NN_IS_UNUSED_VAR ) 87 { 88 ARM 89 PRESERVE8 90 91 // r0: this 92 // r1: pStackBottom 93 // r2: stackBottom 94 // r3: returnAddress 95 96 mov sp, r2 97 mov lr, r3 98 99 ldr r2, [r0] 100 ldr r2, [r2, #__vcall_offsetof_vfunc(SimpleAutoStackManagerBase, FreeStack)] 101 102 // r0: this 103 // r1: pStackBottom 104 // r2: FreeStack 105 // lr: returnAddr 106 107 bx r2 108 } 109 110 111 }} // namespace nn::os 112 113 #endif // if NN_PLATFORM_HAS_MMU 114