201 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#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
 |