#ifndef MRT_THREAD_LOCAL_H
#define MRT_THREAD_LOCAL_H
#include <cstdint>
#include "Base/RwLock.h"
namespace MapleRuntime {
class AllocBuffer;
class Mutator;
enum class ThreadType { CJ_PROCESSOR = 0, GC_THREAD, FP_THREAD, HOT_UPDATE_THREAD };
struct ThreadLocalData {
AllocBuffer* buffer;
Mutator* mutator;
uint8_t* cjthread;
uint8_t* schedule;
uint8_t* preemptFlag;
uint8_t* protectAddr;
uint64_t safepointState;
uint64_t tid;
void* foreignCJThread;
ThreadType threadType;
bool isCJProcessor;
void* threadCache;
};
struct CleanThreadLocalData {
CleanThreadLocalData() noexcept;
~CleanThreadLocalData();
};
class ThreadLocal {
public:
static ThreadLocalData* GetThreadLocalData();
static void InitializeCleaner();
static void SetMutator(Mutator* newMutator) { GetThreadLocalData()->mutator = newMutator; }
static Mutator* GetMutator() { return GetThreadLocalData()->mutator; }
static AllocBuffer* GetAllocBuffer() { return GetThreadLocalData()->buffer; }
static void SetAllocBuffer(AllocBuffer* buffer) { GetThreadLocalData()->buffer = buffer; }
static uint8_t* GetPreemptFlag() { return GetThreadLocalData()->preemptFlag; }
static void SetProtectAddr(uint8_t* addr) { GetThreadLocalData()->protectAddr = addr; }
static void SetThreadType(ThreadType type) { GetThreadLocalData()->threadType = type; }
static ThreadType GetThreadType() { return GetThreadLocalData()->threadType; }
static void SetCJProcessorFlag(bool flag) { GetThreadLocalData()->isCJProcessor = flag; }
static bool IsCJProcessor() { return GetThreadLocalData()->isCJProcessor; }
static void SetForeignCJThread(void* cjthread)
{
GetThreadLocalData()->foreignCJThread = cjthread;
}
static void* GetForeignCJThread()
{
return GetThreadLocalData()->foreignCJThread;
}
static void SetCJThread(void* cjthread)
{
GetThreadLocalData()->cjthread = reinterpret_cast<uint8_t*>(cjthread);
}
static void* GetSchedule()
{
return GetThreadLocalData()->schedule;
}
static void SetSchedule(void* schedule)
{
GetThreadLocalData()->schedule = reinterpret_cast<uint8_t*>(schedule);
}
static void* GetThreadCache()
{
return GetThreadLocalData()->threadCache;
}
static void* SetThreadCache(void* threadCache)
{
return GetThreadLocalData()->threadCache = threadCache;
}
static void ThreadLocalFini()
{
tlEnableLock.LockWrite();
}
static bool TryGetRdLock()
{
return tlEnableLock.TryLockRead();
}
static void UnlockRdLock()
{
tlEnableLock.UnlockRead();
}
private:
static RwLock tlEnableLock;
};
}
#endif