2019-08-23 11:56:54 -07:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "BeefySysLib/Common.h"
|
|
|
|
#include "BeefySysLib/util/CritSect.h"
|
|
|
|
#include "BfObjects.h"
|
|
|
|
#include "ThreadLocalStorage.h"
|
|
|
|
|
|
|
|
#ifdef BF_HAS_TLS_DECLSPEC
|
|
|
|
#define BF_THREAD_TLS
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#pragma push_macro("MemoryBarrier")
|
|
|
|
#undef MemoryBarrier
|
|
|
|
|
|
|
|
class BfDbgInternalThread;
|
|
|
|
|
|
|
|
namespace bf
|
|
|
|
{
|
|
|
|
namespace System
|
|
|
|
{
|
|
|
|
namespace Threading
|
|
|
|
{
|
|
|
|
struct ThreadHandle
|
|
|
|
{
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
class Thread : public Object
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
Thread();
|
|
|
|
|
|
|
|
public:
|
|
|
|
BF_DECLARE_CLASS(Thread, Object);
|
|
|
|
|
|
|
|
#ifdef BF_THREAD_TLS
|
|
|
|
static BF_TLS_DECLSPEC Thread* sCurrentThread;
|
|
|
|
#endif
|
|
|
|
private:
|
|
|
|
BfInternalThread* SetupInternalThread();
|
|
|
|
|
|
|
|
BFRT_EXPORT void ManualThreadInit();
|
|
|
|
BFRT_EXPORT void SuspendInternal();
|
|
|
|
BFRT_EXPORT void ResumeInternal();
|
|
|
|
BFRT_EXPORT void InterruptInternal();
|
|
|
|
BFRT_EXPORT int GetPriorityNative();
|
|
|
|
BFRT_EXPORT void SetPriorityNative(int priority);
|
|
|
|
BFRT_EXPORT void SetJoinOnDelete(bool joinOnDelete);
|
|
|
|
BFRT_EXPORT bool GetIsAlive();
|
|
|
|
BFRT_EXPORT bool GetIsThreadPoolThread();
|
|
|
|
BFRT_EXPORT bool JoinInternal(int millisecondsTimeout);
|
|
|
|
BFRT_EXPORT static void SleepInternal(int millisecondsTimeout);
|
|
|
|
BFRT_EXPORT static void SpinWaitInternal(int iterations);
|
|
|
|
BFRT_EXPORT static bool YieldInternal();
|
|
|
|
BFRT_EXPORT static Thread* GetCurrentThreadNative();
|
|
|
|
BFRT_EXPORT unsigned long GetProcessDefaultStackSize();
|
|
|
|
BFRT_EXPORT void StartInternal();
|
2022-03-18 18:06:14 -07:00
|
|
|
BFRT_EXPORT void ThreadStarted();
|
2019-08-23 11:56:54 -07:00
|
|
|
BFRT_EXPORT void SetStackStart(void* ptr);
|
|
|
|
BFRT_EXPORT void InternalFinalize();
|
|
|
|
BFRT_EXPORT bool IsBackgroundNative();
|
|
|
|
BFRT_EXPORT void SetBackgroundNative(bool isBackground);
|
|
|
|
BFRT_EXPORT int GetThreadStateNative();
|
|
|
|
BFRT_EXPORT void InformThreadNameChange(String* name);
|
|
|
|
BFRT_EXPORT int GetThreadId();
|
|
|
|
|
|
|
|
BFRT_EXPORT void Dbg_CreateInternal();
|
|
|
|
|
|
|
|
public:
|
|
|
|
BFRT_EXPORT static void MemoryBarrier();
|
|
|
|
|
|
|
|
static Thread* Alloc()
|
|
|
|
{
|
2019-08-27 08:04:41 -07:00
|
|
|
return BFRTCALLBACKS.Thread_Alloc();
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
BfInternalThread* GetInternalThread()
|
|
|
|
{
|
2019-08-27 08:04:41 -07:00
|
|
|
return BFRTCALLBACKS.Thread_GetInternalThread(this);
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
BfDbgInternalThread* Dbg_GetInternalThread()
|
|
|
|
{
|
2019-08-27 08:04:41 -07:00
|
|
|
return (BfDbgInternalThread*)BFRTCALLBACKS.Thread_GetInternalThread(this);
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetInternalThread(BfInternalThread* internalThread)
|
|
|
|
{
|
2019-08-27 08:04:41 -07:00
|
|
|
BFRTCALLBACKS.Thread_SetInternalThread(this, internalThread);
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int GetMaxStackSize()
|
|
|
|
{
|
2019-08-27 08:04:41 -07:00
|
|
|
return BFRTCALLBACKS.Thread_GetMaxStackSize(this);
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} // Namespace System
|
|
|
|
}
|
|
|
|
|
|
|
|
class BfInternalThread
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool mIsSuspended;
|
|
|
|
intptr mStackStart;
|
|
|
|
bf::System::Threading::Thread* mThread;
|
|
|
|
bool mRunning;
|
|
|
|
bool mDone;
|
|
|
|
bool mStarted;
|
|
|
|
bool mJoinOnDelete;
|
2022-03-18 18:06:14 -07:00
|
|
|
bool mIsManualInit;
|
2019-08-23 11:56:54 -07:00
|
|
|
BfpThread* mThreadHandle;
|
|
|
|
intptr mThreadId;
|
|
|
|
Beefy::CritSect mCritSect;
|
2022-03-18 18:06:14 -07:00
|
|
|
Beefy::SyncEvent mStartedEvent;
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
BfInternalThread()
|
|
|
|
{
|
|
|
|
mThread = NULL;
|
|
|
|
mThreadHandle = 0;
|
|
|
|
mStarted = false;
|
|
|
|
mRunning = false;
|
|
|
|
mDone = false;
|
|
|
|
mIsSuspended = false;
|
|
|
|
mJoinOnDelete = true;
|
2022-03-18 18:06:14 -07:00
|
|
|
mIsManualInit = false;
|
2019-08-23 11:56:54 -07:00
|
|
|
mStackStart = 0;
|
|
|
|
mThreadId = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~BfInternalThread()
|
|
|
|
{
|
|
|
|
if (mThreadHandle != 0)
|
|
|
|
{
|
|
|
|
BfpThread_Release(mThreadHandle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void ManualThreadInit(bf::System::Threading::Thread* thread)
|
|
|
|
{
|
|
|
|
bf::System::Threading::Thread* newThread = thread;
|
|
|
|
|
2022-03-18 18:06:14 -07:00
|
|
|
mIsManualInit = true;
|
2019-08-23 11:56:54 -07:00
|
|
|
mStarted = true;
|
2022-03-18 18:06:14 -07:00
|
|
|
mStartedEvent.Set(true);
|
2019-08-23 11:56:54 -07:00
|
|
|
mThread = newThread;
|
|
|
|
newThread->SetInternalThread(this);
|
|
|
|
mThreadId = BfpThread_GetCurrentId();
|
|
|
|
mThreadHandle = BfpThread_GetCurrent();
|
|
|
|
mStackStart = ((intptr)&newThread + 0xFFF) & ~(intptr)0xFFF;
|
|
|
|
ThreadStarted();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void ThreadStarted()
|
2019-10-29 05:01:04 -07:00
|
|
|
{
|
2019-08-23 11:56:54 -07:00
|
|
|
mRunning = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void ThreadStopped()
|
|
|
|
{
|
|
|
|
//printf("TheadStopped\n");
|
|
|
|
mRunning = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WaitForAllDone();
|
|
|
|
};
|
|
|
|
|
|
|
|
#pragma pop_macro("MemoryBarrier")
|