A synchronous version of `Async_kernel.Time_source`. `advance_by_alarms` runs alarms immediately, rather than enqueueing Async jobs.

`module T1 : sig ... end`
`module Read_write : sig ... end`
`type t``= Core_kernel.read T1.t```
`include sig ... end`
`val sexp_of_t : t ‑> Base.Sexp.t`
`include Core_kernel.Invariant.S with type t := t`
`type t`````
`val invariant : t Base__.Invariant_intf.inv`
`val read_only : [> Core_kernel.read ] T1.t ‑> t`
`type callback``= unit ‑> unit```
`val create : ?⁠timing_wheel_config:Core_kernel.Timing_wheel_ns.Config.t ‑> now:Async_kernel__.Import.Time_ns.t ‑> unit ‑> Core_kernel.read_write T1.t`

`create ~now ()` creates a new time source. The default `timing_wheel_config` has 100 microsecond precision, with levels of >1s, >1m, >1h, >1d.

`val alarm_precision : [> Core_kernel.read ] T1.t ‑> Async_kernel__.Import.Time_ns.Span.t`
`val is_wall_clock : [> Core_kernel.read ] T1.t ‑> bool`

`is_wall_clock` reports whether this time source represents 'wall clock' time, or some alternate source of time.

`val now : [> Core_kernel.read ] T1.t ‑> Async_kernel__.Import.Time_ns.t`

The behavior of `now` is special for `wall_clock ()`; it always calls `Time_ns.now ()`, so it can return times that the time source has not yet been advanced to.

`val timing_wheel_now : [> Core_kernel.read ] T1.t ‑> Async_kernel__.Import.Time_ns.t`

Removes the special behavior of `now` for `wall_clock ()`; it always returns the timing wheel's notion of now, which means that the following inequality always holds: `timing_wheel_now () <= now ()`.

`val advance_by_alarms : [> Core_kernel.write ] T1.t ‑> to_:Async_kernel__.Import.Time_ns.t ‑> unit Core_kernel.Or_error.t`

`advance_by_alarms t ~to_` advances `t`'s time to `to_`, running callbacks for all alarms in `t` whose `at <= to_`. Callbacks run in nondecreasing order of `at`. If `to_ <= now t`, then `now t` does not change (and in particular does not go backward), but alarms with `at <= to_` may still may fire.

`val run_at : [> Core_kernel.read ] T1.t ‑> Async_kernel__.Import.Time_ns.t ‑> callback ‑> unit`

`run_at t at f` schedules an alarm that will run `f` during the next subsequent `advance_by_alarms t ~to_` that causes `now t >= at`. If `at <= now t`, then `f` will to run at the next call to `advance_by_alarms`. `f` is allowed to do all `Synchronous_time_source` operations except for `advance_by_alarms` (because `f` is already running during `advance_by_alarms`. Adding alarms is not zero-alloc and the underlying events live in the OCaml heap.

`val run_after : [> Core_kernel.read ] T1.t ‑> Async_kernel__.Import.Time_ns.Span.t ‑> callback ‑> unit`

`run_after t span f` is `run_at t (now t + span) f`.

`val run_at_intervals : [> Core_kernel.read ] T1.t ‑> Async_kernel__.Import.Time_ns.Span.t ‑> callback ‑> unit`

`run_at_intervals t span f` causes `f` to run at intervals `now t + k * span`, for k = 0, 1, 2, etc. `run_at_intervals` raises if `span < alarm_precision t`.

`module Event : sig ... end`
`val default_timing_wheel_config : Core_kernel.Timing_wheel_ns.Config.t`
`val wall_clock : unit ‑> t`

A time source with `now t` given by wall-clock time (i.e. `Time_ns.now`), and automatically advanced at the start of each Async cycle. The wall clock uses the same timing wheel as that used by the Async scheduler, and is hence similarly affected by the `ASYNC_CONFIG` environment variable.