Thread migration race?
It's not at all clear why migrateThread
and tryWakeupThread
are safe. Specifically, tryWakeupThread
looks at tso->cap
of threads that it may or may not own. If it does not own the thread it (that is, the thread isn't on the local capability's run queue) then it will send a TRY_WAKEUP
message to the owning capability. However, tryWakeupThread
, which may be called from any number of places, may set tso->cap
concurrently. It is then possible that tryWakeupThread
will read the old value of tso->cap
and send the wakeup message to the capability which the TSO was migrated away from.
This is often okay as executeMessage
's logic for handling TRY_WAKEUP
messages simply calls back into tryWakeupThread
, which will send another message if the local capability no longer owns the TSO.
However, what happens if the TSO was migrated away from the local capability? That is, we have
- Capability A owns Thread X
- Capability B calls
migrateThread(A, X, C)
- Capability A calls
tryWakeupThread(A, X)
, adding X to its run queue and racing with B to modifyX->why_blocked