Skip to content

Commit d0f7cab

Browse files
iohk-bors[bot]coot
andauthored
Merge #3640 #3662
3640: Connection manager transition order test using IOSimPOR r=coot a=coot This PR adds a quickcheck property test which validates order of connection manager transitions using *IOSimPOR*. It also fixes a connection manager bug discovered thanks to the new test. Fixes #3613. - connection-manager-tests: test transition order - connection-manager: don't blindly override state - connection-manager-tests: code style 3662: Removed ST effects from IOSimPOR r=coot a=coot ST effects are thread local, they never race with other steps. This patch reverts a previous fix commited in PR #3647. Thanks for `IOSimPOR` we also found out that the transition: `UnnegotiatedSt Inbound → TerminatingSt` should be valid, similarly to one for outbound connections (see PR #3652, commit fbcb6aada). Co-authored-by: Marcin Szamotulski <[email protected]>
2 parents 3fb8a11 + 2736c97 commit d0f7cab

File tree

2 files changed

+12
-31
lines changed

2 files changed

+12
-31
lines changed

io-sim/src/Control/Monad/IOSimPOR/Internal.hs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,7 @@ schedule thread@Thread{
378378

379379
LiftST st k -> do
380380
x <- strictToLazyST st
381-
let thread' = thread { threadControl = ThreadControl (k x) ctl,
382-
threadEffect = effect <> liftSTEffect }
381+
let thread' = thread { threadControl = ThreadControl (k x) ctl }
383382
schedule thread' simstate
384383

385384
GetMonoTime k -> do
@@ -1463,23 +1462,16 @@ updateRaces newStep@Step{ stepThreadId = tid, stepEffect = newEffect }
14631462
-- then any threads that it wakes up become non-concurrent also.
14641463
let lessConcurrent = foldr Set.delete concurrent (effectWakeup newEffect) in
14651464
if tid `elem` concurrent then
1466-
let theseStepsRace = isRacyThreadId tid
1467-
&& step `racingSteps` newStep
1465+
let theseStepsRace = isRacyThreadId tid && racingSteps step newStep
14681466
happensBefore = step `happensBeforeStep` newStep
14691467
nondep' | happensBefore = nondep
14701468
| otherwise = newStep : nondep
1471-
-- We cannot remove the 'tid' thread from the set of concurrent
1472-
-- threads if 'theseStepsRace'. This was done previously in
1473-
-- order to record only the first race with each thread. But
1474-
-- it can happen that the frist race will block a thread that
1475-
-- is scheduled to run until another later step unblock it
1476-
-- (e.g. 'modifyTMVar`). If we remove the 'tid' from the set
1477-
-- of concurrent threads we can end up in a situation where
1478-
-- a schedule is not runnable, because the next thread to run
1479-
-- is still blocked (e.g. 'TMVar' is taken but not yet
1480-
-- released).
1481-
concurrent' | happensBefore = Set.delete tid lessConcurrent
1482-
| otherwise = concurrent
1469+
-- We will only record the first race with each thread---reversing
1470+
-- the first race makes the next race detectable. Thus we remove a
1471+
-- thread from the concurrent set after the first race.
1472+
concurrent' | happensBefore = Set.delete tid lessConcurrent
1473+
| theseStepsRace = Set.delete tid concurrent
1474+
| otherwise = concurrent
14831475
-- Here we record discovered races.
14841476
-- We only record a new race if we are following the default schedule,
14851477
-- to avoid finding the same race in different parts of the search space.

io-sim/src/Control/Monad/IOSimPOR/Types.hs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,17 @@ data Effect = Effect {
1717
effectReads :: !(Set TVarId),
1818
effectWrites :: !(Set TVarId),
1919
effectForks :: !(Set ThreadId),
20-
effectLiftST :: !Bool,
2120
effectThrows :: ![ThreadId],
2221
effectWakeup :: ![ThreadId]
2322
}
2423
deriving (Eq, Show)
2524

2625
instance Semigroup Effect where
27-
Effect r w s b ts wu <> Effect r' w' s' b' ts' wu' =
28-
Effect (r<>r') (w<>w') (s<>s') (b||b') (ts++ts') (wu++wu')
26+
Effect r w s ts wu <> Effect r' w' s' ts' wu' =
27+
Effect (r<>r') (w<>w') (s<>s') (ts++ts') (wu++wu')
2928

3029
instance Monoid Effect where
31-
mempty = Effect Set.empty Set.empty Set.empty False [] []
30+
mempty = Effect Set.empty Set.empty Set.empty [] []
3231

3332
-- readEffect :: SomeTVar s -> Effect
3433
-- readEffect r = mempty{effectReads = Set.singleton $ someTvarId r }
@@ -45,9 +44,6 @@ writeEffects rs = mempty{effectWrites = Set.fromList (map someTvarId rs)}
4544
forkEffect :: ThreadId -> Effect
4645
forkEffect tid = mempty{effectForks = Set.singleton $ tid}
4746

48-
liftSTEffect :: Effect
49-
liftSTEffect = mempty{ effectLiftST = True }
50-
5147
throwToEffect :: ThreadId -> Effect
5248
throwToEffect tid = mempty{ effectThrows = [tid] }
5349

@@ -62,9 +58,7 @@ onlyReadEffect e = e { effectReads = effectReads mempty } == mempty
6258

6359
racingEffects :: Effect -> Effect -> Bool
6460
racingEffects e e' =
65-
(effectLiftST e && racesWithLiftST e')
66-
|| (effectLiftST e' && racesWithLiftST e )
67-
|| effectThrows e `intersectsL` effectThrows e'
61+
effectThrows e `intersectsL` effectThrows e'
6862
|| effectReads e `intersects` effectWrites e'
6963
|| effectWrites e `intersects` effectReads e'
7064
|| effectWrites e `intersects` effectWrites e'
@@ -74,8 +68,3 @@ racingEffects e e' =
7468

7569
intersectsL :: Eq a => [a] -> [a] -> Bool
7670
intersectsL a b = not $ null $ a `List.intersect` b
77-
78-
racesWithLiftST eff =
79-
effectLiftST eff
80-
|| not (Set.null (effectReads eff) && Set.null (effectWrites eff))
81-

0 commit comments

Comments
 (0)