forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			201 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			201 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#ifdef HX_TLS_H_OVERRIDE
							 | 
						||
| 
								 | 
							
								// Users can define their own header to use here, but there is no API
							 | 
						||
| 
								 | 
							
								// compatibility gaurantee for future changes.
							 | 
						||
| 
								 | 
							
								#include HX_TLS_H_OVERRIDE
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef HX_TLS_INCLUDED
							 | 
						||
| 
								 | 
							
								#define HX_TLS_INCLUDED
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(HX_WINDOWS) || defined(KORE_CONSOLE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  #if defined(HX_WINRT)
							 | 
						||
| 
								 | 
							
								    // Nothing
							 | 
						||
| 
								 | 
							
								  #elif defined(KORE_CONSOLE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <kinc/threads/threadlocal.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace hx {
							 | 
						||
| 
								 | 
							
									template<typename DATA, bool FAST = false> struct TLSData {
							 | 
						||
| 
								 | 
							
										TLSData() {
							 | 
						||
| 
								 | 
							
											kinc_thread_local_init(&tls);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										~TLSData() {
							 | 
						||
| 
								 | 
							
											kinc_thread_local_destroy(&tls);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										DATA *Get() {
							 | 
						||
| 
								 | 
							
											return (DATA*)kinc_thread_local_get(&tls);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										void Set(DATA *inData) {
							 | 
						||
| 
								 | 
							
											kinc_thread_local_set(&tls, inData);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										inline DATA *operator=(DATA *inData) {
							 | 
						||
| 
								 | 
							
											kinc_thread_local_set(&tls, inData);
							 | 
						||
| 
								 | 
							
											return inData;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										inline operator DATA*() {
							 | 
						||
| 
								 | 
							
											return (DATA*)kinc_thread_local_get(&tls);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									private:
							 | 
						||
| 
								 | 
							
										kinc_thread_local_t tls;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  #else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #if ! defined(__GNUC__) && !defined(__BORLANDC__)
							 | 
						||
| 
								 | 
							
								   #include <intrin.h>
							 | 
						||
| 
								 | 
							
								   #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   extern "C"
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      __declspec(dllimport)
							 | 
						||
| 
								 | 
							
								     int __stdcall TlsSetValue(unsigned long  dwTlsIndex, void *lpTlsValue);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								     __declspec(dllimport)
							 | 
						||
| 
								 | 
							
								     void * __stdcall TlsGetValue(unsigned long  dwTlsIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								     __declspec(dllimport)
							 | 
						||
| 
								 | 
							
								     unsigned long __stdcall TlsAlloc(void);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   namespace hx {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template<typename DATA,bool FAST=false>
							 | 
						||
| 
								 | 
							
								   struct TLSData
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      static const size_t kMaxInlineSlots = 64;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      TLSData()
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         mSlot = TlsAlloc();
							 | 
						||
| 
								 | 
							
								         TlsSetValue(mSlot,0);
							 | 
						||
| 
								 | 
							
								         #ifdef HXCPP_M64
							 | 
						||
| 
								 | 
							
								         mFastOffset = mSlot*sizeof(void *) + 0x1480;
							 | 
						||
| 
								 | 
							
								         #else
							 | 
						||
| 
								 | 
							
								         if (FAST || mSlot < kMaxInlineSlots)
							 | 
						||
| 
								 | 
							
								            mFastOffset = mSlot*sizeof(void *) + 0xE10;
							 | 
						||
| 
								 | 
							
								         else
							 | 
						||
| 
								 | 
							
								            mFastOffset = mSlot - kMaxInlineSlots;
							 | 
						||
| 
								 | 
							
								         #endif
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      inline DATA *operator=(DATA *inData)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         TlsSetValue(mSlot,inData);
							 | 
						||
| 
								 | 
							
								         return inData;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      inline operator DATA *()
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         #if !defined(HXCPP_M64) && (_MSC_VER >= 1400)
							 | 
						||
| 
								 | 
							
								         const size_t kTibExtraTlsOffset = 0xF94;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         if (FAST || mSlot < kMaxInlineSlots)
							 | 
						||
| 
								 | 
							
								           return (DATA *)__readfsdword(mFastOffset);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         DATA **extra = (DATA **)(__readfsdword(kTibExtraTlsOffset));
							 | 
						||
| 
								 | 
							
								         return extra[mFastOffset];
							 | 
						||
| 
								 | 
							
								         #elif (_MSC_VER >= 1400) & !defined(HXCPP_DEBUG) && !defined(HXCPP_ARM64)// 64 bit version...
							 | 
						||
| 
								 | 
							
								         if (mSlot < 64)
							 | 
						||
| 
								 | 
							
								           return (DATA *)__readgsqword(mFastOffset);
							 | 
						||
| 
								 | 
							
								         else
							 | 
						||
| 
								 | 
							
								           return (DATA *)TlsGetValue(mSlot);
							 | 
						||
| 
								 | 
							
								         #else
							 | 
						||
| 
								 | 
							
								         return (DATA *)TlsGetValue(mSlot);
							 | 
						||
| 
								 | 
							
								         #endif
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      int mSlot;
							 | 
						||
| 
								 | 
							
								      int mFastOffset;
							 | 
						||
| 
								 | 
							
								   };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   } // end namespace hx
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   #define DECLARE_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								      hx::TLSData<TYPE> NAME;
							 | 
						||
| 
								 | 
							
								   #define DECLARE_FAST_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								      hx::TLSData<TYPE,true> NAME;
							 | 
						||
| 
								 | 
							
								   #define EXTERN_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								      extern hx::TLSData<TYPE> NAME;
							 | 
						||
| 
								 | 
							
								   #define EXTERN_FAST_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								      extern hx::TLSData<TYPE,true> NAME;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  #endif
							 | 
						||
| 
								 | 
							
								#else // not HX_WINDOWS
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <pthread.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace hx
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename DATA,bool FAST=false>
							 | 
						||
| 
								 | 
							
								struct TLSData
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   TLSData()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      pthread_key_create(&mSlot, 0);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   DATA *Get()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      return (DATA *)pthread_getspecific(mSlot);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   void Set(DATA *inData)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      pthread_setspecific(mSlot,inData);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   inline DATA *operator=(DATA *inData)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      pthread_setspecific(mSlot,inData);
							 | 
						||
| 
								 | 
							
								      return inData;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   inline operator DATA *() { return (DATA *)pthread_getspecific(mSlot); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   pthread_key_t mSlot;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // end namespace hx
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef HX_WINRT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define DECLARE_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								   __declspec(thread) TYPE * NAME = nullptr;
							 | 
						||
| 
								 | 
							
								#define DECLARE_FAST_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								   __declspec(thread) TYPE * NAME = nullptr;
							 | 
						||
| 
								 | 
							
								#define EXTERN_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								   __declspec(thread) extern TYPE * NAME;
							 | 
						||
| 
								 | 
							
								#define EXTERN_FAST_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								   __declspec(thread) extern TYPE * NAME;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define DECLARE_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								   hx::TLSData<TYPE> NAME;
							 | 
						||
| 
								 | 
							
								#define DECLARE_FAST_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								   hx::TLSData<TYPE,true> NAME;
							 | 
						||
| 
								 | 
							
								#define EXTERN_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								   extern hx::TLSData<TYPE> NAME;
							 | 
						||
| 
								 | 
							
								#define EXTERN_FAST_TLS_DATA(TYPE,NAME) \
							 | 
						||
| 
								 | 
							
								   extern hx::TLSData<TYPE,true> NAME;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |