Landin library reference discuss source

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