[Kernel] Poll host semaphore waits and deliver guest exceptions

Co-authored-by: Sekai <140012992+igettingit@users.noreply.github.com>
This commit is contained in:
ParantezTech 2026-10-06 13:44:48 +03:00
parent 4c9464effa
commit 4d2b7035d9
1 changed files with 35 additions and 20 deletions

View File

@ -266,40 +266,55 @@ public static class KernelSemaphoreCompatExports
var deadlineMs = hasTimeout
? Environment.TickCount64 + Math.Max(1L, timeoutUsec / 1000L)
: long.MaxValue;
lock (semaphore.Gate)
if (_traceSema)
{
if (_traceSema)
lock (semaphore.Gate)
{
TraceSemaphore(
$"wait-host-block handle=0x{handle:X8} name='{semaphore.Name}' need={needCount} " +
$"count={semaphore.Count} timeout={(timeoutAddress == 0 ? "infinite" : timeoutUsec)} {FormatCallSite(ctx)}");
$"count={semaphore.Count} timeout={(hasTimeout ? timeoutUsec : "infinite")} {FormatCallSite(ctx)}");
}
while (semaphore.Count < needCount)
}
while (true)
{
lock (semaphore.Gate)
{
if (semaphore.Count >= needCount)
{
semaphore.Count -= needCount;
semaphore.WaitingThreads = Math.Max(0, semaphore.WaitingThreads - 1);
if (_traceSema)
{
TraceSemaphore(
$"wait-host-wake handle=0x{handle:X8} name='{semaphore.Name}' need={needCount} count={semaphore.Count} {FormatCallSite(ctx)}");
}
if (timeoutAddress != 0)
{
_ = TryWriteUInt32(ctx, timeoutAddress, 0);
}
return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK);
}
var remaining = deadlineMs - Environment.TickCount64;
if (timeoutAddress != 0 && remaining <= 0)
if (hasTimeout && remaining <= 0)
{
semaphore.WaitingThreads = Math.Max(0, semaphore.WaitingThreads - 1);
_ = TryWriteUInt32(ctx, timeoutAddress, 0);
if (timeoutAddress != 0)
{
_ = TryWriteUInt32(ctx, timeoutAddress, 0);
}
return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_TIMED_OUT);
}
Monitor.Wait(semaphore.Gate, (int)Math.Min(remaining, 100));
var waitMilliseconds = hasTimeout
? (int)Math.Max(1L, Math.Min(remaining, 10L))
: 10;
Monitor.Wait(semaphore.Gate, waitMilliseconds);
}
semaphore.Count -= needCount;
semaphore.WaitingThreads = Math.Max(0, semaphore.WaitingThreads - 1);
if (_traceSema)
{
TraceSemaphore(
$"wait-host-wake handle=0x{handle:X8} name='{semaphore.Name}' need={needCount} count={semaphore.Count} {FormatCallSite(ctx)}");
}
if (timeoutAddress != 0)
{
_ = TryWriteUInt32(ctx, timeoutAddress, 0);
}
return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK);
GuestThreadExecution.Scheduler?.DeliverPendingGuestExceptionIfReady(ctx);
}
}