Commit 1120322b authored by Simon Marlow's avatar Simon Marlow
Browse files

fix a rather subtle SMP bug in anyWorkForMe()

parent 4dfe2a24
...@@ -53,19 +53,23 @@ globalWorkToDo (void) ...@@ -53,19 +53,23 @@ globalWorkToDo (void)
STATIC_INLINE rtsBool STATIC_INLINE rtsBool
anyWorkForMe( Capability *cap, Task *task ) anyWorkForMe( Capability *cap, Task *task )
{ {
// If the run queue is not empty, then we only wake up the guy who if (task->tso != NULL) {
// can run the thread at the head, even if there is some other // A bound task only runs if its thread is on the run queue of
// reason for this task to run (eg. interrupted=rtsTrue). // the capability on which it was woken up. Otherwise, we
if (!emptyRunQueue(cap)) { // can't be sure that we have the right capability: the thread
if (cap->run_queue_hd->bound == NULL) { // might be woken up on some other capability, and task->cap
return (task->tso == NULL); // could change under our feet.
} else { return (!emptyRunQueue(cap) && cap->run_queue_hd->bound == task);
return (cap->run_queue_hd->bound == task); } else {
} // A vanilla worker task runs if either (a) there is a
} else if (task->tso == NULL && !emptySparkPoolCap(cap)) { // lightweight thread at the head of the run queue, or (b)
return rtsTrue; // there are sparks to execute, or (c) there is some other
// global condition to check, such as threads blocked on
// blackholes.
return ((!emptyRunQueue(cap) && cap->run_queue_hd->bound == NULL)
|| !emptySparkPoolCap(cap)
|| globalWorkToDo());
} }
return globalWorkToDo();
} }
#endif #endif
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment