[*] Begin reworking Linux/POSIX PRIOs

This commit is contained in:
Reece Wilson 2023-08-23 18:08:48 +01:00 committed by J Reece Wilson
parent 9c04b31da3
commit 10e95fb5ae

View File

@ -448,8 +448,8 @@ namespace Aurora::Threading::Threads
return; return;
} }
UpdatePrio(throttle, this->prio_);
this->throttle_ = throttle; this->throttle_ = throttle;
UpdatePrio(this->throttle_, this->prio_);
AffinityPrioThrottleTickAmendECores(); AffinityPrioThrottleTickAmendECores();
} }
@ -771,7 +771,7 @@ namespace Aurora::Threading::Threads
EThreadPriority::ePrioRT, -19 EThreadPriority::ePrioRT, -19
}, },
{ {
EThreadPriority::ePrioAboveHigh, -19 EThreadPriority::ePrioAboveHigh, -15
}, },
{ {
EThreadPriority::ePrioHigh, -11 EThreadPriority::ePrioHigh, -11
@ -926,8 +926,31 @@ namespace Aurora::Threading::Threads
//#elif defined(AURORA_IS_XNU_DERIVED) //#elif defined(AURORA_IS_XNU_DERIVED)
#elif defined(AURORA_HAS_PTHREADS) #elif defined(AURORA_HAS_PTHREADS)
sched_param param {};
int policyNonRT {};
int schedA {};
int scheduler {};
#if defined(AURORA_IS_LINUX_DERIVED)
rlimit rl;
#endif
#if defined(AURORA_IS_POSIX_DERIVED)
static const auto GetPrioLevel = [](int sched, EThreadPriority prio)
{
const int *val;
if (!AuTryFind(kNiceMap, prio, val))
{
return (int)sched_get_priority_max(sched);
}
int min = sched_get_priority_min(sched);
int max = sched_get_priority_max(sched);
float f = ((1.0 - ((float(*val) + 19.0) / (19.0 + 20.0))) * float(max - min)) + float(min);
return (int)f;
};
#endif
if (!this->handle_) if (!this->handle_)
{ {
@ -936,43 +959,151 @@ namespace Aurora::Threading::Threads
if (prio == EThreadPriority::ePrioRT) if (prio == EThreadPriority::ePrioRT)
{ {
sched_param param {}; #if defined(AURORA_IS_POSIX_DERIVED)
#if defined(SCHED_RR)
param.sched_priority = sched_get_priority_max((schedA = SCHED_RR));
#else
param.sched_priority = sched_get_priority_max((schedA = SCHED_FIFO));
#endif
if (::sched_setscheduler(this->unixThreadId_, schedA, &param) == 0)
{
goto gtfo;
}
{
#if defined(AURORA_IS_LINUX_DERIVED)
if (getrlimit(RLIMIT_RTPRIO, &rl) == 0)
{
rl.rlim_max = param.sched_priority;
if (rl.rlim_max != RLIM_INFINITY)
{
AuLogWarn("We will not use RT-Kit to keep your Linux machine alive through XDG_FREEEEEEDESKTOP_HOPES_AND_DREAMS");
AuLogWarn("Hint: append '* hard rtprio unlimited' to /etc/security/limits.conf");
rl.rlim_cur = rl.rlim_max;
}
else
{
rl.rlim_cur = rl.rlim_max;
}
param.sched_priority = rl.rlim_cur;
#if defined(SCHED_RR)
if (::sched_setscheduler(this->unixThreadId_, SCHED_RR, &param) == 0)
{
goto gtfo;
}
#endif
if (::setrlimit(RLIMIT_RTPRIO, &rl) != 0)
{
AuLogWarn("We will not use RT-Kit to keep your Linux machine alive through XDG_FREEEEEEDESKTOP_HOPES_AND_DREAMS");
AuLogWarn("Hint: append '* hard rtprio unlimited' to /etc/security/limits.conf");
}
#if defined(SCHED_RR)
if (::sched_setscheduler(this->unixThreadId_, SCHED_RR, &param) == 0)
{
goto gtfo;
}
#endif
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
if (::sched_setscheduler(this->unixThreadId_, SCHED_FIFO, &param) == 0)
{
goto gtfo;
}
}
else
#endif
{
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
if (::sched_setscheduler(this->unixThreadId_, SCHED_FIFO, &param) == 0)
{
goto gtfo;
}
}
}
#else
#if defined(SCHED_RR)
param.sched_priority = sched_get_priority_min(SCHED_RR); param.sched_priority = sched_get_priority_min(SCHED_RR);
if (pthread_setschedparam(this->handle_, SCHED_RR, &param) == 0) if (pthread_setschedparam(this->handle_, SCHED_RR, &param) == 0)
{ {
return; goto gtfo;
} }
#endif
param.sched_priority = GetPrioLevel(SCHED_FIFO, prio);
if (pthread_setschedparam(this->handle_, SCHED_FIFO, &param) == 0)
{
goto gtfo;
}
#endif
// fall through on error // fall through on error
} }
else if (this->prio_ == EThreadPriority::ePrioRT) #if defined(AURORA_IS_LINUX_DERIVED)
else if (throttle == EThreadThrottle::eEfficient)
{ {
int policyNonRT = param.sched_priority = GetPrioLevel(SCHED_IDLE, prio);
if (::sched_setscheduler(this->unixThreadId_, SCHED_IDLE, &param) == 0)
{
goto gtfo;
}
// fail
return;
}
else if (this->throttle_ == EThreadThrottle::eEfficient ||
this->prio_ == EThreadPriority::ePrioRT)
#else
else if (this->prio_ == EThreadPriority::ePrioRT)
#endif
{
#if defined(AURORA_IS_POSIX_DERIVED)
policyNonRT =
#if defined(AURORA_IS_XNU_DERIVED) #if defined(AURORA_IS_XNU_DERIVED)
SCHED_FIFO; SCHED_FIFO;
#else #else
SCHED_OTHER; SCHED_OTHER;
#endif #endif
sched_param param {}; param.sched_priority = GetPrioLevel(policyNonRT, prio);
param.sched_priority = sched_get_priority_min(policyNonRT);
pthread_setschedparam(this->handle_, policyNonRT, &param); if (::sched_setscheduler(this->unixThreadId_, policyNonRT, &param) == 0)
} {
goto gtfo;
}
const int *val;
if (!AuTryFind(kNiceMap, prio, val))
{
return; return;
#endif
} }
if (auto tid = unixThreadId_)
{ {
// TODO: per thread beaviour is a linux bug scheduler = ::sched_getscheduler(this->unixThreadId_);
setpriority(PRIO_PROCESS, tid, *val); param.sched_priority = GetPrioLevel(scheduler, prio);
if (::sched_setscheduler(this->unixThreadId_, scheduler, &param) == 0)
{
goto gtfo;
}
} }
// TODO: We used to set the legacy unix niceness value here.
AuLogWarn("Couldn't set affinity");
#endif #endif
gtfo:
#if defined(AURORA_IS_LINUX_DERIVED) || defined(AURORA_IS_BSD_DERIVED) #if defined(AURORA_IS_LINUX_DERIVED) || defined(AURORA_IS_BSD_DERIVED)
switch (throttle) switch (throttle)
{ {