[commit: ghc] ghc-lwc2: Fixed an error with sleepCapability. tso->is_sleeping variable is set to 0 if the thread does not actually block on the STM. (77dff34)
Sivaramakrishnan Krishnamoorthy Chandrasekaran
t-sichan at microsoft.com
Tue Apr 30 02:16:20 CEST 2013
Repository : http://darcs.haskell.org/ghc.git/
On branch : ghc-lwc2
https://github.com/ghc/ghc/commit/77dff342f1c5361378ba17f2ce5d0c60c75ec3be
>---------------------------------------------------------------
commit 77dff342f1c5361378ba17f2ce5d0c60c75ec3be
Author: KC Sivaramakrishnan <chandras at cs.purdue.edu>
Date: Mon Apr 29 12:43:44 2013 -0400
Fixed an error with sleepCapability. tso->is_sleeping variable is set to 0 if the thread does not actually block on the STM.
>---------------------------------------------------------------
libraries/base/GHC/Event/TimerManager.hs | 18 ++++++++++++++++++
rts/PrimOps.cmm | 10 +++++++++-
rts/Threads.c | 6 +++++-
tests/Benchmarks/Sieve/MVarList.hs | 4 ++--
tests/Benchmarks/Sieve/sieve-TMVar.hs | 1 -
5 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/libraries/base/GHC/Event/TimerManager.hs b/libraries/base/GHC/Event/TimerManager.hs
index dd55355..5ba82a4 100644
--- a/libraries/base/GHC/Event/TimerManager.hs
+++ b/libraries/base/GHC/Event/TimerManager.hs
@@ -54,6 +54,10 @@ import GHC.Event.Control
import GHC.Event.Internal (Backend, Event, evtRead, Timeout(..))
import GHC.Event.Unique (Unique, UniqueSource, newSource, newUnique)
import System.Posix.Types (Fd)
+import System.Posix.Internals hiding (FD)
+
+import Foreign.Safe (castPtr)
+import Foreign.C
import qualified GHC.Event.Internal as I
import qualified GHC.Event.PSQ as Q
@@ -124,6 +128,20 @@ data TimerManager = TimerManager
------------------------------------------------------------------------
-- Creation
+c_DEBUG_DUMP :: Bool
+c_DEBUG_DUMP = True
+
+debugIO :: String -> IO ()
+debugIO s
+ | c_DEBUG_DUMP
+ = do _ <- withCStringLen (s ++ "\n") $
+ \(p, len) -> c_write 1 (castPtr p) (fromIntegral len)
+ return ()
+ | otherwise = return ()
+
+------------------------------------------------------------------------
+-- Creation
+
handleControlEvent :: TimerManager -> Fd -> Event -> IO ()
handleControlEvent mgr fd _evt = do
msg <- readControlMessage (emControl mgr) fd
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index 2eee6c2..850fef9 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -633,7 +633,7 @@ again: MAYBE_GC(again);
}
}
}
- })
+ } )
#endif
@@ -1375,6 +1375,14 @@ retry_pop_stack:
jump stg_block_stmwait [R3];
} else {
// Transaction was not valid: retry immediately
+
+ /* KC thread is no longer considered sleeping since the transaction is being
+ * retried. See stg_sleepCapability. The correct solution is to make the
+ * tso->is_sleeping variable into a TVar. This would avoid having to reason
+ * explicitly about the states being manipulated.
+ */
+ StgTSO_is_sleeping (CurrentTSO) = 0::I32;
+
("ptr" trec) = ccall stmStartTransaction(MyCapability() "ptr", outer "ptr");
StgTSO_trec(CurrentTSO) = trec;
Sp = frame;
diff --git a/rts/Threads.c b/rts/Threads.c
index e1fec18..c30b3da 100644
--- a/rts/Threads.c
+++ b/rts/Threads.c
@@ -314,7 +314,11 @@ tryWakeupThread (Capability *cap, StgTSO *tso)
}
case BlockedOnBlackHole:
- if (hasHaskellScheduler (tso)) //Note: Upcall threads do not have a user-level scheduler
+ if (tso->is_sleeping) {
+ tso->is_sleeping = 0;
+ goto unblock2;
+ }
+ else if (hasHaskellScheduler (tso)) //Note: Upcall threads do not have a user-level scheduler
goto unblock1;
else
goto unblock2;
diff --git a/tests/Benchmarks/Sieve/MVarList.hs b/tests/Benchmarks/Sieve/MVarList.hs
index 106bafd..10ac5f9 100644
--- a/tests/Benchmarks/Sieve/MVarList.hs
+++ b/tests/Benchmarks/Sieve/MVarList.hs
@@ -62,8 +62,8 @@ deque (TwoListQueue !front !back) =
x:tl -> (TwoListQueue tl back, Just x)
newtype MVar a = MVar (PVar (MVPState a)) deriving (Eq)
-data MVPState a = Full a (TwoListQueue (a, PTM()))
- | Empty (TwoListQueue (IORef a, PTM()))
+data MVPState a = Full a {-# UNPACK #-} !(TwoListQueue (a, PTM()))
+ | Empty {-# UNPACK #-} !(TwoListQueue (IORef a, PTM()))
_INL_(newMVar)
diff --git a/tests/Benchmarks/Sieve/sieve-TMVar.hs b/tests/Benchmarks/Sieve/sieve-TMVar.hs
index dd000a0..a8df0c2 100644
--- a/tests/Benchmarks/Sieve/sieve-TMVar.hs
+++ b/tests/Benchmarks/Sieve/sieve-TMVar.hs
@@ -43,7 +43,6 @@ main = do
linkFilter :: TMVar Int -> TMVar Int -> IO (TMVar Int)
linkFilter mIn mOut = do
prime <- atomically $ takeTMVar mIn
- traceIO $ show prime
putStrLn $ show prime
forkIO $ primeFilter mIn mOut prime
return mOut
More information about the ghc-commits
mailing list