[*] Improve arrow perf under win32

This commit is contained in:
Reece Wilson 2023-05-31 08:09:44 +01:00
parent ce424388aa
commit 45b7bc6e99
5 changed files with 93 additions and 39 deletions

View File

@ -33,6 +33,6 @@ namespace Aurora::Debug
AuUInt32 ReportStackTrace(const StackTrace &trace, const AuString &message);
void CheckErrors();
void PlatformHandleFatal(bool fatal);
void PlatformHandleFatal(bool fatal, bool bNoExit = false);
void InitDebug();
}

View File

@ -176,7 +176,7 @@ namespace Aurora::Debug
#endif
}
void PlatformHandleFatal(bool fatal)
void PlatformHandleFatal(bool fatal, bool bNoExit)
{
static bool forceFail {false};
_EXCEPTION_POINTERS ptrs;
@ -191,9 +191,12 @@ namespace Aurora::Debug
Debug::Panic();
}
if (!AuExchange(forceFail, true))
if (!bNoExit)
{
Exit::PostLevel(AuThreads::GetThread(), Aurora::Exit::ETriggerLevel::eFatalException);
if (!AuExchange(forceFail, true))
{
Exit::PostLevel(AuThreads::GetThread(), Exit::ETriggerLevel::eFatalException);
}
}
ex.ExceptionCode = 0x1337;

View File

@ -201,6 +201,7 @@ namespace Aurora::Debug
}
};
StackTrace backtrace;
{
static bool bRunOnce {};
struct ArrowEx : Grug::Arrow
@ -219,46 +220,75 @@ namespace Aurora::Debug
PlatformHandleFatal(true);
}
StackTrace backtrace;
ParseStack(ExceptionInfo->ContextRecord, backtrace);
#if defined(AU_CFG_ID_INTERNAL) || defined(AU_CFG_ID_DEBUG)
const bool kShouldPrintErrors = true;
#else
const bool kShouldPrintErrors = false;
#endif
if (pThrowInfo)
{
ReportSEH(handle, exception, pThrowInfo, handleNoCppObject, backtrace, [&](const AuString &str)
{
// Pre-submit callback -> its showtime
if ((isCritical || kShouldPrintErrors) && (minimal == 0))
{
if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut)
{
AuLogWarn("NT Exception: 0x{:x}, {}", ExceptionInfo->ExceptionRecord->ExceptionCode, str);
AuLogWarn("{}", StringifyStackTrace(backtrace));
}
}
});
}
}
catch (...)
{
}
};
empty.pCallback =[](Grug::Arrow *pBase) -> void
{
auto pEx = (ArrowEx *)pBase;
pEx->callback();
};
Grug::HurlArrow(&empty, empty.pCallback, {});
Grug::ArrowWait(&empty);
}
AuVoidFunc doReportLocal;
{
#if defined(AU_CFG_ID_INTERNAL) || defined(AU_CFG_ID_DEBUG)
const bool kShouldPrintErrors = true;
#else
const bool kShouldPrintErrors = false;
#endif
doReportLocal = [&]()
{
if (pThrowInfo)
{
ReportSEH(handle, exception, pThrowInfo, handleNoCppObject, backtrace, [&](const AuString &str)
{
// Pre-submit callback -> its showtime
if ((isCritical || kShouldPrintErrors) && (minimal == 0))
{
if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut)
{
AuLogWarn("NT Exception: 0x{:x}, {}", ExceptionInfo->ExceptionRecord->ExceptionCode, str);
AuLogWarn("{}", StringifyStackTrace(backtrace));
}
}
});
}
};
doReportLocal();
}
auto pThread = AuThreads::GetThread();
{
static bool bRunOnce {};
struct ArrowEx : Grug::Arrow
{
AuFunction<void()> callback;
};
ArrowEx empty;
empty.callback = [&]()
{
doReportLocal();
Exit::PostLevel(pThread, Aurora::Exit::ETriggerLevel::eFatalException);
try
{
if (isCritical)
{
Telemetry::Mayday();
}
if (isCritical || gRuntimeConfig.debug.bIsExceptionThrowFatal) // exception = literally anything
{
PlatformHandleFatal(true);
PlatformHandleFatal(true, true);
}
}
catch (...)

View File

@ -17,15 +17,15 @@ namespace Aurora::Grug
static AuThreadPrimitives::SpinLock gSpinLock;
static bool gDisableGrugMessages {};
void SignalSafeSleepLockYield(AuThreadPrimitives::SpinLock &lock)
void SignalSafeSleepLockYield(AuThreading::IWaitable *pLock)
{
#if defined(AURORA_IS_POSIX_DERIVED)
while (!lock.TryLock())
while (!pLock->TryLock())
{
sched_yield();
}
#else
lock.Lock();
pLock->Lock();
#endif
}
@ -39,10 +39,14 @@ namespace Aurora::Grug
pArrow->pCallback = pCallback;
pArrow->pCallbackRunaway = pCallbackRunaway;
SignalSafeSleepLockYield(pArrow->spinSemaphore);
#if defined(ARROW_NO_MUTEX)
SignalSafeSleepLockYield(&pArrow->spinSemaphore);
#else
SignalSafeSleepLockYield(pArrow->spinSemaphore2.AsPointer());
#endif
{
SignalSafeSleepLockYield(gSpinLock);
SignalSafeSleepLockYield(&gSpinLock);
while (!AuTryInsert(gReservedArrows, pArrow))
{
@ -65,13 +69,22 @@ namespace Aurora::Grug
return;
}
#if defined(ARROW_NO_MUTEX)
AU_LOCK_GUARD(arrow->spinSemaphore);
#else
AU_LOCK_GUARD(arrow->spinSemaphore2);
#endif
}
void ArrowThreadAsyncSafe(Arrow *pArrow)
{
SignalSafeSleepLockYield(pArrow->spinSemaphore);
#if defined(ARROW_NO_MUTEX)
SignalSafeSleepLockYield(&pArrow->spinSemaphore);
pArrow->spinSemaphore.Unlock();
#else
SignalSafeSleepLockYield(pArrow->spinSemaphore2.AsPointer());
pArrow->spinSemaphore2->Unlock();
#endif
}
void DequeueOneArrow()
@ -100,6 +113,7 @@ namespace Aurora::Grug
auto lastCallback = last->pCallbackRunaway;
last->spinSemaphore.Unlock();
last->spinSemaphore2->Unlock();
gReservedArrows.pop_back();

View File

@ -7,6 +7,10 @@
***/
#pragma once
#if defined(AURORA_IS_POSIX_DERIVED)
#define ARROW_NO_MUTEX
#endif
namespace Aurora::Grug
{
struct Arrow;
@ -15,6 +19,9 @@ namespace Aurora::Grug
struct Arrow
{
AuThreadPrimitives::SpinLock spinSemaphore;
#if !defined(ARROW_NO_MUTEX)
AuThreadPrimitives::Mutex spinSemaphore2;
#endif
bool bPermitRunAhead;
GrugThread thread;
GrugReport_f pCallback;