2021-06-27 21:25:29 +00:00
|
|
|
/***
|
|
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
|
2022-11-17 07:46:07 +00:00
|
|
|
File: AuOSThread.cpp
|
2021-06-27 21:25:29 +00:00
|
|
|
Date: 2021-6-12
|
|
|
|
Author: Reece
|
|
|
|
***/
|
2021-09-30 14:57:41 +00:00
|
|
|
#include <Source/RuntimeInternal.hpp>
|
2022-11-17 07:46:07 +00:00
|
|
|
#include "AuThreads.hpp"
|
|
|
|
#include <Source/Threading/AuWaitFor.hpp>
|
|
|
|
#include "AuOSThread.hpp"
|
|
|
|
#include "AuThreadHandles.hpp"
|
2021-06-27 21:25:29 +00:00
|
|
|
#include "TLSView.hpp"
|
|
|
|
|
2021-09-06 10:58:08 +00:00
|
|
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
2022-01-24 18:37:06 +00:00
|
|
|
#include <sys/resource.h>
|
2022-08-14 22:59:48 +00:00
|
|
|
#include <cxxabi.h>
|
2021-06-27 21:25:29 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(AURORA_HAS_PTHREADS)
|
2022-01-24 18:37:06 +00:00
|
|
|
#include <sched.h>
|
2021-06-27 21:25:29 +00:00
|
|
|
#endif
|
|
|
|
|
2021-09-06 10:58:08 +00:00
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
2022-01-24 18:37:06 +00:00
|
|
|
#include <Aux_ulib.h>
|
2021-09-06 10:58:08 +00:00
|
|
|
#endif
|
|
|
|
|
2022-12-14 01:35:18 +00:00
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
2023-07-09 09:03:29 +00:00
|
|
|
static auto const kThreadPowerThrottling = Aurora::THREAD_INFORMATION_CLASS::ThreadPowerThrottling;
|
2022-12-14 01:35:18 +00:00
|
|
|
|
|
|
|
struct THREAD_POWER_THROTTLING_STATE2
|
|
|
|
{
|
|
|
|
ULONG Version;
|
|
|
|
ULONG ControlMask;
|
|
|
|
ULONG StateMask;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2022-11-17 07:46:07 +00:00
|
|
|
#include "AuSpawnThread.hpp"
|
2021-09-06 10:58:08 +00:00
|
|
|
|
2022-08-14 13:41:19 +00:00
|
|
|
namespace Aurora
|
|
|
|
{
|
|
|
|
void RuntimeLateClean();
|
|
|
|
}
|
|
|
|
|
2021-06-27 21:25:29 +00:00
|
|
|
namespace Aurora::Threading::Threads
|
|
|
|
{
|
2022-04-02 00:48:29 +00:00
|
|
|
static struct DtorFlipper
|
|
|
|
{
|
|
|
|
DtorFlipper() : bActive(true)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~DtorFlipper()
|
|
|
|
{
|
|
|
|
bActive = false;
|
|
|
|
}
|
|
|
|
bool bActive;
|
|
|
|
|
|
|
|
} gGlobal;
|
|
|
|
|
2021-10-24 10:19:47 +00:00
|
|
|
static ThreadInfo gDummyThreadInfo;
|
2021-09-06 10:58:08 +00:00
|
|
|
|
2022-08-06 19:50:40 +00:00
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
static const auto kSignalAbort = SIGUSR1;
|
2022-08-02 04:52:17 +00:00
|
|
|
|
|
|
|
static void HandleSigAbortThread(int a)
|
|
|
|
{
|
2022-08-06 19:50:40 +00:00
|
|
|
((OSThread *)HandleCurrent())->InternalKillForceNtfy();
|
2022-08-02 04:52:17 +00:00
|
|
|
SysPanic("Couldn't terminate thread context");
|
|
|
|
}
|
2022-08-06 19:50:40 +00:00
|
|
|
|
2022-08-02 04:52:17 +00:00
|
|
|
#endif
|
|
|
|
|
2021-10-23 18:25:43 +00:00
|
|
|
OSThread::OSThread(const ThreadInfo &info) : info_(info)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
this->name_ = info.name.value_or("Aurora Thread");
|
2021-10-25 17:08:28 +00:00
|
|
|
|
|
|
|
// maybe we should atomic exchange compare these when needed frogthink
|
2022-08-14 11:01:54 +00:00
|
|
|
this->terminatedSignalLs_ = AuLoop::NewLSEvent(true, false, true);
|
2022-06-11 23:52:46 +00:00
|
|
|
this->terminateSignalLs_ = AuLoop::NewLSEvent(true, false, true);
|
2021-10-25 17:08:28 +00:00
|
|
|
|
2023-04-30 06:54:28 +00:00
|
|
|
this->terminated_ = AuThreadPrimitives::EventShared(true, false, true);
|
|
|
|
this->terminateSignal_ = AuThreadPrimitives::EventShared(true, false, true);
|
|
|
|
|
|
|
|
SysAssert(this->terminatedSignalLs_ && this->terminateSignalLs_ && this->terminated_ && this->terminateSignal_);
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
2021-09-06 10:58:08 +00:00
|
|
|
|
|
|
|
OSThread::OSThread() : info_(gDummyThreadInfo)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
this->name_ = "Main Thread";
|
2023-04-30 06:54:28 +00:00
|
|
|
|
|
|
|
this->terminated_ = AuThreadPrimitives::EventShared(true, false, true);
|
|
|
|
this->terminateSignal_ = AuThreadPrimitives::EventShared(true, false, true);
|
|
|
|
|
|
|
|
SysAssert(this->terminated_ && this->terminateSignal_);
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 10:58:08 +00:00
|
|
|
OSThread::OSThread(AuUInt64 id) : info_(gDummyThreadInfo)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
this->name_ = "System Thread";
|
|
|
|
this->handle_ = reinterpret_cast<decltype(handle_)>(id);
|
2022-08-02 04:52:17 +00:00
|
|
|
this->bNotOwned = true;
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-04-02 00:48:29 +00:00
|
|
|
bool DeadTest();
|
|
|
|
|
2021-06-27 21:25:29 +00:00
|
|
|
OSThread::~OSThread()
|
|
|
|
{
|
2021-11-05 17:34:23 +00:00
|
|
|
bool bDetached {};
|
|
|
|
bool bDetachedSuccess {};
|
|
|
|
|
2022-08-02 04:52:17 +00:00
|
|
|
if (this->bNotOwned)
|
|
|
|
{
|
2022-10-14 06:14:56 +00:00
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
|
|
auto hHandle = (HANDLE)this->handle_;
|
|
|
|
AuWin32CloseHandle(hHandle);
|
|
|
|
#endif
|
2022-08-02 04:52:17 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-08-14 13:41:19 +00:00
|
|
|
if (!gGlobal.bActive)
|
2022-04-02 00:48:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-08-14 21:09:25 +00:00
|
|
|
#if 0
|
2022-08-14 13:41:19 +00:00
|
|
|
if (DeadTest())
|
2022-04-02 00:48:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2022-08-14 21:09:25 +00:00
|
|
|
#endif
|
2022-03-16 17:12:08 +00:00
|
|
|
if (this->contextUsed_)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
if (this->detached_)
|
2021-11-05 17:34:23 +00:00
|
|
|
{
|
|
|
|
bDetached = true;
|
|
|
|
}
|
|
|
|
else
|
2021-10-25 18:19:49 +00:00
|
|
|
{
|
2022-08-14 22:59:48 +00:00
|
|
|
if (gRuntimeRunLevel <= 3)
|
2022-08-14 11:01:54 +00:00
|
|
|
{
|
|
|
|
Exit();
|
|
|
|
}
|
2022-08-14 13:41:19 +00:00
|
|
|
else if (gRuntimeRunLevel >= 5)
|
|
|
|
{
|
|
|
|
// Application is dead
|
|
|
|
}
|
2022-08-14 11:01:54 +00:00
|
|
|
else
|
|
|
|
{
|
2022-08-15 02:31:35 +00:00
|
|
|
if (this->terminated_)
|
|
|
|
{
|
|
|
|
this->exiting_ = true;
|
2023-04-30 06:54:28 +00:00
|
|
|
if (this->terminated_->LockMS(5'000))
|
2022-08-15 02:31:35 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-14 11:01:54 +00:00
|
|
|
// Kill the current OS thread instance
|
|
|
|
TeminateOSContext(false);
|
2022-08-14 22:59:48 +00:00
|
|
|
|
2022-08-14 13:41:19 +00:00
|
|
|
if (this->exitOnlyOnce_)
|
2022-08-14 11:01:54 +00:00
|
|
|
{
|
2022-08-14 13:41:19 +00:00
|
|
|
this->exitOnlyOnce_->Unlock();
|
|
|
|
}
|
2022-08-14 22:59:48 +00:00
|
|
|
|
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
if (this->terminated_)
|
|
|
|
{
|
|
|
|
WaitFor(this->terminated_.get());
|
|
|
|
}
|
|
|
|
#endif
|
2022-08-14 11:01:54 +00:00
|
|
|
}
|
2021-10-25 18:19:49 +00:00
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
2021-09-06 10:58:08 +00:00
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
this->terminated_.reset();
|
2021-06-27 21:25:29 +00:00
|
|
|
FreeOSContext();
|
2022-08-14 22:59:48 +00:00
|
|
|
|
2021-11-05 17:34:23 +00:00
|
|
|
if (bDetached)
|
|
|
|
{
|
|
|
|
if (this->tlsReferenceThread_)
|
|
|
|
{
|
|
|
|
AU_LOCK_GUARD(this->tlsLock_);
|
|
|
|
AU_LOCK_GUARD(this->tlsReferenceThread_->tlsLock_);
|
|
|
|
|
2023-04-30 06:54:28 +00:00
|
|
|
SetThreadKey(this->tlsReferenceThread_->tls_);
|
2022-01-19 17:08:13 +00:00
|
|
|
AuExchange(this->tlsReferenceThread_->tls_, this->tls_);
|
|
|
|
AuExchange(this->tlsReferenceThread_->threadFeatures_, this->threadFeatures_);
|
2021-11-05 17:34:23 +00:00
|
|
|
|
|
|
|
bDetachedSuccess = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bDetachedSuccess || !bDetached)
|
|
|
|
{
|
|
|
|
HookReleaseThreadResources();
|
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Called whenever an aurora thread is exiting
|
|
|
|
void OSThread::HookOnExit()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Called whenever a thread object is released, or on thread termination
|
|
|
|
// Whichever is soonest
|
|
|
|
// It is possible a user may wish to keep a thread handle open
|
|
|
|
// Is is expected for a system thread to release on dtor unlike our aurora threads
|
|
|
|
void OSThread::HookReleaseThreadResources()
|
|
|
|
{
|
2023-04-30 06:54:28 +00:00
|
|
|
AU_LOCK_GUARD(this->tlsLock_);
|
2022-03-16 17:12:08 +00:00
|
|
|
for (const auto &feature : this->threadFeatures_)
|
2021-09-06 10:58:08 +00:00
|
|
|
{
|
|
|
|
feature->Cleanup();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-05 17:34:23 +00:00
|
|
|
void OSThread::AddLastHopeTlsHook(const AuSPtr<AuThreads::IThreadFeature> &feature)
|
2021-09-06 10:58:08 +00:00
|
|
|
{
|
2023-04-30 06:54:28 +00:00
|
|
|
AU_LOCK_GUARD(this->tlsLock_);
|
2021-11-05 17:34:23 +00:00
|
|
|
if (!feature)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2022-03-16 17:12:08 +00:00
|
|
|
AuTryInsert(this->threadFeatures_, feature);
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2021-10-25 18:19:49 +00:00
|
|
|
void OSThread::Detach()
|
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
this->detached_ = true;
|
2021-10-25 18:19:49 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 10:58:08 +00:00
|
|
|
AuSPtr<IWaitable> OSThread::AsWaitable()
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
return this->terminated_;
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSThread::SendExitSignal()
|
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
this->exiting_ = true;
|
2021-10-25 17:08:28 +00:00
|
|
|
|
|
|
|
if (this->terminateSignalLs_)
|
|
|
|
{
|
|
|
|
this->terminateSignalLs_->Set();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->terminateSignal_)
|
|
|
|
{
|
|
|
|
this->terminateSignal_->Set();
|
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-08-13 23:32:39 +00:00
|
|
|
void OSThread::UnsafeForceTerminateSignal()
|
|
|
|
{
|
|
|
|
TeminateOSContext(false);
|
|
|
|
}
|
|
|
|
|
2021-09-06 10:58:08 +00:00
|
|
|
bool OSThread::Run()
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
if (!this->terminated_)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
SysPanic("::Run called on system thread");
|
|
|
|
}
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
if (AuExchange(this->contextUsed_, true))
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2021-09-06 10:58:08 +00:00
|
|
|
return false;
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
this->terminated_->Reset();
|
2021-06-27 21:25:29 +00:00
|
|
|
|
2021-09-06 10:58:08 +00:00
|
|
|
return ExecuteNewOSContext([=]()
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2021-10-23 18:25:43 +00:00
|
|
|
// this functional backends are being deprecated
|
2022-03-16 17:12:08 +00:00
|
|
|
if (this->info_.callbacks)
|
2021-10-23 18:25:43 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
this->info_.callbacks->OnEntry(this);
|
2021-10-23 18:25:43 +00:00
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
Debug::PrintError();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSThread::Exit()
|
|
|
|
{
|
2023-06-04 16:28:29 +00:00
|
|
|
this->PrivateUserDataClear();
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
while ((!this->terminated_) || (!this->terminated_->TryLock()))
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
if (Exit(false)) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 00:48:29 +00:00
|
|
|
bool OSThread::Exit(bool willReturnToOS, bool isEOL)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
if (GetThread() == this)
|
|
|
|
{
|
|
|
|
if (!this->InternalKill(false))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// release handle + sigterm
|
|
|
|
if (!willReturnToOS)
|
|
|
|
{
|
|
|
|
TeminateOSContext(true);
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
YieldToOtherThread();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// exit signal
|
2022-03-16 17:12:08 +00:00
|
|
|
this->exiting_ = true;
|
2021-06-27 21:25:29 +00:00
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
if (!this->terminated_)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-08-14 13:41:19 +00:00
|
|
|
if (!this->exitOnlyOnce_)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-06-27 21:25:29 +00:00
|
|
|
// attempt to join with the thread once it has exited, or timeout
|
2022-03-16 17:12:08 +00:00
|
|
|
if (WaitFor(this->terminated_.get(), 15 * 1000))
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do not force terminate if we're marked as dead and still running
|
|
|
|
// The thread must've requested suicide and got stuck in a lengthy clean up effort
|
2022-03-16 17:12:08 +00:00
|
|
|
if (!this->exitOnlyOnce_->TryLock())
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-01-24 18:37:06 +00:00
|
|
|
AuLogWarn("Watchdog error - OS thread context didn't finish in 15 seconds, but he should exiting now.");
|
2021-06-27 21:25:29 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-01-24 18:37:06 +00:00
|
|
|
AuLogWarn("Watchdog error - OS thread context didn't finish in 15 seconds, forcefully terminating without a watchdog overlooking onExit");
|
2021-06-27 21:25:29 +00:00
|
|
|
|
|
|
|
// Kill the current OS thread instance
|
|
|
|
TeminateOSContext(false);
|
|
|
|
|
|
|
|
// Dispatch kill callback from within an emulated thread context (no switch, just just change thread tls)
|
|
|
|
ExecuteInDeadThread([=]()
|
|
|
|
{
|
|
|
|
this->InternalKill(true);
|
|
|
|
});
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
this->exitOnlyOnce_->Unlock();
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OSThread::Exiting()
|
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
return this->exiting_;
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSThread::SetName(const AuString &name)
|
|
|
|
{
|
2023-07-30 09:00:54 +00:00
|
|
|
if (gRuntimeConfig.threadingConfig.bNoThreadNames)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2022-03-16 17:12:08 +00:00
|
|
|
this->name_ = name;
|
2022-10-14 06:14:56 +00:00
|
|
|
this->UpdateName();
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
EThreadThrottle OSThread::GetThrottle()
|
|
|
|
{
|
|
|
|
return this->throttle_;
|
|
|
|
}
|
|
|
|
|
|
|
|
EThreadPriority OSThread::GetPriority()
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
return this->prio_;
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
AuHwInfo::CpuBitId OSThread::GetMask()
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
return this->mask_;
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AuString OSThread::GetName()
|
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
return this->name_;
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
void OSThread::SetAffinity(const HWInfo::CpuBitId &mask)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
auto zero = HWInfo::CpuBitId();
|
|
|
|
|
|
|
|
if (mask == zero ||
|
|
|
|
mask == zero.Not())
|
|
|
|
{
|
2022-03-20 12:50:36 +00:00
|
|
|
this->mask_ = HWInfo::GetCPUInfo().maskAllCores;
|
2022-03-21 07:16:12 +00:00
|
|
|
this->userManagingAffinity_ = false;
|
|
|
|
|
|
|
|
UpdatePrio(this->throttle_, this->prio_);
|
2022-03-16 17:12:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->mask_ = mask;
|
2022-03-21 07:16:12 +00:00
|
|
|
this->userManagingAffinity_ = true;
|
2022-03-16 17:12:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UpdateAffinity(this->mask_);
|
2023-01-23 15:23:43 +00:00
|
|
|
AffinityPrioThrottleTickAmendECores();
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
void OSThread::SetPriority(EThreadPriority prio)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
if (!EThreadPriorityIsValid(prio))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdatePrio(this->throttle_, prio);
|
2023-01-23 15:23:43 +00:00
|
|
|
AffinityPrioThrottleTickAmendECores();
|
2022-03-21 07:16:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSThread::SetThrottle(EThreadThrottle throttle)
|
|
|
|
{
|
|
|
|
if (!EThreadThrottleIsValid(throttle))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->throttle_ = throttle;
|
|
|
|
UpdatePrio(this->throttle_, this->prio_);
|
2023-01-23 15:23:43 +00:00
|
|
|
AffinityPrioThrottleTickAmendECores();
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AuSPtr<TLSView> OSThread::GetTlsView()
|
|
|
|
{
|
2023-04-30 06:54:28 +00:00
|
|
|
SysPanic("Deprecated Concept");
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-01-19 17:08:13 +00:00
|
|
|
bool OSThread::ExecuteNewOSContext(AuFunction<void()> task)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
this->task_ = task;
|
2021-06-27 21:25:29 +00:00
|
|
|
|
2022-10-14 06:14:56 +00:00
|
|
|
this->handle_ = 0;
|
|
|
|
|
2022-01-24 18:37:06 +00:00
|
|
|
auto ret = SpawnThread([this]()
|
2021-09-06 10:58:08 +00:00
|
|
|
{
|
2023-01-23 15:23:43 +00:00
|
|
|
while ((!this->handle_) ||
|
2023-08-11 15:51:42 +00:00
|
|
|
#if defined(INVALID_HANDLE_VALUE)
|
2023-01-23 15:23:43 +00:00
|
|
|
(this->handle_ == INVALID_HANDLE_VALUE)
|
2023-08-11 15:51:42 +00:00
|
|
|
#else
|
|
|
|
0
|
|
|
|
#endif
|
2023-01-23 15:23:43 +00:00
|
|
|
)
|
2022-10-14 06:14:56 +00:00
|
|
|
{
|
2023-01-23 15:23:43 +00:00
|
|
|
AuThreading::ContextYield();
|
|
|
|
}
|
2022-10-14 06:14:56 +00:00
|
|
|
|
2023-04-30 06:54:28 +00:00
|
|
|
if (!this->tls_)
|
|
|
|
{
|
|
|
|
this->tls_ = GetThreadKey();
|
|
|
|
}
|
|
|
|
|
2022-01-24 18:37:06 +00:00
|
|
|
this->_ThreadEP();
|
2022-03-16 17:12:08 +00:00
|
|
|
}, GetName(), this->info_.stackSize);
|
2022-01-24 18:37:06 +00:00
|
|
|
|
|
|
|
if (ret.first)
|
2021-09-06 10:58:08 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
this->handle_ = (decltype(handle_))ret.second;
|
2021-09-06 10:58:08 +00:00
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
|
2022-01-24 18:37:06 +00:00
|
|
|
return ret.first;
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2023-01-23 15:23:43 +00:00
|
|
|
void OSThread::AffinityPrioThrottleTickAmendECores()
|
|
|
|
{
|
|
|
|
auto zero = HWInfo::CpuBitId();
|
|
|
|
auto &cpuInfo = AuHwInfo::GetCPUInfo();
|
|
|
|
auto sysEcores = cpuInfo.maskECores;
|
|
|
|
bool bIsMaskProbablyDefault = this->mask_ == zero || this->mask_ == zero.Not();
|
|
|
|
bool bSystemHasNoECores = sysEcores == zero;
|
|
|
|
EThreadPriority prio = this->prio_;
|
|
|
|
|
|
|
|
if (this->throttle_ == EThreadThrottle::eEfficient &&
|
|
|
|
bSystemHasNoECores)
|
|
|
|
{
|
|
|
|
if (bIsMaskProbablyDefault)
|
|
|
|
{
|
|
|
|
sysEcores = cpuInfo.maskAllCores;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
* Systems without ecores would see a higher prio work than normal tasks if
|
|
|
|
* we do nothing about this. On systems without ecores, efficiency throttle
|
|
|
|
* will just lock the prio to low.
|
|
|
|
*/
|
|
|
|
prio = EThreadPriority::ePrioLow;
|
|
|
|
|
|
|
|
UpdatePrio(this->throttle_, prio);
|
|
|
|
UpdateAffinity(sysEcores);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-27 21:25:29 +00:00
|
|
|
void OSThread::_ThreadEP()
|
|
|
|
{
|
2021-11-05 17:34:23 +00:00
|
|
|
// Poke TLS reference thread entity
|
|
|
|
// TODO: we need an internal OSThread *TryPokeTLSThread()
|
|
|
|
auto osThread = static_cast<OSThread *>(GetThread());
|
|
|
|
this->tlsReferenceThread_ = osThread;
|
2022-08-14 13:41:19 +00:00
|
|
|
bool bFailing {};
|
2021-11-05 17:34:23 +00:00
|
|
|
|
2021-10-25 18:19:49 +00:00
|
|
|
OSAttach();
|
2022-08-14 22:59:48 +00:00
|
|
|
|
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
this->bLongJmpOnce = false;
|
|
|
|
if (setjmp(env) != 0)
|
|
|
|
{
|
|
|
|
Exit(true);
|
2022-08-15 02:31:35 +00:00
|
|
|
return;
|
2022-08-14 22:59:48 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-01-21 16:26:35 +00:00
|
|
|
try
|
|
|
|
{
|
2022-08-02 04:52:17 +00:00
|
|
|
if (task_)
|
|
|
|
{
|
|
|
|
task_();
|
|
|
|
}
|
2022-01-21 16:26:35 +00:00
|
|
|
}
|
2022-08-14 11:01:54 +00:00
|
|
|
|
|
|
|
#if !defined(AURORA_IS_POSIX_DERIVED)
|
2022-01-21 16:26:35 +00:00
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
SysPushErrorHAL("OS Thread Aborted");
|
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
Exit(true);
|
2022-08-14 11:01:54 +00:00
|
|
|
#else
|
2022-08-14 22:59:48 +00:00
|
|
|
#if defined(AURORA_COMPILER_GCC)
|
|
|
|
catch (abi::__forced_unwind&)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
#endif
|
2022-08-14 11:01:54 +00:00
|
|
|
catch (...)
|
|
|
|
{
|
2022-08-14 13:41:19 +00:00
|
|
|
bFailing = true;
|
2022-08-14 11:01:54 +00:00
|
|
|
if (!Aurora::kIsDebugBuild)
|
|
|
|
{
|
|
|
|
SysPushErrorHAL("OS Thread Aborted");
|
|
|
|
}
|
2022-08-14 13:41:19 +00:00
|
|
|
|
|
|
|
// "Safer" update
|
|
|
|
this->HookOnExit();
|
|
|
|
|
2022-08-15 02:31:35 +00:00
|
|
|
|
2022-08-14 13:41:19 +00:00
|
|
|
if (this->terminated_)
|
|
|
|
{
|
2022-08-14 22:59:48 +00:00
|
|
|
if (this->exitOnlyOnce_)
|
|
|
|
{
|
|
|
|
this->exitOnlyOnce_->Unlock();
|
|
|
|
}
|
2022-08-14 13:41:19 +00:00
|
|
|
this->terminated_->Set();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->terminatedSignalLs_)
|
|
|
|
{
|
|
|
|
this->terminatedSignalLs_->Set();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bFailing)
|
|
|
|
{
|
2022-08-14 11:01:54 +00:00
|
|
|
Exit(true);
|
|
|
|
}
|
|
|
|
#endif
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-01-19 17:08:13 +00:00
|
|
|
void OSThread::ExecuteInDeadThread(AuFunction<void()> callback)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
auto old = HandleCurrent();
|
|
|
|
|
|
|
|
if (this == old) [[unlikely]]
|
|
|
|
{
|
|
|
|
callback();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (old)
|
|
|
|
{
|
2021-10-25 18:19:49 +00:00
|
|
|
static_cast<OSThread *>(old)->OSDeatach();
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2023-04-30 08:05:14 +00:00
|
|
|
auto uOldHandle = GetThreadKey();
|
2021-10-25 18:19:49 +00:00
|
|
|
this->OSAttach();
|
2021-06-27 21:25:29 +00:00
|
|
|
|
|
|
|
callback();
|
|
|
|
|
|
|
|
if (old)
|
|
|
|
{
|
|
|
|
HandleRegister(old);
|
2021-10-25 18:19:49 +00:00
|
|
|
static_cast<OSThread *>(old)->OSDeatach();
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
else [[unlikely]]
|
|
|
|
{
|
|
|
|
HandleRemove();
|
|
|
|
}
|
2023-04-30 08:05:14 +00:00
|
|
|
|
|
|
|
SetThreadKey(uOldHandle);
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OSThread::UpdateName()
|
|
|
|
{
|
2023-07-30 09:00:54 +00:00
|
|
|
if (gRuntimeConfig.threadingConfig.bNoThreadNames)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-16 16:34:55 +00:00
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
2021-06-27 21:25:29 +00:00
|
|
|
|
2022-03-16 16:34:55 +00:00
|
|
|
if (this->handle_ == INVALID_HANDLE_VALUE)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-16 16:34:55 +00:00
|
|
|
if ((AuBuild::kCurrentPlatform == AuBuild::EPlatform::ePlatformWin32) && (!AuSwInfo::IsWindows10OrGreater()))
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-16 16:34:55 +00:00
|
|
|
static const DWORD kMSVCExceptionSetName = 0x406D1388;
|
2021-06-27 21:25:29 +00:00
|
|
|
|
2022-03-16 16:34:55 +00:00
|
|
|
#pragma pack(push,8)
|
|
|
|
typedef struct tagTHREADNAME_INFO
|
|
|
|
{
|
|
|
|
DWORD dwType;
|
|
|
|
LPCSTR szName;
|
|
|
|
DWORD dwThreadID;
|
|
|
|
DWORD dwFlags;
|
|
|
|
} THREADNAME_INFO;
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
if (!IsDebuggerPresent())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
|
2022-03-16 16:34:55 +00:00
|
|
|
THREADNAME_INFO info;
|
|
|
|
info.dwType = 0x1000;
|
|
|
|
info.szName = this->name_.c_str();
|
2023-07-24 11:48:42 +00:00
|
|
|
if (pGetThreadId)
|
|
|
|
{
|
|
|
|
info.dwThreadID = pGetThreadId(this->handle_);
|
|
|
|
}
|
|
|
|
else if (this->unixThreadId_ == GetCurrentThreadId())
|
|
|
|
{
|
|
|
|
info.dwThreadID = this->unixThreadId_;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-16 16:34:55 +00:00
|
|
|
info.dwFlags = 0;
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
auto raise = AuStaticCast<void(__cdecl *)(THREADNAME_INFO &)>([](THREADNAME_INFO &info)
|
2022-03-16 16:34:55 +00:00
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
__try
|
|
|
|
{
|
|
|
|
RaiseException(kMSVCExceptionSetName, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info);
|
|
|
|
}
|
|
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
raise(info);
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
2022-03-16 16:34:55 +00:00
|
|
|
else
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2023-07-09 09:03:29 +00:00
|
|
|
if (pSetThreadDescription)
|
2022-03-16 16:34:55 +00:00
|
|
|
{
|
2023-07-09 09:03:29 +00:00
|
|
|
pSetThreadDescription(this->handle_, AuLocale::ConvertFromUTF8(this->name_).c_str());
|
2022-03-16 16:34:55 +00:00
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
2022-03-16 16:34:55 +00:00
|
|
|
|
2021-06-27 21:25:29 +00:00
|
|
|
#elif defined(AURORA_HAS_PTHREADS)
|
|
|
|
|
2023-08-11 15:51:42 +00:00
|
|
|
if (!this->handle_)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
pthread_setname_np(this->handle_, this->name_.c_str());
|
2021-06-27 21:25:29 +00:00
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2022-08-06 19:50:40 +00:00
|
|
|
static void AttachSignalKiller()
|
|
|
|
{
|
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
struct sigaction action =
|
|
|
|
{
|
|
|
|
.sa_handler = HandleSigAbortThread,
|
|
|
|
};
|
|
|
|
::sigemptyset(&action.sa_mask);
|
|
|
|
::sigaction(kSignalAbort, &action, nullptr);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-10-25 18:19:49 +00:00
|
|
|
void OSThread::OSAttach()
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-08-02 04:52:17 +00:00
|
|
|
this->bSupportsAltKill = true;
|
|
|
|
|
2021-06-27 21:25:29 +00:00
|
|
|
HandleRegister(this);
|
2021-09-06 10:58:08 +00:00
|
|
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
2021-06-27 21:25:29 +00:00
|
|
|
this->unixThreadId_ = gettid();
|
2021-09-06 10:58:08 +00:00
|
|
|
#elif defined(AURORA_IS_XNU_DERIVED)
|
2021-06-27 21:25:29 +00:00
|
|
|
this->unixThreadId_ = pthread_getthreadid_np();
|
2021-09-06 10:58:08 +00:00
|
|
|
#elif defined(AURORA_IS_BSD_DERIVED)
|
|
|
|
#if __FreeBSD_version < 900031
|
|
|
|
long lwpid;
|
|
|
|
thr_self(&lwpid);
|
|
|
|
this->unixThreadId_ = lwpid;
|
|
|
|
#elif __FreeBSD_version > 900030
|
|
|
|
this->unixThreadId_ = pthread_getthreadid_np();
|
|
|
|
#else
|
|
|
|
static_assert(false);
|
|
|
|
#endif
|
2021-06-27 21:25:29 +00:00
|
|
|
#elif defined(AURORA_HAS_PTHREADS)
|
|
|
|
this->unixThreadId_ = 0; // !!!!
|
|
|
|
#endif
|
2022-03-21 07:16:12 +00:00
|
|
|
|
2023-07-24 11:48:42 +00:00
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
|
|
this->unixThreadId_ = GetCurrentThreadId();
|
|
|
|
#endif
|
|
|
|
|
2023-04-30 08:05:14 +00:00
|
|
|
if (this->tls_)
|
|
|
|
{
|
|
|
|
SetThreadKey(this->tls_);
|
|
|
|
}
|
2022-03-21 07:16:12 +00:00
|
|
|
UpdatePrio(this->throttle_, this->prio_);
|
2022-03-16 17:12:08 +00:00
|
|
|
SetAffinity(this->mask_);
|
2023-01-23 15:23:43 +00:00
|
|
|
AffinityPrioThrottleTickAmendECores();
|
2021-06-27 21:25:29 +00:00
|
|
|
UpdateName();
|
2022-08-06 19:50:40 +00:00
|
|
|
AttachSignalKiller();
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
static AuHashMap<EThreadPriority, int> kNiceMap
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
EThreadPriority::ePrioRT, -19
|
2021-06-27 21:25:29 +00:00
|
|
|
},
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
EThreadPriority::ePrioAboveHigh, -19
|
2021-06-27 21:25:29 +00:00
|
|
|
},
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
EThreadPriority::ePrioHigh, -11
|
2021-06-27 21:25:29 +00:00
|
|
|
},
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
EThreadPriority::ePrioNormal, -2
|
2021-06-27 21:25:29 +00:00
|
|
|
},
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
EThreadPriority::ePrioLow, 5
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EThreadPriority::ePrioLowest, 15
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
};
|
2021-09-06 10:58:08 +00:00
|
|
|
|
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
2022-03-21 07:16:12 +00:00
|
|
|
static const AuHashMap<EThreadPriority, int> kWin32Map
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
EThreadPriority::ePrioRT, THREAD_PRIORITY_TIME_CRITICAL
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EThreadPriority::ePrioAboveHigh, THREAD_PRIORITY_HIGHEST
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EThreadPriority::ePrioHigh, THREAD_PRIORITY_ABOVE_NORMAL
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EThreadPriority::ePrioNormal, THREAD_PRIORITY_NORMAL
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EThreadPriority::ePrioLow, THREAD_PRIORITY_BELOW_NORMAL
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EThreadPriority::ePrioLowest, THREAD_PRIORITY_LOWEST
|
|
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(AURORA_IS_XNU_DERIVED)
|
|
|
|
static const AuHashMap<AuPair<EThreadThrottle, EThreadPriority>, AuPair<AuUInt32, int>> kXnuQoSLevel
|
|
|
|
{
|
|
|
|
// Rt
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eNormal, EThreadPriority::ePrioRT), AuMakePair(DISPATCH_QUEUE_PRIORITY_HIGH, 10)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eNormal, EThreadPriority::ePrioAboveHigh), AuMakePair(DISPATCH_QUEUE_PRIORITY_DEFAULT, 5)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eNormal, EThreadPriority::ePrioHigh), AuMakePair(DISPATCH_QUEUE_PRIORITY_DEFAULT, 1)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eNormal, EThreadPriority::ePrioNormal), AuMakePair(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eNormal, EThreadPriority::ePrioLow), AuMakePair(DISPATCH_QUEUE_PRIORITY_LOW, 0)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eNormal, EThreadPriority::ePrioLowest), AuMakePair(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
|
|
|
|
},
|
|
|
|
|
|
|
|
// Perf
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::ePerformance, EThreadPriority::ePrioRT), AuMakePair(DISPATCH_QUEUE_PRIORITY_HIGH, 10)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::ePerformance, EThreadPriority::ePrioAboveHigh), AuMakePair(DISPATCH_QUEUE_PRIORITY_HIGH, 8)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::ePerformance, EThreadPriority::ePrioHigh), AuMakePair(DISPATCH_QUEUE_PRIORITY_HIGH, 3)
|
2021-06-27 21:25:29 +00:00
|
|
|
},
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
AuMakePair(EThreadThrottle::ePerformance, EThreadPriority::ePrioNormal), AuMakePair(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
|
2021-06-27 21:25:29 +00:00
|
|
|
},
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
AuMakePair(EThreadThrottle::ePerformance, EThreadPriority::ePrioLow), AuMakePair(DISPATCH_QUEUE_PRIORITY_DEFAULT, 1)
|
2021-06-27 21:25:29 +00:00
|
|
|
},
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
AuMakePair(EThreadThrottle::ePerformance, EThreadPriority::ePrioLowest), AuMakePair(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
|
2021-06-27 21:25:29 +00:00
|
|
|
},
|
2022-03-21 07:16:12 +00:00
|
|
|
|
|
|
|
// Efficient
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
AuMakePair(EThreadThrottle::eEfficient, EThreadPriority::ePrioRT), AuMakePair(DISPATCH_QUEUE_PRIORITY_LOW, 10)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eEfficient, EThreadPriority::ePrioAboveHigh), AuMakePair(DISPATCH_QUEUE_PRIORITY_LOW, 1)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eEfficient, EThreadPriority::ePrioHigh), AuMakePair(DISPATCH_QUEUE_PRIORITY_LOW, 0)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eEfficient, EThreadPriority::ePrioNormal), AuMakePair(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eEfficient, EThreadPriority::ePrioLow), AuMakePair(DISPATCH_QUEUE_PRIORITY_BACKGROUND, -1)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
AuMakePair(EThreadThrottle::eEfficient, EThreadPriority::ePrioLowest), AuMakePair(DISPATCH_QUEUE_PRIORITY_BACKGROUND, -2)
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
void OSThread::UpdatePrio(EThreadThrottle throttle, EThreadPriority prio)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2021-09-06 10:58:08 +00:00
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
2021-06-27 21:25:29 +00:00
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
if (this->handle_ == INVALID_HANDLE_VALUE)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const int *val;
|
2021-09-06 10:58:08 +00:00
|
|
|
if (!AuTryFind(kWin32Map, prio, val))
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
if (!SetThreadPriority(this->handle_, *val))
|
|
|
|
{
|
|
|
|
SysPushErrorHAL("Couldn't update thread priority");
|
|
|
|
}
|
|
|
|
|
2022-12-14 01:35:18 +00:00
|
|
|
THREAD_POWER_THROTTLING_STATE2 throttlingState {};
|
2022-03-21 07:16:12 +00:00
|
|
|
throttlingState.Version = THREAD_POWER_THROTTLING_CURRENT_VERSION;
|
|
|
|
|
|
|
|
switch (throttle)
|
|
|
|
{
|
|
|
|
case EThreadThrottle::eNormal:
|
|
|
|
throttlingState.ControlMask = 0;
|
|
|
|
throttlingState.StateMask = 0;
|
|
|
|
break;
|
|
|
|
case EThreadThrottle::ePerformance:
|
|
|
|
throttlingState.ControlMask = THREAD_POWER_THROTTLING_EXECUTION_SPEED;
|
|
|
|
throttlingState.StateMask = 0;
|
|
|
|
break;
|
|
|
|
case EThreadThrottle::eEfficient:
|
|
|
|
throttlingState.ControlMask = THREAD_POWER_THROTTLING_EXECUTION_SPEED;
|
|
|
|
throttlingState.StateMask = THREAD_POWER_THROTTLING_EXECUTION_SPEED;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-07-09 09:03:29 +00:00
|
|
|
if (pSetThreadInformation)
|
2022-12-14 01:35:18 +00:00
|
|
|
{
|
2023-07-09 09:03:29 +00:00
|
|
|
pSetThreadInformation(this->handle_,
|
|
|
|
kThreadPowerThrottling,
|
|
|
|
&throttlingState,
|
|
|
|
sizeof(throttlingState));
|
2022-12-14 01:35:18 +00:00
|
|
|
}
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
//#elif defined(AURORA_IS_XNU_DERIVED)
|
|
|
|
|
2021-06-27 21:25:29 +00:00
|
|
|
|
|
|
|
#elif defined(AURORA_HAS_PTHREADS)
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
if (!this->handle_)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
if (prio == EThreadPriority::ePrioRT)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
sched_param param {};
|
|
|
|
param.sched_priority = sched_get_priority_min(SCHED_RR);
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
if (pthread_setschedparam(this->handle_, SCHED_RR, ¶m) == 0)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// fall through on error
|
|
|
|
}
|
2022-03-21 07:16:12 +00:00
|
|
|
else if (this->prio_ == EThreadPriority::ePrioRT)
|
2021-11-05 17:34:23 +00:00
|
|
|
{
|
|
|
|
int policyNonRT =
|
|
|
|
#if defined(AURORA_IS_XNU_DERIVED)
|
|
|
|
SCHED_FIFO;
|
|
|
|
#else
|
|
|
|
SCHED_OTHER;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
sched_param param {};
|
|
|
|
param.sched_priority = sched_get_priority_min(policyNonRT);
|
2022-03-16 17:12:08 +00:00
|
|
|
pthread_setschedparam(this->handle_, policyNonRT, ¶m);
|
2021-11-05 17:34:23 +00:00
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
|
|
|
|
const int *val;
|
2021-09-06 10:58:08 +00:00
|
|
|
if (!AuTryFind(kNiceMap, prio, val))
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (auto tid = unixThreadId_)
|
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
// TODO: per thread beaviour is a linux bug
|
2021-10-02 16:07:33 +00:00
|
|
|
setpriority(PRIO_PROCESS, tid, *val);
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
2021-11-05 17:34:23 +00:00
|
|
|
#endif
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
#if defined(AURORA_IS_LINUX_DERIVED) || defined(AURORA_IS_BSD_DERIVED)
|
|
|
|
switch (throttle)
|
|
|
|
{
|
|
|
|
case EThreadThrottle::eNormal:
|
2022-03-30 14:18:07 +00:00
|
|
|
this->throttleMask_ = AuHwInfo::GetCPUInfo().maskAllCores;
|
2022-03-21 07:16:12 +00:00
|
|
|
break;
|
|
|
|
case EThreadThrottle::ePerformance:
|
|
|
|
this->throttleMask_ = AuHwInfo::GetCPUInfo().maskPCores;
|
|
|
|
break;
|
|
|
|
case EThreadThrottle::eEfficient:
|
|
|
|
this->throttleMask_ = AuHwInfo::GetCPUInfo().maskECores;
|
|
|
|
break;
|
|
|
|
}
|
2022-03-21 07:31:01 +00:00
|
|
|
|
|
|
|
UpdateAffinity(this->mask_);
|
2022-03-21 07:16:12 +00:00
|
|
|
#endif
|
2022-03-30 14:18:07 +00:00
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
this->prio_ = prio;
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
void OSThread::UpdateAffinity(const HWInfo::CpuBitId &mask)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-04-06 06:25:34 +00:00
|
|
|
|
2021-09-06 10:58:08 +00:00
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
2022-03-21 07:16:12 +00:00
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
if (this->handle_ == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-01-23 15:23:43 +00:00
|
|
|
if ((AuBuild::kCurrentPlatform != AuBuild::EPlatform::ePlatformWin32) ||
|
|
|
|
(AuSwInfo::IsWindows10OrGreater()))
|
2022-03-16 17:12:08 +00:00
|
|
|
{
|
2022-04-10 16:18:21 +00:00
|
|
|
auto sets = mask.CpuBitCount() ?
|
|
|
|
mask.ToCpuSets() :
|
|
|
|
AuHwInfo::GetCPUInfo().maskAllCores.ToCpuSets();
|
2022-03-16 17:12:08 +00:00
|
|
|
|
2023-07-09 09:03:29 +00:00
|
|
|
if (pSetThreadSelectedCpuSets)
|
2022-03-16 17:12:08 +00:00
|
|
|
{
|
2023-07-09 09:03:29 +00:00
|
|
|
if (pSetThreadSelectedCpuSets(this->handle_, sets.data(), sets.size()))
|
2022-03-16 17:12:08 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SysPushErrorUnavailableError("SetThreadSelectedCpuSets is expected on modern NT (CoreOS?) excluding Windows; or Win10+");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
2023-07-14 15:31:47 +00:00
|
|
|
if (pSetThreadGroupAffinity)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2023-07-14 15:31:47 +00:00
|
|
|
GROUP_AFFINITY affinityGroup { 0 };
|
|
|
|
mask.ToMsWin7GroupAffinity(&affinityGroup);
|
|
|
|
if (pSetThreadGroupAffinity(this->handle_, &affinityGroup, nullptr))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
2023-07-14 15:31:47 +00:00
|
|
|
|
|
|
|
SetThreadAffinityMask(this->handle_, mask.lower);
|
2021-06-27 21:25:29 +00:00
|
|
|
#endif
|
2022-03-16 17:12:08 +00:00
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
SysPushErrorUnavailableError("Couldn't set thread affinity");
|
|
|
|
return;
|
2022-03-16 17:12:08 +00:00
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
#elif defined(AURORA_HAS_PTHREADS)
|
2023-08-11 15:51:42 +00:00
|
|
|
|
|
|
|
if (!this->handle_)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
auto mask2 = mask.And(this->throttleMask_);
|
|
|
|
|
|
|
|
if (mask2.CpuBitCount() == 0)
|
|
|
|
{
|
|
|
|
switch (this->throttle_)
|
|
|
|
{
|
|
|
|
case EThreadThrottle::eNormal:
|
2022-04-06 06:25:34 +00:00
|
|
|
mask2 = AuHwInfo::GetCPUInfo().maskAllCores;
|
2022-03-21 07:16:12 +00:00
|
|
|
break;
|
|
|
|
case EThreadThrottle::ePerformance:
|
|
|
|
mask2 = AuHwInfo::GetCPUInfo().maskPCores;
|
|
|
|
break;
|
|
|
|
case EThreadThrottle::eEfficient:
|
|
|
|
mask2 = AuHwInfo::GetCPUInfo().maskECores;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-03-16 17:12:08 +00:00
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
cpu_set_t cpuset;
|
|
|
|
CPU_ZERO(&cpuset);
|
|
|
|
|
|
|
|
AuUInt8 index {};
|
|
|
|
while (mask2.CpuBitScanForward(index, index))
|
|
|
|
{
|
|
|
|
CPU_SET(index, &cpuset);
|
|
|
|
index++;
|
|
|
|
}
|
2022-03-16 17:12:08 +00:00
|
|
|
|
2022-04-06 06:25:34 +00:00
|
|
|
if (!CPU_COUNT(&cpuset))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
if (pthread_setaffinity_np(this->handle_, sizeof(cpuset), &cpuset) != 0)
|
|
|
|
{
|
|
|
|
SysPushErrorHAL("Couldn't set affinity mask");
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
#endif
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2021-10-25 18:19:49 +00:00
|
|
|
void OSThread::OSDeatach()
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-08-06 19:50:40 +00:00
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
2022-08-02 04:52:17 +00:00
|
|
|
struct sigaction action =
|
|
|
|
{
|
|
|
|
.sa_handler = SIG_DFL
|
|
|
|
};
|
|
|
|
::sigemptyset(&action.sa_mask);
|
|
|
|
::sigaction(kSignalAbort, &action, nullptr);
|
|
|
|
#endif
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OSThread::InternalKill(bool locked)
|
|
|
|
{
|
2023-06-04 16:28:29 +00:00
|
|
|
this->PrivateUserDataClear();
|
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
if (this->terminated_)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
if (!locked)
|
|
|
|
{
|
2022-08-14 13:41:19 +00:00
|
|
|
if (!this->exitOnlyOnce_)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
if (!this->exitOnlyOnce_->TryLock())
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
HookOnExit();
|
|
|
|
|
2021-10-23 18:25:43 +00:00
|
|
|
try
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2021-10-23 18:25:43 +00:00
|
|
|
// dispatch kill callback
|
2022-03-21 07:16:12 +00:00
|
|
|
if (this->info_.callbacks)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
this->info_.callbacks->OnExit(this);
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
}
|
2021-10-23 18:25:43 +00:00
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
Debug::PrintError();
|
2022-01-24 18:37:06 +00:00
|
|
|
AuLogWarn("Couldn't deinitialize thread");
|
|
|
|
AuLogWarn("The smart thing to do at this point would be to panic");
|
|
|
|
AuLogWarn("...but we could continue");
|
|
|
|
AuLogWarn("Carrying on despite the potential for data integrity loss and memory leaks");
|
2021-10-23 18:25:43 +00:00
|
|
|
Telemetry::Mayday();
|
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
|
|
|
|
HookReleaseThreadResources();
|
|
|
|
|
2022-03-21 07:16:12 +00:00
|
|
|
if (this->terminatedSignalLs_)
|
2021-10-25 17:08:28 +00:00
|
|
|
{
|
2022-03-21 07:16:12 +00:00
|
|
|
this->terminatedSignalLs_->Set();
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
2021-10-25 17:08:28 +00:00
|
|
|
|
2023-02-11 19:37:30 +00:00
|
|
|
if (this->terminated_)
|
|
|
|
{
|
|
|
|
this->exitOnlyOnce_->Unlock();
|
|
|
|
this->terminated_->Set(); // must be set last, after which point we cannot use this!
|
|
|
|
}
|
|
|
|
|
2021-06-27 21:25:29 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-08-06 19:50:40 +00:00
|
|
|
bool OSThread::InternalKillForceNtfy()
|
|
|
|
{
|
|
|
|
if (this->terminated_)
|
|
|
|
{
|
2022-08-15 02:31:35 +00:00
|
|
|
if (this->exitOnlyOnce_)
|
|
|
|
{
|
|
|
|
this->exitOnlyOnce_->Unlock();
|
|
|
|
}
|
2022-08-06 19:50:40 +00:00
|
|
|
this->terminated_->Set();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->terminatedSignalLs_)
|
|
|
|
{
|
|
|
|
this->terminatedSignalLs_->Set();
|
|
|
|
}
|
|
|
|
|
2022-08-07 22:42:13 +00:00
|
|
|
// Great C++ ABI guys...
|
|
|
|
#if defined(AURORA_HAS_PTHREADS)
|
2022-08-14 13:41:19 +00:00
|
|
|
{
|
2022-08-15 02:31:35 +00:00
|
|
|
if (gettid() == getpid())
|
|
|
|
{
|
|
|
|
AuProcess::Exit(0);
|
|
|
|
return true;
|
|
|
|
}
|
2022-08-14 13:41:19 +00:00
|
|
|
::longjmp(env, 1);
|
|
|
|
}
|
2022-08-15 02:31:35 +00:00
|
|
|
::pthread_exit(nullptr);
|
2022-08-07 22:42:13 +00:00
|
|
|
#endif
|
2022-08-06 19:50:40 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-06-27 21:25:29 +00:00
|
|
|
void OSThread::TeminateOSContext(bool calledFromThis)
|
|
|
|
{
|
2021-09-06 10:58:08 +00:00
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
2021-06-27 21:25:29 +00:00
|
|
|
|
2022-03-16 17:12:08 +00:00
|
|
|
if (this->handle_ == INVALID_HANDLE_VALUE)
|
2021-06-27 21:25:29 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (calledFromThis)
|
|
|
|
{
|
2022-08-06 19:50:40 +00:00
|
|
|
::ExitThread(0);
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-08-06 19:50:40 +00:00
|
|
|
::TerminateThread(this->handle_, 0);
|
2021-06-27 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(AURORA_HAS_PTHREADS)
|
|
|
|
|
2022-08-06 19:50:40 +00:00
|
|
|
if (calledFromThis)
|
2022-08-02 04:52:17 +00:00
|
|
|
{
|
2022-08-15 02:31:35 +00:00
|
|
|
::longjmp(env, 1);
|
2022-08-14 22:59:48 +00:00
|
|
|
::pthread_exit(nullptr);
|
2022-08-02 04:52:17 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// pthreads is fun. thats not how unix works...
|
|
|
|
// pthread_kill(this->handle_, SIGKILL);
|
|
|
|
// remember signal inheritance is a cluster fuck & the tree will be walked
|
|
|
|
// this is giving me flashbacks to hacking in apcs into the kernel
|
|
|
|
// gross...
|
|
|
|
// let's let nptl handle it
|
|
|
|
//pthread_cancel(this->handle_);
|
|
|
|
// ...doesnt work with c++ bc catch handlers get in the way. FUCK
|
|
|
|
|
|
|
|
if (this->bSupportsAltKill)
|
|
|
|
{
|
2022-08-06 19:50:40 +00:00
|
|
|
::pthread_kill(this->handle_, kSignalAbort);
|
2022-08-02 04:52:17 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-08-06 19:50:40 +00:00
|
|
|
::pthread_cancel(this->handle_);
|
2022-08-02 04:52:17 +00:00
|
|
|
}
|
|
|
|
}
|
2021-06-27 21:25:29 +00:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
SysPanic("Not implemented");
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSThread::FreeOSContext()
|
|
|
|
{
|
2021-09-06 10:58:08 +00:00
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
2022-03-16 17:12:08 +00:00
|
|
|
AuWin32CloseHandle(this->handle_);
|
2021-06-27 21:25:29 +00:00
|
|
|
#endif
|
|
|
|
}
|
2021-10-25 17:08:28 +00:00
|
|
|
|
2022-06-11 23:52:46 +00:00
|
|
|
AuSPtr<AuLoop::ILoopSource> OSThread::AsLoopSource()
|
2021-10-25 17:08:28 +00:00
|
|
|
{
|
|
|
|
return this->terminateSignalLs_;
|
|
|
|
}
|
|
|
|
|
|
|
|
AuSPtr<IWaitable> OSThread::GetShutdownSignalWaitable()
|
|
|
|
{
|
|
|
|
return this->terminateSignal_;
|
|
|
|
}
|
|
|
|
|
2022-06-11 23:52:46 +00:00
|
|
|
AuSPtr<AuLoop::ILoopSource> OSThread::GetShutdownSignalLS()
|
2021-10-25 17:08:28 +00:00
|
|
|
{
|
|
|
|
return this->terminateSignalLs_;
|
|
|
|
}
|
2022-01-18 16:02:24 +00:00
|
|
|
|
|
|
|
void InitThreading()
|
|
|
|
{
|
2022-03-16 17:12:08 +00:00
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
2022-01-18 16:02:24 +00:00
|
|
|
AuxUlibInitialize();
|
2022-03-16 17:12:08 +00:00
|
|
|
#endif
|
2022-12-14 01:35:18 +00:00
|
|
|
|
2022-08-06 19:50:40 +00:00
|
|
|
AttachSignalKiller();
|
2022-01-18 16:02:24 +00:00
|
|
|
}
|
2022-03-21 07:16:12 +00:00
|
|
|
}
|