summaryrefslogtreecommitdiff
path: root/rts/STM.c
diff options
context:
space:
mode:
authorJosef Svenningsson <josef.svenningsson@gmail.com>2008-10-10 15:03:22 +0000
committerJosef Svenningsson <josef.svenningsson@gmail.com>2008-10-10 15:03:22 +0000
commita970a3775856642e6d3690b5421e7dcb3e420d36 (patch)
tree80c7621116e716f16c093a7f59ca5638fe0c8fb1 /rts/STM.c
parentb69843467459d43168519ced8d0cf45227c4c7be (diff)
downloadhaskell-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.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/rts/STM.c b/rts/STM.c
index c271a25d3c..b5dcc54884 100644
--- a/rts/STM.c
+++ b/rts/STM.c
@@ -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));
}