1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: os_ThreadLocalStorage.cpp 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: 23600 $ 14 *---------------------------------------------------------------------------*/ 15 16 #include <nn/os/os_ThreadLocalStorage.h> 17 #include <nn/os/os_Result.h> 18 #include <nn/os/os_Private.h> 19 #include <nn/assert.h> 20 #include <nn/hw/ARM/reg_access.h> 21 //--------------------------------------------------------------------------- 22 23 using namespace nn; 24 using nn::Result; 25 26 namespace nn{ namespace os{ 27 28 namespace { 29 30 31 u16 sTLSMap = 0; // 0-15 ビットで TLS 確保状況を管理 32 33 /*! 34 @brief スロットがマッピング済みかどうかを判定します。 35 36 @return スロットがマッピング済みであれば true を返します。 37 */ IsMappedIndex(s32 index)38inline bool IsMappedIndex(s32 index) 39 { 40 return ((sTLSMap >> index) & 1) == 1; 41 } 42 43 /*! 44 @brief 空いているスレッドローカルストレージのスロットを探索します。 45 46 @return 空いているスロット番号を返します。スロットに空きがなかった場合は -1 を返します。 47 */ SearchFreeTLSIndex()48s32 SearchFreeTLSIndex() 49 { 50 51 for(int i = 0; i < TLS_NUM; ++i) 52 { 53 if(!IsMappedIndex(i)) 54 { 55 return i; 56 } 57 } 58 return -1; 59 } 60 61 /*! 62 @brief スレッドローカルストレージからスロットを確保します。 63 64 @return 確保したスロット番号を返します。スロットに空きがなかった場合は -1 を返します。 65 */ AllocateTLSIndex()66s32 AllocateTLSIndex() 67 { 68 s32 index = SearchFreeTLSIndex(); 69 if(index >= 0 && index < TLS_NUM) 70 { 71 sTLSMap |= (1 << index); 72 } 73 return index; 74 } 75 76 /*! 77 @brief スレッドローカルストレージにスロットを解放します。 78 79 @param[in] スロット番号 80 */ FreeTLSIndex(int index)81s32 FreeTLSIndex(int index) 82 { 83 if(!IsMappedIndex(index)) 84 { 85 return -1; 86 } 87 return sTLSMap &= ~(1 << index); 88 } 89 90 91 } // namespace 92 ThreadLocalStorage()93ThreadLocalStorage::ThreadLocalStorage() 94 { 95 this->m_Index = AllocateTLSIndex(); 96 NN_TASSERTMSG_(m_Index >= 0, "Out of Thread Local Storage Slot."); 97 } 98 ~ThreadLocalStorage()99ThreadLocalStorage::~ThreadLocalStorage() 100 { 101 NN_TASSERT_(m_Index >= 0 && m_Index < TLS_NUM); 102 NN_TASSERT_(IsMappedIndex(m_Index)); 103 FreeTLSIndex(m_Index); 104 } 105 GetValue() const106uptr ThreadLocalStorage::GetValue() const 107 { 108 NN_TASSERT_(m_Index >= 0 && m_Index < TLS_NUM); 109 NN_TASSERT_(IsMappedIndex(m_Index)); 110 return GetThreadLocalRegion()->tls[m_Index]; 111 } 112 SetValue(uptr value)113void ThreadLocalStorage::SetValue(uptr value) 114 { 115 NN_TASSERT_(m_Index >= 0 && m_Index < TLS_NUM); 116 NN_TASSERT_(IsMappedIndex(m_Index)); 117 GetThreadLocalRegion()->tls[m_Index] = value; 118 } 119 ClearAllSlots()120void ThreadLocalStorage::ClearAllSlots() 121 { 122 ThreadLocalRegion& tlr = *GetThreadLocalRegion(); 123 124 for( int i = 0; i < TLS_NUM; ++i ) 125 { 126 tlr.tls[i] = 0; 127 } 128 } 129 130 }} // namespace nn::os 131 132