Skip to content

Commit

Permalink
[GC] Do not set delayed state unless signal is received with busy
Browse files Browse the repository at this point in the history
state entered. This allows busy state to be entered/exited without doing
an extra suspend.
  • Loading branch information
schveiguy authored and deadalnix committed Oct 23, 2024
1 parent 1a8ba56 commit a081eae
Showing 1 changed file with 20 additions and 11 deletions.
31 changes: 20 additions & 11 deletions sdlib/d/gc/tstate.d
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,28 @@ public:
}

bool onSuspendSignal() {
// Sets the status to Delayed no matter what.
auto s = state.fetchAdd(1);
assert(status(s) == SuspendState.Signaled);
auto s = state.load();

// The thread is busy, put it to sleep!
if (s != SignaledState) {
return false;
}
while (true) {
assert(status(s) == SuspendState.Signaled);

import d.gc.signal;
suspendThreadFromSignal(&this);
// If the thread isn't busy, we can suspend
// from the signal handler.
if (s == SignaledState) {
import d.gc.signal;
suspendThreadFromSignal(&this);

return true;
return true;
}

// The thread is busy, delay suspension.
auto n = s + SuspendState.Signaled;
assert(status(n) == SuspendState.Delayed);

if (state.casWeak(s, n)) {
return false;
}
}
}

void sendResumeSignal() {
Expand Down Expand Up @@ -129,7 +138,7 @@ package:
void markSuspended() {
// The status to delayed because of the fetchAdd in onSuspendSignal.
auto s = state.load();
assert(s == DelayedState || s == MustSuspendState);
assert(s == SignaledState || s == MustSuspendState);

state.store(SuspendedState);
}
Expand Down

0 comments on commit a081eae

Please sign in to comment.