diff options
| author | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
|---|---|---|
| committer | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
| commit | b691c43c44ff180d10e7d4a9afc83b98551ff586 (patch) | |
| tree | 3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/PSVita/PSVitaExtras/PSVitaTLSStorage.cpp | |
| parent | def8cb415354ac390b7e89052a50605285f1aca9 (diff) | |
Initial commit
Diffstat (limited to 'Minecraft.Client/PSVita/PSVitaExtras/PSVitaTLSStorage.cpp')
| -rw-r--r-- | Minecraft.Client/PSVita/PSVitaExtras/PSVitaTLSStorage.cpp | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/Minecraft.Client/PSVita/PSVitaExtras/PSVitaTLSStorage.cpp b/Minecraft.Client/PSVita/PSVitaExtras/PSVitaTLSStorage.cpp new file mode 100644 index 00000000..0261f318 --- /dev/null +++ b/Minecraft.Client/PSVita/PSVitaExtras/PSVitaTLSStorage.cpp @@ -0,0 +1,237 @@ +#include "stdafx.h" +#include "PSVitaTLSStorage.h" + +#if 1 +static PSVitaTLSStorage Singleton; + +#define MAX_THREADS 64 + +typedef struct +{ + int ThreadID; + LPVOID Value; +} TLSInfo; + +typedef struct +{ + TLSInfo *Array; + int Size; +} TLSArray; + +static std::vector<TLSArray *> PSVitaTLSStorage_ActiveInfos; + +void PSVitaTLSStorage::Init() +{ +} + +PSVitaTLSStorage *PSVitaTLSStorage::Instance() +{ + return &Singleton; +} + +DWORD PSVitaTLSStorage::Alloc() +{ + TLSArray* Array = new TLSArray; + Array->Array = new TLSInfo[MAX_THREADS]; + Array->Size = 0; + for( int i = 0;i < MAX_THREADS;i += 1 ) + { + Array->Array[i].ThreadID = -1; + } + + // add to the active infos + PSVitaTLSStorage_ActiveInfos.push_back(Array); + return (DWORD) Array; +} + +BOOL PSVitaTLSStorage::Free(DWORD dwTlsIndex) +{ + // remove from the active infos + std::vector<TLSArray *>::iterator iter = std::find(PSVitaTLSStorage_ActiveInfos.begin(), PSVitaTLSStorage_ActiveInfos.end(), (TLSArray *) dwTlsIndex); + PSVitaTLSStorage_ActiveInfos.erase(iter); + + delete []((TLSInfo*)dwTlsIndex); + return 0; +} + +void PSVitaTLSStorage::RemoveThread(int threadID) +{ + // remove this thread from all the active Infos + std::vector<TLSArray *>::iterator iter = PSVitaTLSStorage_ActiveInfos.begin(); + for( ; iter != PSVitaTLSStorage_ActiveInfos.end(); ++iter ) + { + TLSArray* Array = ((TLSArray*)*iter); + + for( int i = 0;i < Array->Size;i += 1 ) + { + if( Array->Array[i].ThreadID == threadID ) + { + // shift all the other entries down + for( ;i < MAX_THREADS - 1;i += 1 ) + { + Array->Array[i].ThreadID = Array->Array[i+1].ThreadID; + Array->Array[i].Value = Array->Array[i+1].Value; + if( Array->Array[i].ThreadID != -1 ) + { + Array->Size = i + 1; + } + } + // mark the top one as unused + Array->Array[i].ThreadID = -1; + break; + } + } + } +} + +LPVOID PSVitaTLSStorage::GetValue(DWORD dwTlsIndex) +{ + if( !dwTlsIndex ) + { + return 0; + } + + TLSArray* Array = ((TLSArray*)dwTlsIndex); + SceUID threadID = sceKernelGetThreadId(); + for( int i = 0;i < Array->Size;i += 1 ) + { + if( Array->Array[i].ThreadID == threadID ) + { + return Array->Array[i].Value; + } + } + + //assert(0); + return 0; +} + +BOOL PSVitaTLSStorage::SetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) +{ + if( !dwTlsIndex ) + { + return 0; + } + + TLSArray* Array = ((TLSArray*)dwTlsIndex); + SceUID threadID = sceKernelGetThreadId(); + for( int i = 0;i < Array->Size;i += 1 ) + { + if( Array->Array[i].ThreadID == threadID || Array->Array[i].ThreadID == -1 ) + { + Array->Array[i].ThreadID = threadID; + Array->Array[i].Value = lpTlsValue; + return 0; + } + } + if( Array->Size < MAX_THREADS ) + { + Array->Array[Array->Size].ThreadID = threadID; + Array->Array[Array->Size].Value = lpTlsValue; + Array->Size++; + return 0; + } + + assert(0); + return 0; +} +#else + + +PSVitaTLSStorage* m_pInstance = NULL; + +#define sc_maxSlots 64 +BOOL m_activeList[sc_maxSlots]; +//__thread void* m_values[64]; + +// AP - Oh my. It seems __thread doesn't like cpp files. I couldn't get it to be thread sensitive as it would always return a shared value. +// For now I've stuck m_values and accessor functions into user_malloc.c. Cheap cheap hack. +extern "C" +{ +void user_setValue( unsigned int _index, void* _val ); +void* user_getValue( unsigned int _index ); +} + + +void PSVitaTLSStorage::Init() +{ + for(int i=0;i<sc_maxSlots; i++) + { + m_activeList[i] = false; +// m_values[i] = NULL; + } +} + +PSVitaTLSStorage* PSVitaTLSStorage::Instance() +{ + if ( m_pInstance == 0 ) // Is this the first time? + { + m_pInstance = new PSVitaTLSStorage; // Create the singleton instance. + m_pInstance->Init(); + } + return m_pInstance; +} + + +DWORD PSVitaTLSStorage::Alloc() +{ + for(int i=0; i<sc_maxSlots; i++) + { + if(m_activeList[i] == false) + { + m_activeList[i] = true; +// m_values[i] = NULL; + return i; + } + } + assert(0); // we've ran out of slots + return -1; +} + +BOOL PSVitaTLSStorage::Free( DWORD _index ) +{ + if(m_activeList[_index] == false) + return false; // not been allocated + + m_activeList[_index] = false; +// m_values[_index] = NULL; + return true; +} + +BOOL PSVitaTLSStorage::SetValue( DWORD _index, LPVOID _val ) +{ + if(m_activeList[_index] == false) + return false; + user_setValue(_index, _val); +// m_values[_index] = _val; + return true; +} + +LPVOID PSVitaTLSStorage::GetValue( DWORD _index ) +{ + if(m_activeList[_index] == false) + return NULL; + return user_getValue(_index); +// return m_values[_index]; +} + +void PSVitaTLSStorage::RemoveThread(int threadID) +{ + for(int i=0; i<sc_maxSlots; i++) + { + //m_values[i] = NULL; + user_setValue(i, NULL); + } +} + +// AP - Oh my. It seems __thread doesn't like cpp files. I couldn't get it to be thread sensitive as it would always return a shared value. +// For now I've stuck m_values and accessor functions into user_malloc.c. Cheap cheap hack. +__thread void* m_values[64]; +void user_setValue( unsigned int _index, void* _val ) +{ + m_values[_index] = _val; +} +void* user_getValue( unsigned int _index ) +{ + return m_values[_index]; +} +#endif
\ No newline at end of file |
