[*] Refactor IAuroraThread
This commit is contained in:
parent
5ab97be4e3
commit
e4fa5d549e
@ -37,26 +37,62 @@ namespace Aurora::Threading::Threads
|
|||||||
///
|
///
|
||||||
struct IAuroraThread
|
struct IAuroraThread
|
||||||
{
|
{
|
||||||
virtual bool Run() = 0;
|
virtual bool Run() = 0;
|
||||||
virtual void Exit() = 0;
|
|
||||||
virtual bool Exiting() = 0;
|
/**
|
||||||
virtual void SendExitSignal() = 0;
|
* @brief Forcefully terminates the thread from within the threads context or externally
|
||||||
|
* In the event another thread requests termination, the thread has until (SetNoUnwindTerminateExitWatchDogTimeoutInMS)
|
||||||
|
* to terminate before the context is forcefully destroyed, and the RAII objects are forever leaked.
|
||||||
|
* At this point it is up to the application to start recycling memory heaps.
|
||||||
|
*/
|
||||||
|
virtual void Terminate() = 0;
|
||||||
|
|
||||||
virtual void UnsafeForceTerminateSignal() = 0;
|
/**
|
||||||
|
* @brief Terminate's force kill path with even less niceness and less waiting around by the caller
|
||||||
|
*/
|
||||||
|
virtual void UnsafeForceTerminateSignal() = 0;
|
||||||
|
|
||||||
virtual void SetPriority(EThreadPriority prio) = 0;
|
/**
|
||||||
virtual void SetThrottle(EThreadThrottle throttle) = 0;
|
* @brief Dispatches the shutdown signals (the IO objects, not in the POSIX or NT DPC sense, more APC-like)
|
||||||
virtual void SetAffinity(const HWInfo::CpuBitId &mask) = 0;
|
*/
|
||||||
virtual void SetName(const AuString &name) = 0;
|
virtual void SendExitSignal() = 0;
|
||||||
virtual void SetNameIdentity(AuUInt32 uNameIdentity) = 0;
|
|
||||||
|
|
||||||
virtual EThreadPriority GetPriority() = 0;
|
virtual bool Exiting() = 0;
|
||||||
virtual EThreadThrottle GetThrottle() = 0;
|
|
||||||
virtual HWInfo::CpuBitId GetMask() = 0;
|
|
||||||
virtual AuString GetName() = 0;
|
|
||||||
virtual AuUInt32 GetNameIdentity() = 0;
|
|
||||||
|
|
||||||
virtual AuUInt64 GetThreadCreationTime(Time::EClock eClock) = 0;
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param eClock EClock::eWall, EClock::eSteady, or EClock::eProcessTime
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual AuUInt64 GetThreadCreationTime(Time::EClock eClock) = 0;
|
||||||
|
|
||||||
|
virtual void SetPriority(EThreadPriority prio) = 0;
|
||||||
|
virtual EThreadPriority GetPriority() = 0;
|
||||||
|
|
||||||
|
virtual void SetThrottle(EThreadThrottle throttle) = 0;
|
||||||
|
virtual EThreadThrottle GetThrottle() = 0;
|
||||||
|
|
||||||
|
virtual void SetAffinityMask(const HWInfo::CpuBitId &mask) = 0;
|
||||||
|
virtual HWInfo::CpuBitId GetAffinityMask() = 0;
|
||||||
|
|
||||||
|
virtual void SetName(const AuString &name) = 0;
|
||||||
|
virtual AuString GetName() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Optional:
|
||||||
|
*/
|
||||||
|
virtual void SetNameIdentity(AuUInt32 uNameIdentity) = 0;
|
||||||
|
/**
|
||||||
|
* @brief returns SetNameIdentity or a hash for SetName.
|
||||||
|
Ship processes with anti-debug may not wish to provide users a hint towards which thread does what with English strings.
|
||||||
|
Deterministic thread identities are still useful for debugging and telemetry.
|
||||||
|
*/
|
||||||
|
virtual AuUInt32 GetNameIdentity() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defer to ::Terminate()
|
||||||
|
*/
|
||||||
|
virtual AuUInt64 SetNoUnwindTerminateExitWatchDogTimeoutInMS(AuUInt64 uMS) = 0;
|
||||||
|
|
||||||
// TODO: will deprecate with a version that does call init on thread and deinit on deinit
|
// TODO: will deprecate with a version that does call init on thread and deinit on deinit
|
||||||
/// Registers a thread feature _not_ calling on init [for now]
|
/// Registers a thread feature _not_ calling on init [for now]
|
||||||
@ -64,18 +100,37 @@ namespace Aurora::Threading::Threads
|
|||||||
/// Use this to register teardown functions
|
/// Use this to register teardown functions
|
||||||
virtual void AddLastHopeTlsHook(const AuSPtr<Threading::Threads::IThreadFeature> &feature) = 0;
|
virtual void AddLastHopeTlsHook(const AuSPtr<Threading::Threads::IThreadFeature> &feature) = 0;
|
||||||
|
|
||||||
virtual AuUInt64 SetNoUnwindTerminateExitWatchDogTimeoutInMS(AuUInt64 uMS) = 0;
|
/**
|
||||||
|
* @brief Read only signal.
|
||||||
|
*/
|
||||||
|
virtual AuSPtr<IWaitable> GetShutdownWaitable() = 0;
|
||||||
|
|
||||||
virtual AuSPtr<IWaitable> AsWaitable() = 0;
|
/**
|
||||||
virtual AuSPtr<IO::Loop::ILoopSource> AsLoopSource() = 0;
|
* @brief Read only signal.
|
||||||
|
*/
|
||||||
|
virtual AuSPtr<IO::Loop::ILoopSource> GetShutdownLoopSource() = 0;
|
||||||
|
|
||||||
virtual AuSPtr<IWaitable> GetShutdownSignalWaitable() = 0;
|
/**
|
||||||
virtual AuSPtr<IO::Loop::ILoopSource> GetShutdownSignalLS() = 0;
|
* @brief Read only signal.
|
||||||
|
*/
|
||||||
|
virtual AuSPtr<IWaitable> GetShutdownSignalWaitable() = 0;
|
||||||
|
|
||||||
virtual void Detach() = 0;
|
/**
|
||||||
|
* @brief Read only signal.
|
||||||
|
*/
|
||||||
|
virtual AuSPtr<IO::Loop::ILoopSource> GetShutdownSignalLoopSource() = 0;
|
||||||
|
|
||||||
virtual void ExecuteInDeadThread(AuFunction<void()> callback) = 0;
|
/**
|
||||||
|
* @brief Do not force ::Terminate-like shutdown on release.
|
||||||
|
*/
|
||||||
|
virtual void Detach() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Impersonation for AuThreads::TLSVariable<T> access.
|
||||||
|
* Useful for shutting down thread local subsystems with c-like C++.
|
||||||
|
*/
|
||||||
|
virtual void ExecuteInDeadThread(AuFunction<void()> callback) = 0;
|
||||||
|
|
||||||
AURT_ADD_USR_DATA;
|
AURT_ADD_USR_DATA;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -667,7 +667,7 @@ namespace Aurora::Async
|
|||||||
{
|
{
|
||||||
if (thread.get() != pSelf)
|
if (thread.get() != pSelf)
|
||||||
{
|
{
|
||||||
thread->Exit();
|
thread->Terminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ namespace Aurora::Processes
|
|||||||
AuSPtr<Threading::IWaitable> ProcessImpl::AsWaitable()
|
AuSPtr<Threading::IWaitable> ProcessImpl::AsWaitable()
|
||||||
{
|
{
|
||||||
if (!this->thread_) return nullptr;
|
if (!this->thread_) return nullptr;
|
||||||
return this->thread_->AsWaitable();
|
return this->thread_->GetShutdownWaitable();
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<AuLoop::ILoopSource> ProcessImpl::AsLoopSource()
|
AuSPtr<AuLoop::ILoopSource> ProcessImpl::AsLoopSource()
|
||||||
|
@ -166,7 +166,7 @@ namespace Aurora::Threading::Threads
|
|||||||
{
|
{
|
||||||
if (gRuntimeRunLevel <= 3)
|
if (gRuntimeRunLevel <= 3)
|
||||||
{
|
{
|
||||||
Exit();
|
Terminate();
|
||||||
}
|
}
|
||||||
else if (gRuntimeRunLevel >= 5)
|
else if (gRuntimeRunLevel >= 5)
|
||||||
{
|
{
|
||||||
@ -278,7 +278,7 @@ namespace Aurora::Threading::Threads
|
|||||||
this->detached_ = true;
|
this->detached_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<IWaitable> OSThread::AsWaitable()
|
AuSPtr<IWaitable> OSThread::GetShutdownWaitable()
|
||||||
{
|
{
|
||||||
if (!this->terminated_)
|
if (!this->terminated_)
|
||||||
{
|
{
|
||||||
@ -302,11 +302,6 @@ namespace Aurora::Threading::Threads
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSThread::UnsafeForceTerminateSignal()
|
|
||||||
{
|
|
||||||
TeminateOSContext(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OSThread::Run()
|
bool OSThread::Run()
|
||||||
{
|
{
|
||||||
AU_DEBUG_MEMCRUNCH;
|
AU_DEBUG_MEMCRUNCH;
|
||||||
@ -341,7 +336,7 @@ namespace Aurora::Threading::Threads
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSThread::Exit()
|
void OSThread::Terminate()
|
||||||
{
|
{
|
||||||
this->PrivateUserDataClear();
|
this->PrivateUserDataClear();
|
||||||
|
|
||||||
@ -351,6 +346,11 @@ namespace Aurora::Threading::Threads
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OSThread::UnsafeForceTerminateSignal()
|
||||||
|
{
|
||||||
|
TeminateOSContext(false);
|
||||||
|
}
|
||||||
|
|
||||||
bool OSThread::Exit(bool willReturnToOS, bool isEOL)
|
bool OSThread::Exit(bool willReturnToOS, bool isEOL)
|
||||||
{
|
{
|
||||||
if (GetThread() == this)
|
if (GetThread() == this)
|
||||||
@ -442,7 +442,7 @@ namespace Aurora::Threading::Threads
|
|||||||
return this->prio_;
|
return this->prio_;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuHwInfo::CpuBitId OSThread::GetMask()
|
AuHwInfo::CpuBitId OSThread::GetAffinityMask()
|
||||||
{
|
{
|
||||||
return this->mask_;
|
return this->mask_;
|
||||||
}
|
}
|
||||||
@ -457,7 +457,7 @@ namespace Aurora::Threading::Threads
|
|||||||
return this->uNameIdentity_;
|
return this->uNameIdentity_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSThread::SetAffinity(const HWInfo::CpuBitId &mask)
|
void OSThread::SetAffinityMask(const HWInfo::CpuBitId &mask)
|
||||||
{
|
{
|
||||||
auto zero = HWInfo::CpuBitId();
|
auto zero = HWInfo::CpuBitId();
|
||||||
|
|
||||||
@ -556,10 +556,11 @@ namespace Aurora::Threading::Threads
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* We have a lot of code that will specify an efficiency throttle and then
|
* We have a lot of code that will specify an efficiency throttle and then
|
||||||
* arbitrarily use prio levels to (hopefully) order work in the os scheduler.
|
* arbitrarily use prio levels to (hopefully) order work in the os scheduler.
|
||||||
* Systems without ecores would see a higher prio work than normal tasks if
|
* Systems without ecores would see a higher prio thread than normal tasks, if
|
||||||
* we do nothing about this. On systems without ecores, efficiency throttle
|
* we do nothing about this condition. On systems without ecores, the efficiency
|
||||||
* will just lock the prio to low.
|
* throttle should just lock the prio to low, instead of attempting to use prio
|
||||||
|
* as a localized ecore scheduler hint.
|
||||||
*/
|
*/
|
||||||
prio = EThreadPriority::ePrioLow;
|
prio = EThreadPriority::ePrioLow;
|
||||||
|
|
||||||
@ -879,7 +880,7 @@ namespace Aurora::Threading::Threads
|
|||||||
}
|
}
|
||||||
|
|
||||||
UpdatePrio(this->throttle_, this->prio_);
|
UpdatePrio(this->throttle_, this->prio_);
|
||||||
SetAffinity(this->mask_);
|
SetAffinityMask(this->mask_);
|
||||||
AffinityPrioThrottleTickAmendECores();
|
AffinityPrioThrottleTickAmendECores();
|
||||||
UpdateName();
|
UpdateName();
|
||||||
}
|
}
|
||||||
@ -1510,7 +1511,7 @@ namespace Aurora::Threading::Threads
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<AuLoop::ILoopSource> OSThread::AsLoopSource()
|
AuSPtr<AuLoop::ILoopSource> OSThread::GetShutdownLoopSource()
|
||||||
{
|
{
|
||||||
if (!this->terminatedSignalLs_)
|
if (!this->terminatedSignalLs_)
|
||||||
{
|
{
|
||||||
@ -1524,7 +1525,7 @@ namespace Aurora::Threading::Threads
|
|||||||
return this->terminateSignal_;
|
return this->terminateSignal_;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<AuLoop::ILoopSource> OSThread::GetShutdownSignalLS()
|
AuSPtr<AuLoop::ILoopSource> OSThread::GetShutdownSignalLoopSource()
|
||||||
{
|
{
|
||||||
return this->terminateSignalLs_;
|
return this->terminateSignalLs_;
|
||||||
}
|
}
|
||||||
|
@ -20,27 +20,26 @@ namespace Aurora::Threading::Threads
|
|||||||
OSThread(AuUInt64);
|
OSThread(AuUInt64);
|
||||||
~OSThread();
|
~OSThread();
|
||||||
|
|
||||||
bool Run() override;
|
bool Run() override;
|
||||||
void Exit() override;
|
void Terminate() override;
|
||||||
bool Exiting() override;
|
void UnsafeForceTerminateSignal() override;
|
||||||
void SendExitSignal() override;
|
bool Exiting() override;
|
||||||
|
void SendExitSignal() override;
|
||||||
|
|
||||||
void UnsafeForceTerminateSignal() override;
|
|
||||||
|
|
||||||
void SetPriority(EThreadPriority prio) override;
|
void SetPriority(EThreadPriority prio) override;
|
||||||
void SetThrottle(EThreadThrottle prio) override;
|
void SetThrottle(EThreadThrottle prio) override;
|
||||||
void SetAffinity(const HWInfo::CpuBitId &mask) override;
|
void SetAffinityMask(const HWInfo::CpuBitId &mask) override;
|
||||||
void SetName(const AuString &name) override;
|
void SetName(const AuString &name) override;
|
||||||
void SetNameIdentity(AuUInt32 uNameIdentity) override;
|
void SetNameIdentity(AuUInt32 uNameIdentity) override;
|
||||||
|
|
||||||
EThreadPriority GetPriority() override;
|
EThreadPriority GetPriority() override;
|
||||||
EThreadThrottle GetThrottle() override;
|
EThreadThrottle GetThrottle() override;
|
||||||
HWInfo::CpuBitId GetMask() override;
|
HWInfo::CpuBitId GetAffinityMask() override;
|
||||||
AuString GetName() override;
|
AuString GetName() override;
|
||||||
AuUInt32 GetNameIdentity() override;
|
AuUInt32 GetNameIdentity() override;
|
||||||
|
|
||||||
void ExecuteInDeadThread(AuFunction<void()> callback) override;
|
void ExecuteInDeadThread(AuFunction<void()> callback) override;
|
||||||
AuSPtr<IWaitable> AsWaitable() override;
|
|
||||||
|
|
||||||
void AddLastHopeTlsHook(const AuSPtr<Threading::Threads::IThreadFeature> &feature) override;
|
void AddLastHopeTlsHook(const AuSPtr<Threading::Threads::IThreadFeature> &feature) override;
|
||||||
AuUInt64 SetNoUnwindTerminateExitWatchDogTimeoutInMS(AuUInt64 uMS) override;
|
AuUInt64 SetNoUnwindTerminateExitWatchDogTimeoutInMS(AuUInt64 uMS) override;
|
||||||
@ -52,9 +51,11 @@ namespace Aurora::Threading::Threads
|
|||||||
void InitThreadCreateTime();
|
void InitThreadCreateTime();
|
||||||
|
|
||||||
void _ThreadEP();
|
void _ThreadEP();
|
||||||
AuSPtr<AuLoop::ILoopSource> AsLoopSource() override;
|
AuSPtr<AuLoop::ILoopSource> GetShutdownSignalLoopSource() override;
|
||||||
|
AuSPtr<AuLoop::ILoopSource> GetShutdownLoopSource() override;
|
||||||
|
|
||||||
|
AuSPtr<IWaitable> GetShutdownWaitable() override;
|
||||||
AuSPtr<IWaitable> GetShutdownSignalWaitable() override;
|
AuSPtr<IWaitable> GetShutdownSignalWaitable() override;
|
||||||
AuSPtr<AuLoop::ILoopSource> GetShutdownSignalLS() override;
|
|
||||||
|
|
||||||
bool InternalKillForceNtfy();
|
bool InternalKillForceNtfy();
|
||||||
void SignalDeath();
|
void SignalDeath();
|
||||||
|
@ -32,7 +32,7 @@ namespace Aurora::Threading::Threads
|
|||||||
auto thread = GetThread();
|
auto thread = GetThread();
|
||||||
if (thread && gRuntimeRunLevel < 4)
|
if (thread && gRuntimeRunLevel < 4)
|
||||||
{
|
{
|
||||||
thread->Exit();
|
thread->Terminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user