| ... |
... |
@@ -12,15 +12,19 @@ import Prelude hiding (init) |
|
12
|
12
|
-- Test thread fairness:
|
|
13
|
13
|
-- run two cpu-bound threads concurrently for a second,
|
|
14
|
14
|
-- each counts how many operations it can perform until signaled to stop
|
|
15
|
|
--- expect a balance between the two with no more than a 75% imperfection.
|
|
16
|
|
--- Yes, 75%! On the CI machines we occasionally observe extraordinary levels
|
|
17
|
|
--- of unfairness: nearly 60% in some cases. We don't want this to become a
|
|
18
|
|
--- fragile test that is ignored, so we use an extreme bound. This should still
|
|
19
|
|
--- catch gross breakage.
|
|
|
15
|
+-- expect a balance between the two with no more than a 30% imperfection.
|
|
20
|
16
|
--
|
|
21
|
|
--- This _should_ detect if the interval timer is not working, or if thread
|
|
22
|
|
--- context switching is messed up. We can expect failure if we force a
|
|
23
|
|
--- contex switch interval of more than half the test time, i.e. more than 0.5s
|
|
|
17
|
+-- Sadly we have had to mark this test as fragile. On the CI machines we
|
|
|
18
|
+-- occasionally observe extraordinary levels of unfairness: over 80% in some
|
|
|
19
|
+-- cases. Having this marked fragile is not ideal, but it's no good having
|
|
|
20
|
+-- random failures. See issue #27522.
|
|
|
21
|
+--
|
|
|
22
|
+-- People working on the RTS timers, scheduler or capability infrastructure
|
|
|
23
|
+-- *ought* to check this test is not failing badly in a reproducible way.
|
|
|
24
|
+-- Doing so should still catch gross breakage. This test _should_ detect if
|
|
|
25
|
+-- the interval timer is not working, or if thread context switching is messed
|
|
|
26
|
+-- up. We can expect failure if we force a contex switch interval of more than
|
|
|
27
|
+-- half the test time, i.e. more than 0.5s.
|
|
24
|
28
|
--
|
|
25
|
29
|
-- We run the test twice, with allocating and non-allocating worker threads.
|
|
26
|
30
|
-- The -fno-omit-yields above is crucial for worker_nonalloc below, or it never
|
| ... |
... |
@@ -42,17 +46,16 @@ test worker = do |
|
42
|
46
|
threadDelay 300_000
|
|
43
|
47
|
-- Let them run for 300ms. The default context switch interval is 20ms.
|
|
44
|
48
|
-- This gives time for 15 context switches, so this _should_ be enough
|
|
45
|
|
- -- to get less than 10% unfairness. And on most platforms it is enough.
|
|
46
|
|
- -- But OSX! Oh OSX! How do I loath thee? Let me count++ the ways.
|
|
47
|
|
- -- To avoid a fragile test, we use a 75% unfairness threshold.
|
|
|
49
|
+ -- to get less than 10% unfairness. And on most platforms it is enough,
|
|
|
50
|
+ -- but for a bit of robustness we use 30%.
|
|
48
|
51
|
putMVar stop ()
|
|
49
|
52
|
count1 <- takeMVar res1
|
|
50
|
53
|
count2 <- takeMVar res2
|
|
51
|
54
|
let balance :: Double
|
|
52
|
55
|
balance = abs ((fromIntegral count1 - fromIntegral count2)
|
|
53
|
56
|
/ fromIntegral count2)
|
|
54
|
|
- when (balance > 0.75) $ do
|
|
55
|
|
- putStrLn "Schedule fairness more than 75% tolerance:"
|
|
|
57
|
+ when (balance > 0.30) $ do
|
|
|
58
|
+ putStrLn "Schedule fairness more than 30% tolerance:"
|
|
56
|
59
|
putStrLn $ "imperfection: " ++ show (balance * 100) ++ "%"
|
|
57
|
60
|
putStrLn $ "work counts: " ++ show (count1, count2)
|
|
58
|
61
|
exitFailure
|