[commit: ghc] ghc-lwc2: Disabled labelling upcall threads. The hashtable used for storing the meta-data appears not to be thread-safe. Setting tso->is_sleeping to false just before a thread runs in the Scheudler (under run_thread label in the main scheduler loop). This avoids errors associated with sleeping threads (see stg_sleepCapability for more info). (8dc2f20)

Sivaramakrishnan Krishnamoorthy Chandrasekaran t-sichan at microsoft.com
Tue Apr 30 02:16:23 CEST 2013


Repository : http://darcs.haskell.org/ghc.git/

On branch  : ghc-lwc2

https://github.com/ghc/ghc/commit/8dc2f205559a9abc201f7c1b933bc85daa69a73b

>---------------------------------------------------------------

commit 8dc2f205559a9abc201f7c1b933bc85daa69a73b
Author: KC Sivaramakrishnan <chandras at cs.purdue.edu>
Date:   Mon Apr 29 14:01:10 2013 -0400

    Disabled labelling upcall threads. The hashtable used for storing the meta-data appears not to be thread-safe. Setting tso->is_sleeping to false just before a thread runs in the Scheudler (under run_thread label in the main scheduler loop). This avoids errors associated with sleeping threads (see stg_sleepCapability for more info).

>---------------------------------------------------------------

 rts/Capability.c                        | 3 +--
 rts/Schedule.c                          | 2 ++
 rts/Threads.c                           | 6 +++---
 tests/Benchmarks/Sieve/Makefile         | 2 +-
 tests/Benchmarks/Sieve/sieve-vanilla.hs | 7 +++++--
 5 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/rts/Capability.c b/rts/Capability.c
index f92a3af..9be497d 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -389,9 +389,8 @@ moreCapabilities (nat from USED_IF_THREADS, nat to USED_IF_THREADS)
 void initUpcallThreadOnCapability (Capability* cap) {
   cap->upcall_thread = createThread (cap, RtsFlags.GcFlags.initialStkSize);
   cap->upcall_thread->what_next = ThreadComplete; //Default state of upcall
-  //thread is ThreadComplete
   cap->upcall_thread->is_upcall_thread = rtsTrue;
-  labelThread (cap, cap->upcall_thread, "Upcall thread");
+  //labelThread (cap, cap->upcall_thread, "Upcall thread");
   debugTrace (DEBUG_sched, "allocated upcall thread (%d) for capability %d",
               cap->upcall_thread->id, cap->no);
 }
diff --git a/rts/Schedule.c b/rts/Schedule.c
index 8be1390..a626ef7 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -438,6 +438,8 @@ run_thread:
         ASSERT_FULL_CAPABILITY_INVARIANTS(cap,task);
         ASSERT(t->cap == cap);
         ASSERT(t->bound ? t->bound->task->cap == cap : 1);
+        t->is_sleeping = rtsFalse;
+
 
         prev_what_next = t->what_next;
 
diff --git a/rts/Threads.c b/rts/Threads.c
index c30b3da..703bb8d 100644
--- a/rts/Threads.c
+++ b/rts/Threads.c
@@ -109,7 +109,7 @@ createThread(Capability *cap, W_ size)
   tso->flags = 0;
   tso->dirty = 1;
   tso->is_upcall_thread = 0;
-  tso->is_sleeping = 0;
+  tso->is_sleeping = rtsFalse;
   tso->_link = END_TSO_QUEUE;
 
   tso->saved_errno = 0;
@@ -315,7 +315,7 @@ tryWakeupThread (Capability *cap, StgTSO *tso)
 
     case BlockedOnBlackHole:
       if (tso->is_sleeping) {
-        tso->is_sleeping = 0;
+        tso->is_sleeping = rtsFalse;
         goto unblock2;
       }
       else if (hasHaskellScheduler (tso)) //Note: Upcall threads do not have a user-level scheduler
@@ -325,7 +325,7 @@ tryWakeupThread (Capability *cap, StgTSO *tso)
 
     case BlockedOnSTM:
       if (tso->is_sleeping) {
-        tso->is_sleeping = 0;
+        tso->is_sleeping = rtsFalse;
         goto unblock2;
       }
       else if (hasHaskellScheduler (tso))
diff --git a/tests/Benchmarks/Sieve/Makefile b/tests/Benchmarks/Sieve/Makefile
index 96e57da..d662f80 100644
--- a/tests/Benchmarks/Sieve/Makefile
+++ b/tests/Benchmarks/Sieve/Makefile
@@ -3,7 +3,7 @@ TARGET := sieve-vanilla.bin sieve-lwc.bin sieve-TMVar.bin sieve-vanilla-TMVar.bi
 include ../../config.mk
 
 TOP := ../../../
-GHC_OPTS_EXTRA=-O2 -threaded -XBangPatterns -XCPP -XGeneralizedNewtypeDeriving -funbox-strict-fields -optc-O3 -debug
+GHC_OPTS_EXTRA=-O2 -threaded -XBangPatterns -XCPP -XGeneralizedNewtypeDeriving -funbox-strict-fields -optc-O3
 
 PROFILE_FLAGS := -DPROFILE_ENABLED -prof -auto-all -fprof-auto
 
diff --git a/tests/Benchmarks/Sieve/sieve-vanilla.hs b/tests/Benchmarks/Sieve/sieve-vanilla.hs
index 54af576..ef6cc94 100644
--- a/tests/Benchmarks/Sieve/sieve-vanilla.hs
+++ b/tests/Benchmarks/Sieve/sieve-vanilla.hs
@@ -1,6 +1,6 @@
 import Control.Concurrent
 import Control.Monad
-
+import GHC.Conc
 import System.Environment
 
 -- Map over [2..] (2 until infinity), putting the value in mOut. The putting operation will block until
@@ -10,7 +10,10 @@ generate mOut = mapM_ (putMVar mOut) [2..]
 
 -- Take a value from mIn, divide it by a prime, if the remainder is not 0, put the value in mOut.
 primeFilter :: MVar Int -> MVar Int -> Int -> IO ()
-primeFilter mIn mOut prime = forever $ do
+primeFilter mIn mOut prime = do
+  tid <- myThreadId
+  labelThread tid $ "ThrPrime:" ++ show prime
+  forever $ do
     i <- takeMVar mIn
     when (i `mod` prime /= 0) (putMVar mOut i)
 





More information about the ghc-commits mailing list