compiler/tests/fixtures/runtime/clock-manual/main.ldn
1-- core/io's manual clock, which a test sets and advances: code that
2-- times itself and sleeps, written against the `clock` and `wall_clock`
3-- concepts, runs over it in no time and gives the same answer on every
4-- target, Cortex-M0 included. A sleep advances the clock by exactly
5-- what was asked, both of its clocks move together, the wall clock
6-- carries its nanoseconds into seconds, and spans and instants convert
7-- as their counts say. Each check that fails returns its own code.
8import core/io/fake
9import core/time
10
11-- Poll until the clock has moved on by SPAN, sleeping STEP between
12-- readings, and say how many times it slept: a routine that only knows
13-- the `clock` concept.
14waited: (provider: type is time.clock, host: provider, span: time.duration,
15 step: time.duration) -> (sleeps: usize) =
16 start: time.instant = time.now(host)
17 deadline: time.instant = time.later(start, span)
18 sleeps = 0
19 while time.now(host) < deadline do
20 time.sleep(host, step)
21 inc sleeps
22 end while
23end waited
24
25-- How long WORK took, timed on HOST's clock.
26timed: (provider: type is time.clock, host: provider, work: time.duration)
27 -> (took: time.duration) =
28 start: time.instant = time.now(host)
29 time.sleep(host, work)
30 took = time.elapsed(start, time.now(host))
31end timed
32
33public main: () -> (code: i32) =
34 code = 1
35 return when u64(time.nanoseconds(7)) <> 7
36 or u64(time.microseconds(3)) <> 3000
37 or u64(time.milliseconds(250)) <> 250000000
38 or u64(time.seconds(90)) <> 90000000000
39 or time.in_milliseconds(time.nanoseconds(1999999)) <> 1
40 or time.duration(5) <> time.nanoseconds(5)
41 code = 2
42 mut state: fake.clock_space = zeroed
43 clock := fake.clock_over(state, time.instant(1000),
44 (seconds: 1767225600, nanoseconds: 999999000))
45 return when u64(time.now(clock)) <> 1000
46 took: time.duration = timed(clock, time.milliseconds(250))
47 return when took <> time.milliseconds(250) or state.sleeps <> 1
48 or state.slept <> 250000000
49 code = 3
50 -- The wall clock moved with it, carrying past a whole second.
51 wall: time.wall_time = time.wall_now(clock)
52 return when wall.seconds <> 1767225601 or wall.nanoseconds <> 249999000
53 code = 4
54 -- Three sleeps of 400 ms pass a second; the third reaches it.
55 sleeps: usize = waited(clock, time.seconds(1), time.milliseconds(400))
56 return when sleeps <> 3 or state.monotonic <> 1000 + 1450000000
57 code = 5
58 -- A sleep of zero does not move the clock; `advance` moves it as a
59 -- test says, and a test may set the wall clock back.
60 before: time.instant = time.now(clock)
61 time.sleep(clock, time.duration(0))
62 return when time.now(clock) <> before
63 fake.advance(clock, time.seconds(2))
64 return when u64(time.elapsed(before, time.now(clock))) <> 2000000000
65 state.wall_seconds = 0
66 set_back: time.wall_time = time.wall_now(clock)
67 return when set_back.seconds <> 0 or set_back.nanoseconds <> 449999000
68 code = 6
69 return when state.readings < 10 or state.sleeps <> 5
70 deadline: time.instant = time.later(time.instant(1), time.nanoseconds(2))
71 return when u64(deadline) <> 3
72 code = 42
73end main