mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-22 19:06:15 +08:00
[CPU] Preserve blocked leaf import waiters (#350)
This commit is contained in:
@@ -1345,8 +1345,7 @@ public sealed partial class DirectExecutionBackend
|
||||
out var blockContinuation,
|
||||
out var hasBlockContinuation,
|
||||
out var blockWakeKey,
|
||||
out var blockResumeHandler,
|
||||
out var blockWakeHandler,
|
||||
out var blockWaiter,
|
||||
out var blockDeadlineTimestamp);
|
||||
if (consumedThreadBlock &&
|
||||
TryYieldGuestThreadToHostStub(argPackPtr, dispatchIndex, returnRip, importStubEntry.Nid, blockReason))
|
||||
@@ -1357,8 +1356,7 @@ public sealed partial class DirectExecutionBackend
|
||||
GuestThreadExecution.CurrentGuestThreadHandle,
|
||||
blockContinuation,
|
||||
blockWakeKey,
|
||||
blockResumeHandler,
|
||||
blockWakeHandler,
|
||||
blockWaiter,
|
||||
blockDeadlineTimestamp);
|
||||
}
|
||||
|
||||
|
||||
@@ -443,10 +443,6 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
// Stays set through the wake transition; Resume() consumes it when the thread pumps.
|
||||
public IGuestThreadBlockWaiter? BlockWaiter { get; set; }
|
||||
|
||||
public Func<int>? BlockResumeHandler { get; set; }
|
||||
|
||||
public Func<bool>? BlockWakeHandler { get; set; }
|
||||
|
||||
public long BlockDeadlineTimestamp { get; set; }
|
||||
|
||||
public long ImportCount;
|
||||
@@ -3215,43 +3211,6 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
thread.HasBlockedContinuation = true;
|
||||
thread.BlockWakeKey = wakeKey;
|
||||
thread.BlockWaiter = waiter;
|
||||
thread.BlockResumeHandler = null;
|
||||
thread.BlockWakeHandler = null;
|
||||
thread.BlockDeadlineTimestamp = blockDeadlineTimestamp;
|
||||
TraceFocusedContinuation(
|
||||
"register",
|
||||
guestThreadHandle,
|
||||
continuation,
|
||||
wakeKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterBlockedGuestThreadContinuation(
|
||||
ulong guestThreadHandle,
|
||||
GuestCpuContinuation continuation,
|
||||
string wakeKey,
|
||||
Func<int>? resumeHandler,
|
||||
Func<bool>? wakeHandler,
|
||||
long blockDeadlineTimestamp)
|
||||
{
|
||||
if (guestThreadHandle == 0 || continuation.Rip < 65536 || continuation.Rsp == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (LockGate("RegisterBlockedContinuation"))
|
||||
{
|
||||
if (!_guestThreads.TryGetValue(guestThreadHandle, out var thread))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
thread.BlockedContinuation = continuation;
|
||||
thread.HasBlockedContinuation = true;
|
||||
thread.BlockWakeKey = wakeKey;
|
||||
thread.BlockWaiter = null;
|
||||
thread.BlockResumeHandler = resumeHandler;
|
||||
thread.BlockWakeHandler = wakeHandler;
|
||||
thread.BlockDeadlineTimestamp = blockDeadlineTimestamp;
|
||||
TraceFocusedContinuation(
|
||||
"register",
|
||||
@@ -3567,11 +3526,10 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
|
||||
owner.State = GuestThreadRunState.Blocked;
|
||||
owner.BlockReason = callbackReason ?? reason;
|
||||
if (owner.BlockWakeHandler is not null && owner.BlockWakeHandler())
|
||||
if (owner.BlockWaiter is not null && owner.BlockWaiter.TryWake())
|
||||
{
|
||||
owner.State = GuestThreadRunState.Ready;
|
||||
owner.BlockReason = null;
|
||||
owner.BlockWakeHandler = null;
|
||||
owner.BlockDeadlineTimestamp = 0;
|
||||
}
|
||||
}
|
||||
@@ -3583,7 +3541,7 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
}
|
||||
|
||||
GuestCpuContinuation continuation = default;
|
||||
Func<int>? resumeHandler = null;
|
||||
IGuestThreadBlockWaiter? blockWaiter = null;
|
||||
while (!ActiveForcedGuestExit)
|
||||
{
|
||||
WakeExpiredBlockedGuestThreads();
|
||||
@@ -3604,9 +3562,8 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
owner.BlockedContinuation = default;
|
||||
owner.HasBlockedContinuation = false;
|
||||
owner.BlockWakeKey = null;
|
||||
resumeHandler = owner.BlockResumeHandler;
|
||||
owner.BlockResumeHandler = null;
|
||||
owner.BlockWakeHandler = null;
|
||||
blockWaiter = owner.BlockWaiter;
|
||||
owner.BlockWaiter = null;
|
||||
owner.BlockDeadlineTimestamp = 0;
|
||||
owner.BlockReason = null;
|
||||
owner.State = GuestThreadRunState.Running;
|
||||
@@ -3629,9 +3586,9 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resumeHandler is not null)
|
||||
if (blockWaiter is not null)
|
||||
{
|
||||
continuation = continuation with { Rax = unchecked((ulong)(long)resumeHandler()) };
|
||||
continuation = continuation with { Rax = unchecked((ulong)(long)blockWaiter.Resume()) };
|
||||
}
|
||||
if (_logGuestThreads)
|
||||
{
|
||||
@@ -3844,8 +3801,7 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
bool savedHasBlockedContinuation;
|
||||
GuestCpuContinuation savedBlockedContinuation;
|
||||
string? savedBlockWakeKey;
|
||||
Func<int>? savedBlockResumeHandler;
|
||||
Func<bool>? savedBlockWakeHandler;
|
||||
IGuestThreadBlockWaiter? savedBlockWaiter;
|
||||
long savedBlockDeadlineTimestamp;
|
||||
ulong exceptionStackBase;
|
||||
lock (_guestThreadGate)
|
||||
@@ -3981,8 +3937,7 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
savedHasBlockedContinuation = target.HasBlockedContinuation;
|
||||
savedBlockedContinuation = target.BlockedContinuation;
|
||||
savedBlockWakeKey = target.BlockWakeKey;
|
||||
savedBlockResumeHandler = target.BlockResumeHandler;
|
||||
savedBlockWakeHandler = target.BlockWakeHandler;
|
||||
savedBlockWaiter = target.BlockWaiter;
|
||||
savedBlockDeadlineTimestamp = target.BlockDeadlineTimestamp;
|
||||
|
||||
target.State = GuestThreadRunState.Running;
|
||||
@@ -3992,8 +3947,7 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
target.HasBlockedContinuation = false;
|
||||
target.BlockedContinuation = default;
|
||||
target.BlockWakeKey = null;
|
||||
target.BlockResumeHandler = null;
|
||||
target.BlockWakeHandler = null;
|
||||
target.BlockWaiter = null;
|
||||
target.BlockDeadlineTimestamp = 0;
|
||||
}
|
||||
|
||||
@@ -4041,8 +3995,7 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
target.HasBlockedContinuation = savedHasBlockedContinuation;
|
||||
target.BlockedContinuation = savedBlockedContinuation;
|
||||
target.BlockWakeKey = savedBlockWakeKey;
|
||||
target.BlockResumeHandler = savedBlockResumeHandler;
|
||||
target.BlockWakeHandler = savedBlockWakeHandler;
|
||||
target.BlockWaiter = savedBlockWaiter;
|
||||
target.BlockDeadlineTimestamp = savedBlockDeadlineTimestamp;
|
||||
|
||||
// A condition/event wake can arrive while the parked thread is
|
||||
@@ -4052,12 +4005,11 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
||||
// pthread wait remains parked forever after a GC suspension races it.
|
||||
if (target.State == GuestThreadRunState.Blocked &&
|
||||
target.HasBlockedContinuation &&
|
||||
target.BlockWakeHandler is not null &&
|
||||
target.BlockWakeHandler())
|
||||
target.BlockWaiter is not null &&
|
||||
target.BlockWaiter.TryWake())
|
||||
{
|
||||
target.State = GuestThreadRunState.Ready;
|
||||
target.BlockReason = null;
|
||||
target.BlockWakeHandler = null;
|
||||
target.BlockDeadlineTimestamp = 0;
|
||||
_readyGuestThreads.Enqueue(target);
|
||||
Interlocked.Increment(ref _readyGuestThreadCount);
|
||||
|
||||
@@ -398,27 +398,6 @@ public static class GuestThreadExecution
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TryConsumeCurrentThreadBlock(
|
||||
out string reason,
|
||||
out GuestCpuContinuation continuation,
|
||||
out bool hasContinuation,
|
||||
out string wakeKey,
|
||||
out Func<int>? resumeHandler,
|
||||
out Func<bool>? wakeHandler,
|
||||
out long blockDeadlineTimestamp)
|
||||
{
|
||||
var consumed = TryConsumeCurrentThreadBlock(
|
||||
out reason,
|
||||
out continuation,
|
||||
out hasContinuation,
|
||||
out wakeKey,
|
||||
out var waiter,
|
||||
out blockDeadlineTimestamp);
|
||||
resumeHandler = waiter is null ? null : waiter.Resume;
|
||||
wakeHandler = waiter is null ? null : waiter.TryWake;
|
||||
return consumed;
|
||||
}
|
||||
|
||||
public static long ComputeDeadlineTimestamp(TimeSpan timeout)
|
||||
{
|
||||
if (timeout <= TimeSpan.Zero)
|
||||
|
||||
Reference in New Issue
Block a user