0 | module Evince.Async.Posix
 1 |
 2 | import public Evince.Async.Synchronized
 3 | import public Evince.Async.Hoist
 4 | import public Evince.Async.Shared
 5 |
 6 | import Data.Maybe
 7 | import System
 8 | import System.Info
 9 | import IO.Async
10 | import IO.Async.Loop.Posix
11 | import Evince.Core
12 |
13 | -- The posix event-loop runner. idris2-async's `simpleApp` takes its worker-thread
14 | -- count only from IDRIS2_ASYNC_THREADS (default 2). We give a better default for a
15 | -- test runner - the processor count - by setting the variable when it's unset, so
16 | -- users get full parallelism out of the box while keeping the env var as an
17 | -- override (an explicit value is always respected).
18 | posixRun : Async Poll [] () -> IO ()
19 | posixRun prog = do
20 |   Nothing <- getEnv "IDRIS2_ASYNC_THREADS"
21 |     | Just _ => simpleApp prog
22 |   cores <- getNProcessors
23 |   ignore $ setEnv "IDRIS2_ASYNC_THREADS" (show (fromMaybe 2 cores)) True
24 |   simpleApp prog
25 |
26 | -- Multi-threaded entry points: idris2-async's poll-based `ThreadPool` distributes
27 | -- top-level groups across OS worker threads, so they execute with genuine
28 | -- multi-core parallelism. In practice this builds and runs only on Chez; Racket
29 | -- and RefC hit upstream threading/FFI gaps that keep the posix loop from running
30 | -- there. The `caswrite1` lock keeps group hooks correct under that true concurrency.
31 |
32 | ||| Run a spec under the multi-threaded posix driver with custom configuration,
33 | ||| printing results and exiting non-zero if any test failed.
34 | export
35 | runSpecAsyncWith : RunConfig -> Spec (Async Poll []) () () -> IO ()
36 | runSpecAsyncWith = runSpecVia posixRun
37 |
38 | ||| Run a spec under the multi-threaded posix driver with default configuration.
39 | export
40 | runSpecAsync : Spec (Async Poll []) () () -> IO ()
41 | runSpecAsync = runSpecAsyncWith defaultConfig
42 |
43 | ||| Run under the posix driver with custom configuration and return the summary
44 | ||| without exiting. Useful for meta-testing.
45 | export
46 | runSpecAsyncWithSummaryAndConfig : RunConfig -> Spec (Async Poll []) () () -> IO Summary
47 | runSpecAsyncWithSummaryAndConfig = summaryVia posixRun
48 |
49 | ||| Run under the posix driver and return the summary without exiting.
50 | export
51 | runSpecAsyncWithSummary : Spec (Async Poll []) () () -> IO Summary
52 | runSpecAsyncWithSummary = runSpecAsyncWithSummaryAndConfig defaultConfig
53 |
54 | ||| Run a spec under the posix driver, reading CLI args (e.g. `--jobs=N`).
55 | export
56 | runSpecAsyncWithArgs : Spec (Async Poll []) () () -> IO ()
57 | runSpecAsyncWithArgs = runSpecArgsVia posixRun
58 |
59 | ||| Run under the posix driver with fail-fast - stop after the first failure.
60 | export
61 | runSpecAsyncFailFast : Spec (Async Poll []) () () -> IO ()
62 | runSpecAsyncFailFast = runSpecFailFastVia posixRun
63 |
64 | ||| Run under the posix driver with per-test timing displayed.
65 | export
66 | runSpecAsyncTimed : Spec (Async Poll []) () () -> IO ()
67 | runSpecAsyncTimed = runSpecTimedVia posixRun
68 |
69 | ||| Run a concrete `Spec IO` under the posix driver, hoisting its actions into
70 | ||| `Async` via `liftIO`.
71 | export
72 | runSpecAsyncIO : Spec IO () () -> IO ()
73 | runSpecAsyncIO = runSpecAsync . hoistSpec liftIO
74 |
75 | ||| Like `runSpecAsyncIO`, with custom configuration.
76 | export
77 | runSpecAsyncIOWith : RunConfig -> Spec IO () () -> IO ()
78 | runSpecAsyncIOWith cfg = runSpecAsyncWith cfg . hoistSpec liftIO
79 |