When waking up thread blocked on TVars, wake oldest first (#2319)
authorJosef Svenningsson <josef.svenningsson@gmail.com>
Fri, 10 Oct 2008 15:03:22 +0000 (15:03 +0000)
committerJosef Svenningsson <josef.svenningsson@gmail.com>
Fri, 10 Oct 2008 15:03:22 +0000 (15:03 +0000)
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.

rts/STM.c

index c271a25..b5dcc54 100644 (file)
--- 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));
     }