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)