[*] 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;
}
UpdatePrio(throttle, this->prio_);
this->throttle_ = throttle;
UpdatePrio(this->throttle_, this->prio_);
AffinityPrioThrottleTickAmendECores();
}
@ -771,7 +771,7 @@ namespace Aurora::Threading::Threads
EThreadPriority::ePrioRT, -19
},
{
EThreadPriority::ePrioAboveHigh, -19
EThreadPriority::ePrioAboveHigh, -15
},
{
EThreadPriority::ePrioHigh, -11
@ -926,8 +926,31 @@ namespace Aurora::Threading::Threads
//#elif defined(AURORA_IS_XNU_DERIVED)
#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_)
{
@ -936,43 +959,151 @@ namespace Aurora::Threading::Threads
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);
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
}
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)
SCHED_FIFO;
#else
SCHED_OTHER;
#endif
sched_param param {};
param.sched_priority = sched_get_priority_min(policyNonRT);
pthread_setschedparam(this->handle_, policyNonRT, &param);
param.sched_priority = GetPrioLevel(policyNonRT, prio);
if (::sched_setscheduler(this->unixThreadId_, policyNonRT, &param) == 0)
{
goto gtfo;
}
const int *val;
if (!AuTryFind(kNiceMap, prio, val))
{
return;
#endif
}
if (auto tid = unixThreadId_)
{
// TODO: per thread beaviour is a linux bug
setpriority(PRIO_PROCESS, tid, *val);
scheduler = ::sched_getscheduler(this->unixThreadId_);
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
gtfo:
#if defined(AURORA_IS_LINUX_DERIVED) || defined(AURORA_IS_BSD_DERIVED)
switch (throttle)
{