64 lines
1.3 KiB
C++
64 lines
1.3 KiB
C++
|
/***
|
||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||
|
|
||
|
File: SMPYield.hpp
|
||
|
Date: 2023-3-12
|
||
|
Author: Reece
|
||
|
***/
|
||
|
#pragma once
|
||
|
|
||
|
namespace Aurora::Threading::Primitives
|
||
|
{
|
||
|
static auline void SMPPause()
|
||
|
{
|
||
|
#if (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86))
|
||
|
_mm_pause();
|
||
|
#elif defined(AURORA_ARCH_ARM)
|
||
|
#if defined(AURORA_COMPILER_GCC)
|
||
|
asm volatile("yield");
|
||
|
#else
|
||
|
__yield();
|
||
|
#endif
|
||
|
#else
|
||
|
// TODO: your platform here
|
||
|
AuThreading::ContextYield();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
bool auline YieldToSharedCore(long spin, T callback)
|
||
|
{
|
||
|
if (callback())
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
int loops = (1 << spin);
|
||
|
while (loops > 0)
|
||
|
{
|
||
|
SMPPause();
|
||
|
|
||
|
loops -= 1;
|
||
|
|
||
|
if (callback())
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return callback();
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
bool auline DoTryIf(T callback)
|
||
|
{
|
||
|
if (gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized)
|
||
|
{
|
||
|
return YieldToSharedCore(gRuntimeConfig.threadingConfig.uSpinLoopPowerA, callback);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return callback();
|
||
|
}
|
||
|
}
|
||
|
}
|