diff options
author | Josef Svenningsson <josef.svenningsson@gmail.com> | 2008-10-10 15:03:22 +0000 |
---|---|---|
committer | Josef Svenningsson <josef.svenningsson@gmail.com> | 2008-10-10 15:03:22 +0000 |
commit | a970a3775856642e6d3690b5421e7dcb3e420d36 (patch) | |
tree | 80c7621116e716f16c093a7f59ca5638fe0c8fb1 | |
parent | b69843467459d43168519ced8d0cf45227c4c7be (diff) | |
download | haskell-a970a3775856642e6d3690b5421e7dcb3e420d36.tar.gz |
When waking up thread blocked on TVars, wake oldest first (#2319)
StgTVarWatchQueue contains the threads blocked on a TVar in order
youngest first. The list has to be traversed backwards to unpark the threads
oldest first.
This improves the fairness when using STM in some situations.
-rw-r--r-- | rts/STM.c | 12 |
1 files changed, 10 insertions, 2 deletions
@@ -389,9 +389,17 @@ static void unpark_tso(Capability *cap, StgTSO *tso) { static void unpark_waiters_on(Capability *cap, StgTVar *s) { StgTVarWatchQueue *q; TRACE("unpark_waiters_on tvar=%p", s); - for (q = s -> first_watch_queue_entry; - q != END_STM_WATCH_QUEUE; + StgTVarWatchQueue *trail; + // unblock TSOs in reverse order, to be a bit fairer (#2319) + for (q = s -> first_watch_queue_entry, trail = q; + q != END_STM_WATCH_QUEUE; q = q -> next_queue_entry) { + trail = q; + } + q = trail; + for (; + q != END_STM_WATCH_QUEUE; + q = q -> prev_queue_entry) { if (watcher_is_tso(q)) { unpark_tso(cap, (StgTSO *)(q -> closure)); } |