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 /rts/STM.c | |
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.
Diffstat (limited to 'rts/STM.c')
-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)); } |