first commit
This commit is contained in:
237
Minecraft.Client/PSVita/PSVitaExtras/PSVitaTLSStorage.cpp
Normal file
237
Minecraft.Client/PSVita/PSVitaExtras/PSVitaTLSStorage.cpp
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user