[GHC] #367: Infinite loops can hang Concurrent Haskell
GHC
cvs-ghc at haskell.org
Sat Sep 22 01:03:33 CEST 2012
#367: Infinite loops can hang Concurrent Haskell
------------------------------------------+---------------------------------
Reporter: simonpj | Owner: ezyang
Type: bug | Status: new
Priority: lowest | Milestone: _|_
Component: Compiler | Version: 6.4.1
Resolution: None | Keywords: scheduler allocation
Os: Unknown/Multiple | Architecture: Unknown/Multiple
Failure: Incorrect result at runtime | Difficulty: Unknown
Testcase: | Blockedby:
Blocking: | Related:
------------------------------------------+---------------------------------
Comment(by ezyang):
Here is a variant of the patch that only does heap checks when not
returning (since it's not possible to "infinitely return".) We do much
better on runtime and binary size; maybe good enough to ship by default!
{{{
diff --git a/compiler/codeGen/StgCmmHeap.hs
b/compiler/codeGen/StgCmmHeap.hs
index fb37391..4c53bc2 100644
--- a/compiler/codeGen/StgCmmHeap.hs
+++ b/compiler/codeGen/StgCmmHeap.hs
@@ -371,7 +371,7 @@ entryHeapCheck cl_info nodeSet arity args code
loop_id <- newLabelC
emitLabel loop_id
- heapCheck True (gc_call updfr_sz <*> mkBranch loop_id) code
+ heapCheck True True (gc_call updfr_sz <*> mkBranch loop_id) code
{-
-- This code is slightly outdated now and we could easily keep the
above
@@ -461,7 +461,7 @@ cannedGCReturnsTo :: Bool -> CmmExpr -> [LocalReg] ->
Label -> ByteOff
cannedGCReturnsTo cont_on_stack gc regs lret off code
= do dflags <- getDynFlags
updfr_sz <- getUpdFrameOff
- heapCheck False (gc_call dflags gc updfr_sz) code
+ heapCheck False False (gc_call dflags gc updfr_sz) code
where
reg_exprs = map (CmmReg . CmmLocal) regs
-- Note [stg_gc arguments]
@@ -476,7 +476,7 @@ genericGC code
lretry <- newLabelC
emitLabel lretry
call <- mkCall generic_gc (GC, GC) [] [] updfr_sz (0,[])
- heapCheck False (call <*> mkBranch lretry) code
+ heapCheck False True (call <*> mkBranch lretry) code
cannedGCEntryPoint :: DynFlags -> [LocalReg] -> Maybe CmmExpr
cannedGCEntryPoint dflags regs
@@ -524,22 +524,23 @@ mkGcLabel :: String -> CmmExpr
mkGcLabel s = CmmLit (CmmLabel (mkCmmCodeLabel rtsPackageId (fsLit s)))
-------------------------------
-heapCheck :: Bool -> CmmAGraph -> FCode a -> FCode a
-heapCheck checkStack do_gc code
+heapCheck :: Bool -> Bool -> CmmAGraph -> FCode a -> FCode a
+heapCheck checkStack checkYield do_gc code
= getHeapUsage $ \ hpHw ->
-- Emit heap checks, but be sure to do it lazily so
-- that the conditionals on hpHw don't cause a black hole
- do { codeOnly $ do_checks checkStack hpHw do_gc
+ do { codeOnly $ do_checks checkStack checkYield hpHw do_gc
; tickyAllocHeap hpHw
; doGranAllocate hpHw
; setRealHp hpHw
; code }
do_checks :: Bool -- Should we check the stack?
+ -> Bool -- Should we check for preemption?
-> WordOff -- Heap headroom
-> CmmAGraph -- What to do on failure
-> FCode ()
-do_checks checkStack alloc do_gc = do
+do_checks checkStack checkYield alloc do_gc = do
dflags <- getDynFlags
let
alloc_lit = mkIntExpr dflags (alloc * wORD_SIZE dflags) -- Bytes
@@ -557,15 +558,22 @@ do_checks checkStack alloc do_gc = do
hp_oflo = CmmMachOp (mo_wordUGt dflags)
[CmmReg hpReg, CmmReg (CmmGlobal HpLim)]
+ -- Yielding if HpLim == 0
+ yielding = CmmMachOp (mo_wordEq dflags)
+ [CmmReg (CmmGlobal HpLim), CmmLit (zeroCLit
dflags)]
+
alloc_n = mkAssign (CmmGlobal HpAlloc) alloc_lit
gc_id <- newLabelC
when checkStack $ do
emit =<< mkCmmIfGoto sp_oflo gc_id
- when (alloc /= 0) $ do
- emitAssign hpReg bump_hp
- emit =<< mkCmmIfThen hp_oflo (alloc_n <*> mkBranch gc_id)
+ if (alloc /= 0)
+ then do
+ emitAssign hpReg bump_hp
+ emit =<< mkCmmIfThen hp_oflo (alloc_n <*> mkBranch gc_id)
+ else do
+ emit =<< mkCmmIfGoto yielding gc_id
emitOutOfLine gc_id $
do_gc -- this is expected to jump back somewhere
}}}
{{{
--------------------------------------------------------------------------------
Program Size Allocs Runtime Elapsed TotalMem
--------------------------------------------------------------------------------
anna +5.5% +0.0% 0.13 0.13 +0.0%
ansi +6.0% +0.0% 0.00 0.00 +0.0%
atom +6.0% +0.0% +0.0% +0.3% +0.0%
awards +6.0% +0.0% 0.00 0.00 +0.0%
banner +5.9% +0.0% 0.00 0.00 +0.0%
bernouilli +6.0% +0.0% +0.3% +0.3% +0.0%
boyer +5.9% +0.0% 0.06 0.06 +0.0%
boyer2 +5.9% +0.0% 0.01 0.01 +0.0%
bspt +5.8% +0.0% 0.02 0.02 +0.0%
cacheprof +5.7% -0.1% -0.3% -0.3% +0.0%
calendar +6.0% +0.0% 0.00 0.00 +0.0%
cichelli +6.0% +0.0% 0.10 0.10 +0.0%
circsim +6.0% +0.0% +1.0% +1.0% +0.0%
clausify +6.0% +0.0% 0.05 0.05 +0.0%
comp_lab_zift +6.0% +0.0% +2.1% +1.6% +0.0%
compress +6.0% +0.0% +0.0% +0.0% +0.0%
compress2 +6.0% +0.0% +0.0% +0.0% +0.0%
constraints +6.0% +0.0% +0.9% +0.9% +0.0%
cryptarithm1 +6.0% +0.0% -2.7% -2.8% +0.0%
cryptarithm2 +6.0% +0.0% 0.02 0.02 +0.0%
cse +6.0% +0.0% 0.00 0.00 +0.0%
eliza +5.9% +0.0% 0.00 0.00 +0.0%
event +6.0% +0.0% 0.17 0.17 +0.0%
exp3_8 +6.0% +0.0% +0.0% -0.3% +0.0%
expert +5.9% +0.0% 0.00 0.00 +0.0%
fem +5.9% +0.0% 0.03 0.03 +0.0%
fft +6.0% +0.0% 0.05 0.05 +0.0%
fft2 +6.0% +0.0% 0.08 0.08 +0.0%
fibheaps +6.0% +0.0% 0.04 0.04 +0.0%
fish +6.0% +0.0% 0.03 0.03 +0.0%
fluid +5.8% +0.0% 0.01 0.01 +0.0%
fulsom +5.9% +0.0% +1.7% +1.0% +0.9%
gamteb +6.0% +0.0% 0.06 0.06 +0.0%
gcd +6.0% +0.0% 0.04 0.04 +0.0%
gen_regexps +6.0% +0.0% 0.00 0.00 +0.0%
genfft +6.0% +0.0% 0.04 0.04 +0.0%
gg +5.9% +0.0% 0.02 0.02 +0.0%
grep +5.9% +0.0% 0.00 0.00 +0.0%
hidden +5.9% +0.0% +8.9% +9.3% +0.0%
hpg +5.9% +0.0% 0.16 0.16 +0.0%
ida +6.0% +0.0% 0.13 0.13 +0.0%
infer +5.9% +0.0% 0.08 0.08 +0.0%
integer +6.0% +0.0% +1.1% +1.0% +0.0%
integrate +6.0% +0.0% -4.9% -4.7% +0.0%
knights +6.0% +0.0% 0.01 0.01 +0.0%
lcss +6.0% +0.0% +0.0% +0.0% +0.0%
life +6.0% +0.0% +5.3% +4.6% +0.0%
lift +6.0% +0.0% 0.00 0.00 +0.0%
listcompr +6.0% +0.0% 0.11 0.11 +0.0%
listcopy +6.0% +0.0% 0.12 0.12 +0.0%
maillist +6.0% +0.0% 0.10 0.10 +1.7%
mandel +6.0% +0.0% 0.09 0.09 +0.0%
mandel2 +6.0% +0.0% 0.01 0.01 +0.0%
minimax +6.0% +0.0% 0.01 0.01 +0.0%
mkhprog +6.0% +0.0% 0.01 0.01 +0.0%
multiplier +6.0% +0.0% 0.15 0.15 +0.0%
nucleic2 +6.0% +0.0% 0.08 0.08 +0.0%
para +6.0% +0.0% -0.2% -0.0% +0.0%
paraffins +6.0% +0.0% 0.11 0.11 +0.0%
parser +5.8% +0.0% 0.04 0.04 +0.0%
parstof +5.7% +0.0% 0.01 0.01 +0.0%
pic +5.9% +0.0% 0.02 0.02 +0.0%
power +6.0% +0.0% +3.1% +2.8% +0.0%
pretty +6.0% +0.0% 0.00 0.00 +0.0%
primes +6.0% +0.0% 0.08 0.08 +0.0%
primetest +6.0% +0.0% 0.14 0.14 +0.0%
prolog +6.0% +0.0% 0.01 0.01 +0.0%
puzzle +6.0% +0.0% 0.18 0.18 +0.0%
queens +6.0% +0.0% 0.03 0.03 +0.0%
reptile +5.8% +0.0% 0.02 0.02 +0.0%
rewrite +6.0% +0.0% 0.02 0.02 +0.0%
rfib +6.0% +0.0% 0.02 0.02 +0.0%
rsa +6.0% +0.0% 0.04 0.04 +0.0%
scc +6.0% +0.0% 0.00 0.00 +0.0%
sched +6.0% +0.0% 0.03 0.03 +0.0%
scs +5.9% +0.0% +1.5% +1.6% +0.0%
simple +5.7% +0.0% +1.0% +1.8% +0.0%
solid +5.9% +0.0% 0.17 0.17 +0.0%
sorting +6.0% +0.0% 0.00 0.00 +0.0%
sphere +6.0% +0.0% 0.08 0.08 +0.0%
symalg +6.0% +0.0% 0.02 0.02 +0.0%
tak +6.0% +0.0% 0.02 0.02 +0.0%
transform +5.9% +0.0% -6.7% -6.7% +0.0%
treejoin +6.0% +0.0% -0.3% -0.3% +0.0%
typecheck +5.9% +0.0% +0.5% +1.1% +0.0%
veritas +5.4% +0.0% 0.01 0.01 +0.0%
wang +6.0% +0.0% 0.14 0.14 +0.0%
wave4main +6.0% +0.0% +1.1% +0.9% +0.0%
wheel-sieve1 +6.0% +0.0% +4.3% +4.6% +0.0%
wheel-sieve2 +6.0% +0.0% +1.0% +1.0% +0.0%
x2n1 +6.0% +0.0% 0.01 0.01 +0.0%
--------------------------------------------------------------------------------
Min +5.4% -0.1% -6.7% -6.7% +0.0%
Max +6.0% +0.0% +8.9% +9.3% +1.7%
Geometric Mean +5.9% -0.0% +0.7% +0.7% +0.0%
}}}
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/367#comment:24>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the Glasgow-haskell-bugs
mailing list