[Threading] Implement priority boost on wake

When a thread wakes from a kernel wait, the Xenon scheduler boosts its
effective priority by the increment passed to the signaling call
(KeSetEvent, KeReleaseSemaphore, KeReleaseMutant). The boost is clamped
to the per-thread max_dynamic_priority cap, respects the guest
boost_disabled flag, and is drained on the next quantum expiry.
Guest KTHREAD priority fields are now initialized from parent process
defaults, and the previously unknown fields involved have been renamed
to match their identified purpose.
This commit is contained in:
Herman S.
2026-04-11 17:05:05 +09:00
parent b3d8a21b72
commit 65b74819aa
9 changed files with 127 additions and 47 deletions

View File

@@ -207,10 +207,9 @@ X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
switch (result) {
case xe::threading::WaitResult::kSuccess:
case xe::threading::WaitResult::kUserCallback: {
// Thread actually blocked and woke — reset priority to base.
auto current_thread = XThread::GetCurrentThread();
if (current_thread) {
current_thread->ResetQuantum();
current_thread->BoostOnWake(priority_increment());
}
if (result == xe::threading::WaitResult::kSuccess) {
WaitCallback();
@@ -245,7 +244,7 @@ X_STATUS XObject::SignalAndWait(XObject* signal_object, XObject* wait_object,
case xe::threading::WaitResult::kUserCallback: {
auto current_thread = XThread::GetCurrentThread();
if (current_thread) {
current_thread->ResetQuantum();
current_thread->BoostOnWake(wait_object->priority_increment());
}
if (result == xe::threading::WaitResult::kSuccess) {
wait_object->WaitCallback();
@@ -280,12 +279,14 @@ X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects,
: std::chrono::milliseconds::max();
X_STATUS status;
uint32_t boost_increment = 0;
if (wait_type) {
auto result = xe::threading::WaitAny(wait_handles, count,
alertable ? true : false, timeout_ms);
switch (result.first) {
case xe::threading::WaitResult::kSuccess:
objects[result.second]->WaitCallback();
boost_increment = objects[result.second]->priority_increment();
status = X_STATUS(result.second);
break;
case xe::threading::WaitResult::kUserCallback:
@@ -310,6 +311,10 @@ X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects,
case xe::threading::WaitResult::kSuccess:
for (uint32_t i = 0; i < count; i++) {
objects[i]->WaitCallback();
// Use the largest increment among the signaled objects.
if (objects[i]->priority_increment() > boost_increment) {
boost_increment = objects[i]->priority_increment();
}
}
status = X_STATUS_SUCCESS;
break;
@@ -328,12 +333,13 @@ X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects,
}
}
// Only reset quantum if the thread actually blocked (not on timeout/failure).
// Apply priority boost if the thread actually blocked (not on
// timeout/failure).
if (status != X_STATUS_TIMEOUT && status != X_STATUS_UNSUCCESSFUL &&
status != X_STATUS_ABANDONED_WAIT_0) {
auto current_thread = XThread::GetCurrentThread();
if (current_thread) {
current_thread->ResetQuantum();
current_thread->BoostOnWake(boost_increment);
}
}
return status;