Landin library reference discuss source

hosted/events/time.ldn

1--  The event provider's `time.clock`: the monotonic clock, and sleeping on
2--  it, which parks the fibre with a deadline and lets the others run.  The
3--  loop's own wait sleeps until the earliest deadline, so a sleep costs no
4--  descriptor and no timer of the system's (D480).  The wall clock is the
5--  system's, in delegated.ldn.
6
7import core/time
8import platform/posix
9
10--  A second in nanoseconds.
11second: u64 = 1000000000
12
13--  The clock `clock` read now.  Every hosted system has both clocks, and
14--  reading one fails only when the process is given a bad address, which
15--  no call here gives, so a failure ends the program.
16clock_read: (clock: posix.clock_kind) -> (sample: posix.time_value) =
17    sample = posix.clock_time(clock) else (problem)
18        _ = problem
19        compiler.unreachable()
20    end
21end clock_read
22
23--  The monotonic clock in nanoseconds since the system started, which no
24--  hosted system counts as negative, and never zero, which a waiting
25--  record takes for no deadline.
26reading: () -> (at: u64) =
27    sample: posix.time_value = clock_read(posix.monotonic_clock)
28    at = u64(sample.seconds) * second + u64(sample.nanoseconds)
29    if at == 0 then at = 1 end if
30end reading
31
32--  The instant `span` after now, the clock's last instant when that is
33--  past it.
34deadline_after: (span: time.duration) -> (deadline: u64) =
35    start: u64 = reading()
36    room: u64 = (0 -% 1) - start
37    deadline = if u64(span) > room then 0 -% 1
38               else start + u64(span) end if
39end deadline_after
40
41events_now: (self: host) -> (at: time.instant) =
42    _ = services(self)
43    at = time.instant(reading())
44end events_now
45
46--  The sleeping fibre waits for its deadline alone; it is answered when
47--  the loop finds the clock past it, never before.
48events_sleep: (self: host, span: time.duration) -> none =
49    deadline: u64 = deadline_after(span)
50    while reading() < deadline do
51        mut entry: waiting = (next: 0, descriptor: -1, output: false,
52                              child: 0, signalled: false, deadline: deadline,
53                              answer: pending)
54        --  A record with no descriptor or child is never refused.
55        _ = park(self, addr entry) else (problem)
56            _ = problem
57            return
58        end
59    end while
60end events_sleep
61
62host is time.clock (now: events_now, sleep: events_sleep)