New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runtime: signal_recv can throw spuriously #4383
Labels
Milestone
Comments
it wont' help. consider all vars are initially = 0 signal_recv sets kick=1 sigsend sets a signal bit, kicking=1, kick=0, and signals note signal_recv discovers new signal bit and return on the next round signal_recv clears note, sets kick=1 again and blocks on note at this point it deadlocks, because kicking=1 so nobody will wake it |
the more separate non-atomic state, states and branches we have, the more tricky it becomes to reason about it I am thinking about something along the lines of: Note note; uint32 mask[...]; uint32 state; // can be in 3 states: (1) no signals, no waiter, (2) have signals, (3) have waiter. sigsend() { set bit in mask in a CAS loop { if state==0 -> state=HAVE_SIGNALS if state==HAVE_SIGNALS -> do nothing is state==HAVE_WAITER -> state=HAVE_SIGNALS, signal note } } signal_recv() { for(;;) { the same logic with local copy in a CAS loop { if state==0 -> state=HAVE_WAITER, block on note, clear note if state==HAVE_SIGNALS -> state=0, recheck mask is state==HAVE_WAITER -> throw } } } This brings 2 simplifications: (1) we have both conditions in a single var (have signals, have waiters), so it's slightly simpler to reason, (2) if signal_recv sets state=HAVE_WAITER, then it always blocks after that. |
I am on it. In a stress test is actually crashes in a second. Owner changed to @dvyukov. Status changed to Accepted. |
This issue was closed by revision 91484c6. Status changed to Fixed. |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
The text was updated successfully, but these errors were encountered: