···11+(srcs-x myocamlbuild.ml pkg test src/mtime_top.ml src/mtime_top_init.ml)
+134
vendor/opam/mtime/CHANGES.md
···11+v2.1.0 2024-09-10 Zagreb
22+------------------------
33+44+- Add `Mtime.Span.{is_shorter,is_longer}` to make duration
55+ comparisons more obivous. Thanks to Pau Ruiz Safont for
66+ the suggestion and the patch.
77+- Regularize naming structure. The `mtime.clock.os` library
88+ is deprecated. Use `mtime.clock` instead.
99+- Make the library `mtime.clock` export `mtime`.
1010+1111+1212+v2.0.0 2022-12-02 Zagreb
1313+------------------------
1414+1515+* Use the new `js_of_ocaml` ocamlfind `META` standard to link JavaScript
1616+ stubs (#28).
1717+* `Mtime_clock` use `CLOCK_BOOTTIME` rather than `CLOCK_MONOTONIC`
1818+ on Linux and `mach_continuous_time` rather than `mach_absolute_time`
1919+ on macOS. This means that on these platforms sleep time is taken
2020+ into account (#10). Thanks to Bikal Lem for the patch.
2121+* Add `Mtime.{to,of}_float_ns`.
2222+* Remove deprecated values `Mtime.s_to_*` and `Mtime.Span.to_*` floating
2323+ points functions. Note that the implementation of `Mtime.Span.to_*`
2424+ functions was broken if your span exceeded `Int64.max_int`. Thanks
2525+ to Thomas Leonard for the report (#46).
2626+* Change implementation of `Mtime.Span.pp` and remove
2727+ `Mtime.Span.pp_float_s`. The implementation no longer uses floating
2828+ point arithmetic and always over approximates the result, no
2929+ duration is printed shorter than it is. The output is no longer
3030+ US-ASCII but UTF-8 encoded since U+03BC is used for µs.
3131+* Stop installing the clock interface in `mtime.clock`, this package
3232+ is now empty (#42).
3333+3434+v1.4.0 2022-02-17 La Forclaz (VS)
3535+---------------------------------
3636+3737+* Change the `js_of_ocaml` strategy for `Mtime_clock`'s JavaScript
3838+ implementation. Primitives of `mtime.clock.os` are now implemented
3939+ in pure JavaScript and linked by `js_of_ocaml`. This means that the
4040+ `mtime.clock.jsoo` library no longer exists, simply link against
4141+ `mtime.clock.os` instead. Thanks to Hugo Heuzard for suggesting and
4242+ implementing this.
4343+4444+* Add `Mtime.{min,max}_stamp`.
4545+* Add durations `Mtime.Span.{ns,us,ms,s,min,hour,day,year}` and
4646+ the `Mtime.Span.(*)` operator (#28).
4747+* Deprecate `Mtime.s_to_*` and `Mtime.*_to_s` floating point constants (#28).
4848+* Require OCaml >= 4.08.
4949+* Allow compiling with MSVC compiler. Thanks to Jonah Beckford for the patch.
5050+5151+v1.3.0 2021-10-20 Zagreb
5252+------------------------
5353+5454+* Add Windows support. Thanks to Andreas Hauptmann for the patch
5555+ and Corentin Leruth for the integration.
5656+5757+v1.2.0 2019-07-19 Zagreb
5858+------------------------
5959+6060+* Add support for node.js. Thanks to Fabian (@copy) for the patch.
6161+* Support for js_of_ocaml 3.4.0.
6262+* Add MTIME_OS environment variable for specifying the OS at build time.
6363+6464+v1.1.0 2017-06-24 London
6565+------------------------
6666+6767+* Add `Mtime.Span.{add,zero,one,min_span,max_span}`.
6868+6969+v1.0.0 2017-05-09 La Forclaz (VS)
7070+---------------------------------
7171+7272+This is a major breaking release with a new API. Thanks to David
7373+Sheets for contributions and discussions. The API was changed to
7474+mirror and follow the conventions and design of `Ptime`. The `Mtime`
7575+module now only provides platform independent datatypes for supporting
7676+monotonic clock readings. Platform dependent access to monotonic
7777+clocks is provided by the `Mtime_clock` modules. The `Mtime.t` type
7878+was added for monotonic timestamps.
7979+8080+* Rename packages `mtime.{jsoo,os}` to `mtime.{clock.jsoo,clock.os}`
8181+ which implement the new `Mtime_clock` interface. The `mtime` package
8282+ has the platform independent support.
8383+* Remove `Mtime.available`, `Mtime_clock` functions now raise `Sys_error`
8484+ on unsupported platforms or errors.
8585+* Add a raw interface to `Mtime_clock` which statisfies MirageOS's monotonic
8686+ clock signature.
8787+* Move `Mtime.{elapsed,counter,count}` to
8888+ `Mtime_clock.{elapsed,counter,count}`.
8989+* Add `Mtime.t` a type to represent system-relative monotonic
9090+ timestamps and related functions. Thanks to David Sheets for the
9191+ patch and his patience.
9292+* Add the `Mtime.Span` module for functions on monotonic time
9393+ spans. Most of the previous platform independent support is now
9494+ provided by this module. See below.
9595+* Move `Mtime.to_ns_uint64` to `Mtime.Span.to_uint64_ns`.
9696+* Move other `Mtime.to_*` to `Mtime.Span.to_*`.
9797+* Move `Mtime.pp_span[_s]` to `Mtime.Span.pp[_float__s]`.
9898+* Add `Mtime.Span.{compare,equal}`. Thanks to David Sheets for the patch.
9999+* Add `Mtime.Span.of_uint64_ns`. Thanks to David Sheets for the patch.
100100+101101+v0.8.4 2017-02-05 La Forclaz (VS)
102102+---------------------------------
103103+104104+* Fix package for -custom linking. Thanks to @orbitz for the report.
105105+* Build depend on topkg.
106106+* Relicense from BSD3 to ISC.
107107+108108+v0.8.3 2015-12-22 Cambridge (UK)
109109+--------------------------------
110110+111111+* Fix Linux bytecode builds. Thanks to Edwin Török for the report.
112112+* Really make js_of_ocaml an optional dependency.
113113+114114+115115+v0.8.2 2015-05-17 La Forclaz (VS)
116116+---------------------------------
117117+118118+* Simpler toploop support (internal change).
119119+* Improve Linux build support by recording link flags against librt in
120120+ the cma and cmxa (this seems to be needed in certain distributions).
121121+ Thanks to David Scott for the report and the fix.
122122+123123+124124+v0.8.1 2015-03-23 La Forclaz (VS)
125125+---------------------------------
126126+127127+* Fix broken arithmetic on 32-bit platform with POSIX clocks. Thanks to
128128+ Stephen Dolan for the report and the fix.
129129+130130+131131+v0.8.0 2015-03-19 La Forclaz (VS)
132132+---------------------------------
133133+134134+First release.
+13
vendor/opam/mtime/LICENSE.md
···11+Copyright (c) 2015 The mtime programmers
22+33+Permission to use, copy, modify, and/or distribute this software for any
44+purpose with or without fee is hereby granted, provided that the above
55+copyright notice and this permission notice appear in all copies.
66+77+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
88+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
99+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1010+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1111+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1212+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1313+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+42
vendor/opam/mtime/README.md
···11+Mtime — Monotonic wall-clock time for OCaml
22+===========================================
33+44+Mtime has platform independent support for monotonic wall-clock time
55+in pure OCaml. This time increases monotonically and is not subject to
66+operating system calendar time adjustments. The library has types to
77+represent nanosecond precision timestamps and time spans.
88+99+The additional Mtime_clock library provide access to a system
1010+monotonic clock.
1111+1212+Mtime has a no dependency. Mtime_clock depends on your system library
1313+or JavaScript runtime system. Mtime and its libraries are distributed
1414+under the ISC license.
1515+1616+Home page: <http://erratique.ch/software/mtime>
1717+1818+# Installation
1919+2020+Mtime can be installed with `opam`:
2121+2222+ opam install mtime
2323+2424+If you don't use `opam` consult the [`opam`](opam) file for build
2525+instructions.
2626+2727+# Documentation
2828+2929+The documentation can be consulted [online] or via `odig doc mtime`.
3030+3131+Questions are welcome but better asked on the [OCaml forum] than on
3232+the issue tracker.
3333+3434+[online]: http://erratique.ch/software/mtime/doc/
3535+[OCaml forum]: https://discuss.ocaml.org/
3636+3737+# Sample programs
3838+3939+See [test/min_clock.ml](test/min_clock.ml).
4040+4141+If you installed mtime with `opam` sample programs are located in
4242+the directory `opam var mtime:doc`.
···11+{0 Mtime {%html: <span class="version">%%VERSION%%</span>%}}
22+33+Mtime has platform independent support for monotonic wall-clock time.
44+This time increases monotonically and is not subject to operating
55+system calendar time adjustments. The library has types to represent
66+nanosecond precision timestamps and time spans.
77+88+{!Mtime_clock} provides acces to {{!Mtime_clock.platform_support}a
99+monotonic system clock} and its resolution (if available).
1010+1111+{1:mtime Library [mtime]}
1212+1313+{!modules: Mtime}
1414+1515+{1:mtime_clock Library [mtime.clock]}
1616+1717+{!modules: Mtime_clock}
1818+1919+This library also works with JavaScript, see the
2020+{{!Mtime_clock.platform_support}platform support}.
···11+open Ocamlbuild_plugin
22+open Command
33+44+let os = try Sys.getenv "MTIME_OS" with
55+| Not_found -> Ocamlbuild_pack.My_unix.run_and_read "uname -s"
66+77+let system_support_lib = match os with
88+| "Linux\n" -> [A "-cclib"; A "-lrt"]
99+| _ -> []
1010+1111+let lib s =
1212+ match !Ocamlbuild_plugin.Options.ext_lib with
1313+ | "" -> s ^ ".a"
1414+ | x -> s ^ "." ^ x
1515+1616+let () =
1717+ dispatch begin function
1818+ | After_rules ->
1919+2020+ (* mtime *)
2121+2222+ ocaml_lib ~tag_name:"use_mtime" ~dir:"src" "src/mtime";
2323+2424+ (* mtime-clock *)
2525+2626+ flag_and_dep ["link"; "ocaml"; "link_mtime_clock_stubs"]
2727+ (P (lib "src/clock/libmtime_clock_stubs"));
2828+2929+ dep ["record_mtime_clock_stubs"]
3030+ [lib "src/clock/libmtime_clock_stubs"];
3131+3232+ flag ["library"; "ocaml"; "byte"; "record_mtime_clock_stubs"]
3333+ (S ([A "-dllib"; A "-lmtime_clock_stubs"] @ system_support_lib));
3434+ flag ["library"; "ocaml"; "record_mtime_clock_stubs"] (* byt + nat *)
3535+ (S ([A "-cclib"; A "-lmtime_clock_stubs"] @ system_support_lib));
3636+3737+ ocaml_lib ~tag_name:"use_mtime_clock" ~dir:"src/clock"
3838+ "src/clock/mtime_clock";
3939+4040+ flag ["link"; "ocaml"; "use_mtime_clock"]
4141+ (S [A "-ccopt"; A "-Lsrc/clock"]);
4242+ | _ -> ()
4343+ end
+32
vendor/opam/mtime/opam
···11+opam-version: "2.0"
22+name: "mtime"
33+synopsis: "Monotonic wall-clock time for OCaml"
44+description: """\
55+Mtime has platform independent support for monotonic wall-clock time
66+in pure OCaml. This time increases monotonically and is not subject to
77+operating system calendar time adjustments. The library has types to
88+represent nanosecond precision timestamps and time spans.
99+1010+The additional Mtime_clock library provide access to a system
1111+monotonic clock.
1212+1313+Mtime has a no dependency. Mtime_clock depends on your system library
1414+or JavaScript runtime system. Mtime and its libraries are distributed
1515+under the ISC license.
1616+1717+Home page: <http://erratique.ch/software/mtime>"""
1818+maintainer: "Daniel Bünzli <daniel.buenzl i@erratique.ch>"
1919+authors: "The mtime programmers"
2020+license: "ISC"
2121+tags: ["time" "monotonic" "system" "org:erratique"]
2222+homepage: "https://erratique.ch/software/mtime"
2323+doc: "https://erratique.ch/software/mtime/doc/"
2424+bug-reports: "https://github.com/dbuenzli/mtime/issues"
2525+depends: [
2626+ "ocaml" {>= "4.08.0"}
2727+ "ocamlfind" {build}
2828+ "ocamlbuild" {build & != "0.9.0"}
2929+ "topkg" {build & >= "1.1.0"}
3030+]
3131+build: ["ocaml" "pkg/pkg.ml" "build" "--dev-pkg" "%{dev}%"]
3232+dev-repo: "git+https://erratique.ch/repos/mtime.git"
···11+(*---------------------------------------------------------------------------
22+ Copyright (c) 2017 The mtime programmers. All rights reserved.
33+ SPDX-License-Identifier: ISC
44+ ---------------------------------------------------------------------------*)
55+66+(* Raw interface *)
77+88+external elapsed_ns : unit -> int64 = "ocaml_mtime_clock_elapsed_ns"
99+external now_ns : unit -> int64 = "ocaml_mtime_clock_now_ns"
1010+external period_ns : unit -> int64 option = "ocaml_mtime_clock_period_ns"
1111+1212+let () = ignore (elapsed_ns ()) (* Initalize elapsed_ns's origin. *)
1313+1414+(* Monotonic clock *)
1515+1616+let elapsed () = Mtime.Span.of_uint64_ns (elapsed_ns ())
1717+let now () = Mtime.of_uint64_ns (now_ns ())
1818+let period () = Mtime.Span.unsafe_of_uint64_ns_option (period_ns ())
1919+2020+(* Counters *)
2121+2222+type counter = int64
2323+let counter = elapsed_ns
2424+let count c = Mtime.Span.of_uint64_ns (Int64.sub (elapsed_ns ()) c)
+108
vendor/opam/mtime/src/clock/mtime_clock.mli
···11+(*---------------------------------------------------------------------------
22+ Copyright (c) 2017 The mtime programmers. All rights reserved.
33+ SPDX-License-Identifier: ISC
44+ ---------------------------------------------------------------------------*)
55+66+(** Monotonic time clock.
77+88+ [Mtime_clock] provides access to a system monotonic clock. This
99+ time increases monotonically and is not subject to operating
1010+ system calendar time adjustments.
1111+1212+ Only use {!Mtime_clock.now} if you need inter-process time
1313+ correlation, otherwise prefer {!Mtime_clock.elapsed} and
1414+ {{!Mtime_clock.counters}counters}.
1515+1616+ Consult important information about {{!err}error handling}
1717+ and {{!platform_support}platform support}. *)
1818+1919+(** {1:clock Monotonic clock} *)
2020+2121+val elapsed : unit -> Mtime.span
2222+(** [elapsed ()] is the monotonic time span elapsed since the
2323+ beginning of the program.
2424+2525+ Raises {!Sys_error}, see {{!err}error handling} *)
2626+2727+val now : unit -> Mtime.t
2828+(** [now ()] is the current system-relative monotonic timestamp. Its
2929+ absolute value is meaningless.
3030+3131+ Raises {!Sys_error}, see {{!err}error handling} *)
3232+3333+val period : unit -> Mtime.span option
3434+(** [period ()] is the clock's period as a monotonic time span (if
3535+ available). *)
3636+3737+(** {1:counters Time counters} *)
3838+3939+type counter
4040+(** The type for monotonic wall-clock time counters. *)
4141+4242+val counter : unit -> counter
4343+(** [counter ()] is a counter counting from now on.
4444+4545+ Raises {!Sys_error}, see {{!err}error handling} *)
4646+4747+val count : counter -> Mtime.span
4848+(** [count c] is the monotonic time span elapsed since [c] was created. *)
4949+5050+(** {1:raw Monotonic clock raw interface} *)
5151+5252+val elapsed_ns : unit -> int64
5353+(** [elapsed_ns ()] is the {e unsigned} 64-bit integer nanosecond monotonic
5454+ time span elapsed since the beginning of the program.
5555+5656+ Raises {!Sys_error}, see {{!err}error handling} *)
5757+5858+val now_ns : unit -> int64
5959+(** [now_ns ()] is an {e unsigned} 64-bit integer nanosecond
6060+ system-relative monotonic timestamp. The absolute value is
6161+ meaningless.
6262+6363+ Raises {!Sys_error}, see {{!err}error handling} *)
6464+6565+val period_ns : unit -> int64 option
6666+(** [period_ns ()] is the clock's period as an {e unsigned} 64-bit
6767+ integer nanosecond monotonic time span (if available). *)
6868+6969+(** {1:err Error handling}
7070+7171+ The functions {!elapsed}, {!now}, {!val-counter}, {!elapsed_ns} and
7272+ {!now_ns} raise [Sys_error] whenever they can't determine the
7373+ current time or that it doesn't fit in [Mtime]'s range. Usually
7474+ this exception should only be catched at the toplevel of your
7575+ program to log it and abort the program. It indicates a serious
7676+ error condition in the system.
7777+7878+ All the other functions, whose functionality is less essential,
7979+ simply silently return [None] if they can't determine the
8080+ information either because it is unavailable or because an error
8181+ occured.
8282+8383+ {1:platform_support Platform support}
8484+8585+ {ul
8686+ {- Linux uses {{:http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_gettime.html}[clock_gettime]}
8787+ with {{:https://www.man7.org/linux/man-pages/man3/clock_settime.3.html}
8888+ CLOCK_BOOTTIME}. This means that sleep time is taken into account.}
8989+ {- Platforms with a POSIX clock use
9090+ {{:http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_gettime.html}[clock_gettime]}
9191+ with CLOCK_MONOTONIC.}
9292+ {- Darwin uses
9393+ {{:https://developer.apple.com/documentation/kernel/1646199-mach_continuous_time}[mach_continous_time]}.
9494+ This means that sleep time is taken into account.}
9595+ {- Windows uses
9696+ {{:https://msdn.microsoft.com/en-us/library/windows/desktop/aa373083%28v=vs.85%29.aspx}Performance counters}. }
9797+ {- JavaScript uses
9898+ {{:http://www.w3.org/TR/hr-time/}[performance.now]} (consult
9999+ {{:http://caniuse.com/#feat=high-resolution-time}availability})
100100+ which returns a
101101+ {{:http://www.w3.org/TR/hr-time/#sec-DOMHighResTimeStamp}double
102102+ floating point value} in milliseconds with
103103+ resolution up to the microsecond.}
104104+ {- JavaScript running on Node.js uses the built-in
105105+ {{:https://nodejs.org/api/perf_hooks.html#perf_hooks_performance_now}[perf_hooks]}
106106+ module, which provides an interface compatible to the [performance]
107107+ module in browsers.}}
108108+*)
···11+/*---------------------------------------------------------------------------
22+ Copyright (c) 2022 The mtime programmers. All rights reserved.
33+ SPDX-License-Identifier: ISC
44+ ---------------------------------------------------------------------------*/
55+66+//Provides: ocaml_mtime_clock_period_ns
77+function ocaml_mtime_clock_period_ns (_unit) {
88+ return 0;
99+}
1010+1111+//Provides: mtime_clock_now
1212+//Requires: caml_int64_of_float, caml_int64_mul
1313+//Requires: caml_raise_sys_error
1414+function find_performance_obj () {
1515+ var test = function (o)
1616+ { return (o && o.performance && typeof o.performance.now == "function");};
1717+1818+ if (test (globalThis)) { return globalThis.performance; };
1919+ if (test (globalThis.perf_hooks)){ return globalThis.perf_hooks.performance;};
2020+ if (typeof require == "function") {
2121+ var ph = require ("perf_hooks");
2222+ if (test (ph)) { return ph.performance; }
2323+ }
2424+ var obj = { now: function ()
2525+ { caml_raise_sys_error ("performance.now () is not available");}}
2626+ return obj;
2727+}
2828+var performance_obj = find_performance_obj ();
2929+function mtime_clock_now () {
3030+ /* Conversion of DOMHighResTimeStamp to uint64 nanosecond timestamps.
3131+3232+ The spec https://www.w3.org/TR/hr-time-3 says DOMHighResTimeStamp
3333+ are double milliseconds that *should* be accurate to 5 microseconds.
3434+ We simply assume we have microsecond precision and multiply the
3535+ stamps given by performance.now () by 1e3 to get double microseconds.
3636+3737+ We then use Int64.of_float on these double microseconds to get an
3838+ uint64 in microseconds. This works in practice for the following
3939+ reasons. Let us assume we have the largest integer microsecond
4040+ timestamp representable exactly in double, i.e. 2^53 :
4141+4242+ 1) Assuming the zero of performance.now is when the tab is created,
4343+ our 2^53 timestamp only occurs after:
4444+4545+ 2^53 / 1_000_000 / (24 * 3600 * 365.25) ≅ 285.4 Julian years
4646+4747+ 2) 2^53 < Int64.max_int = 2^63 - 1, so seing the result of
4848+ Int64.of_float as unsigned for this timestamp is correct and in
4949+ the defined domain of the conversion function (the truncated float
5050+ must lie in [Int64.min_int;Int64.max_int] for defined behaviour).
5151+5252+ So the Int64.of_float conversion is unlikely to be problematic and
5353+ we simply bring the resulting uint64 microsecond to an uint64
5454+ nanosecond by multiplying by 1000L, which for 2^53 microseconds
5555+ remains smaller than Int64.max_int, yielding a correct uint64
5656+ nanosecond timestamp for a reasonable time range. */
5757+5858+ var now_us = performance_obj.now () * 1e3;
5959+ var now_ns = caml_int64_mul (caml_int64_of_float (now_us),
6060+ caml_int64_of_float (1000));
6161+ return now_ns;
6262+}
6363+6464+//Provides: ocaml_mtime_clock_now_ns
6565+//Requires: mtime_clock_now
6666+function ocaml_mtime_clock_now_ns (_unit) {
6767+ return mtime_clock_now ();
6868+}
6969+7070+//Provides: ocaml_mtime_clock_elapsed_ns
7171+//Requires: caml_int64_sub, mtime_clock_now
7272+var mtime_clock_start;
7373+function ocaml_mtime_clock_elapsed_ns (_unix) {
7474+ if (!mtime_clock_start) mtime_clock_start = mtime_clock_now ();
7575+ var now = mtime_clock_now ();
7676+ return caml_int64_sub (now, mtime_clock_start);
7777+}
···11+(*---------------------------------------------------------------------------
22+ Copyright (c) 2015 The mtime programmers. All rights reserved.
33+ SPDX-License-Identifier: ISC
44+ ---------------------------------------------------------------------------*)
55+66+(* Time spans
77+88+ Time spans are in nanoseconds and we represent them by an unsigned
99+ 64-bit integer. This allows to represent spans for:
1010+ (2^64-1) / 1_000_000_000 / (24 * 3600 * 365.25) ≅ 584.5 Julian years *)
1111+1212+type span = int64 (* unsigned nanoseconds *)
1313+1414+module Span = struct
1515+ type t = span
1616+ let zero = 0L
1717+ let one = 1L
1818+ let min_span = zero
1919+ let max_span = -1L
2020+2121+ (* Predicates *)
2222+2323+ let equal = Int64.equal
2424+ let compare = Int64.unsigned_compare
2525+ let is_shorter s ~than = compare s than < 0
2626+ let is_longer s ~than = compare s than > 0
2727+2828+ (* Arithmetic *)
2929+3030+ let add = Int64.add
3131+ let abs_diff s0 s1 =
3232+ if compare s0 s1 < 0 then Int64.sub s1 s0 else Int64.sub s0 s1
3333+3434+ (* Durations *)
3535+3636+ let ( * ) n s = Int64.mul (Int64.of_int n) s
3737+ let ns = 1L
3838+ let us = 1_000L
3939+ let ms = 1_000_000L
4040+ let s = 1_000_000_000L
4141+ let min = 60_000_000_000L
4242+ let hour = 3600_000_000_000L
4343+ let day = 86400_000_000_000L
4444+ let year = 31_557_600_000_000_000L
4545+4646+ (* Converting *)
4747+4848+ let to_uint64_ns s = s
4949+ let of_uint64_ns ns = ns
5050+5151+ let max_float_int = 9007199254740992. (* 2^53. *)
5252+ let int64_min_int_float = Int64.to_float Int64.min_int
5353+ let int64_max_int_float = Int64.to_float Int64.max_int
5454+5555+ let of_float_ns sf =
5656+ if sf < 0. || sf >= max_float_int || not (Float.is_finite sf)
5757+ then None else Some (Int64.of_float sf)
5858+5959+ let to_float_ns s =
6060+ if Int64.compare 0L s <= 0 then Int64.to_float s else
6161+ int64_max_int_float +. (-. int64_min_int_float +. Int64.to_float s)
6262+6363+ let unsafe_of_uint64_ns_option nsopt = nsopt
6464+6565+ (* Formatting *)
6666+6767+ let pf = Format.fprintf
6868+6969+ let rec pp_si_span unit_str unit_str_len si_unit si_higher_unit ppf span =
7070+ let geq x y = Int64.unsigned_compare x y >= 0 in
7171+ let m = Int64.unsigned_div span si_unit in
7272+ let n = Int64.unsigned_rem span si_unit in
7373+ let pp_unit ppf () = Format.pp_print_as ppf unit_str_len unit_str in
7474+ match m with
7575+ | m when geq m 100L -> (* No fractional digit *)
7676+ let m_up = if Int64.equal n 0L then m else Int64.succ m in
7777+ let span' = Int64.mul m_up si_unit in
7878+ if geq span' si_higher_unit then pp ppf span' else
7979+ (pf ppf "%Ld" m_up; pp_unit ppf ())
8080+ | m when geq m 10L -> (* One fractional digit w.o. trailing zero *)
8181+ let f_factor = Int64.unsigned_div si_unit 10L in
8282+ let f_m = Int64.unsigned_div n f_factor in
8383+ let f_n = Int64.unsigned_rem n f_factor in
8484+ let f_m_up = if Int64.equal f_n 0L then f_m else Int64.succ f_m in
8585+ begin match f_m_up with
8686+ | 0L -> pf ppf "%Ld" m; pp_unit ppf ()
8787+ | f when geq f 10L ->
8888+ pp ppf Int64.(add (mul m si_unit) (mul f f_factor))
8989+ | f -> pf ppf "%Ld.%Ld" m f; pp_unit ppf ()
9090+ end
9191+ | m -> (* Two or zero fractional digits w.o. trailing zero *)
9292+ let f_factor = Int64.unsigned_div si_unit 100L in
9393+ let f_m = Int64.unsigned_div n f_factor in
9494+ let f_n = Int64.unsigned_rem n f_factor in
9595+ let f_m_up = if Int64.equal f_n 0L then f_m else Int64.succ f_m in
9696+ match f_m_up with
9797+ | 0L -> pf ppf "%Ld" m; pp_unit ppf ()
9898+ | f when geq f 100L ->
9999+ pp ppf Int64.(add (mul m si_unit) (mul f f_factor))
100100+ | f when Int64.equal (Int64.rem f 10L) 0L ->
101101+ pf ppf "%Ld.%Ld" m (Int64.div f 10L); pp_unit ppf ()
102102+ | f ->
103103+ pf ppf "%Ld.%02Ld" m f; pp_unit ppf ()
104104+105105+ and pp_non_si unit_str unit unit_lo_str unit_lo unit_lo_size ppf span =
106106+ let geq x y = Int64.unsigned_compare x y >= 0 in
107107+ let m = Int64.unsigned_div span unit in
108108+ let n = Int64.unsigned_rem span unit in
109109+ if Int64.equal n 0L then pf ppf "%Ld%s" m unit_str else
110110+ let f_m = Int64.unsigned_div n unit_lo in
111111+ let f_n = Int64.unsigned_rem n unit_lo in
112112+ let f_m_up = if Int64.equal f_n 0L then f_m else Int64.succ f_m in
113113+ match f_m_up with
114114+ | f when geq f unit_lo_size ->
115115+ pp ppf Int64.(add (mul m unit) (mul f unit_lo))
116116+ | f ->
117117+ pf ppf "%Ld%s%Ld%s" m unit_str f unit_lo_str
118118+119119+ and pp ppf span =
120120+ let geq x y = Int64.unsigned_compare x y >= 0 in
121121+ let lt x y = Int64.unsigned_compare x y = -1 in
122122+ match span with
123123+ | sp when lt sp us -> pf ppf "%Ldns" sp
124124+ | sp when lt sp ms -> pp_si_span "\xCE\xBCs" 2 us ms ppf sp
125125+ | sp when lt sp s -> pp_si_span "ms" 2 ms s ppf sp
126126+ | sp when lt sp min -> pp_si_span "s" 1 s min ppf sp
127127+ | sp when lt sp hour -> pp_non_si "min" min "s" s 60L ppf sp
128128+ | sp when lt sp day -> pp_non_si "h" hour "min" min 60L ppf sp
129129+ | sp when lt sp year -> pp_non_si "d" day "h" hour 24L ppf sp | sp ->
130130+ let m = Int64.unsigned_div sp year in
131131+ let n = Int64.unsigned_rem sp year in
132132+ if Int64.equal n 0L then pf ppf "%Lda" m else
133133+ let f_m = Int64.unsigned_div n day in
134134+ let f_n = Int64.unsigned_rem n day in
135135+ let f_m_up = if Int64.equal f_n 0L then f_m else Int64.succ f_m in
136136+ match f_m_up with
137137+ | f when geq f 366L -> pf ppf "%Lda" (Int64.succ m)
138138+ | f -> pf ppf "%Lda%Ldd" m f
139139+140140+ let dump ppf s = Format.fprintf ppf "%Lu" s
141141+end
142142+143143+(* Monotonic timestamps *)
144144+145145+type t = int64
146146+147147+let to_uint64_ns s = s
148148+let of_uint64_ns ns = ns
149149+let min_stamp = 0L
150150+let max_stamp = -1L
151151+152152+(* Predicates *)
153153+154154+let equal = Int64.equal
155155+let compare = Int64.unsigned_compare
156156+let is_earlier t ~than = compare t than < 0
157157+let is_later t ~than = compare t than > 0
158158+159159+(* Arithmetic *)
160160+161161+let span t0 t1 = if compare t0 t1 < 0 then Int64.sub t1 t0 else Int64.sub t0 t1
162162+163163+let add_span t s =
164164+ let sum = Int64.add t s in
165165+ if compare t sum <= 0 then Some sum else None
166166+167167+let sub_span t s =
168168+ if compare t s < 0 then None else Some (Int64.sub t s)
169169+170170+(* Formatters *)
171171+172172+let pp ppf ns = Format.fprintf ppf "%Luns" ns
173173+let dump ppf ns = Format.fprintf ppf "%Lu" ns
+228
vendor/opam/mtime/src/mtime.mli
···11+(*---------------------------------------------------------------------------
22+ Copyright (c) 2015 The mtime programmers. All rights reserved.
33+ SPDX-License-Identifier: ISC
44+ ---------------------------------------------------------------------------*)
55+66+(** Monotonic time values.
77+88+ [Mtime] has platform independent support for monotonic wall-clock
99+ time. This time increases monotonically and is not subject to
1010+ operating system calendar time adjustments.
1111+1212+ {{!spans}Time spans} represent non-negative monotonic time spans
1313+ between two monotonic clock readings. {{!timestamps}Timestamps}
1414+ represent system-relative monotonic {e timestamps}, their absolute
1515+ value is meaningless but they can be compared across the processes
1616+ of an operating system run.
1717+1818+ {!Mtime_clock} provides access to a system monotonic clock. *)
1919+2020+(** {1:spans Monotonic time spans} *)
2121+2222+type span
2323+(** The type for non-negative monotonic time spans. They represent the
2424+ difference between two monotonic clock readings. If the platform's
2525+ clock has nanosecond resolution the representation guarantees that
2626+ the function {!Mtime_clock.elapsed} can measure up to
2727+ approximatively 584 Julian year spans before silently rolling over
2828+ (unlikely since this is in a single program run). *)
2929+3030+(** Monotonic time spans. *)
3131+module Span : sig
3232+3333+ (** {1:spans Monotonic time spans} *)
3434+3535+ type t = span
3636+ (** See {!Mtime.type-span}. *)
3737+3838+ val zero : span
3939+ (** [zero] is a span of 0ns. *)
4040+4141+ val one : span
4242+ (** [one] is a span of 1ns. *)
4343+4444+ val min_span : span
4545+ (** [min_span] is {!zero}. *)
4646+4747+ val max_span : span
4848+ (** [max_span] is 2{^64}-1ns. *)
4949+5050+ (** {1:preds Predicates} *)
5151+5252+ val equal : span -> span -> bool
5353+ (** [equal span span'] is [true] iff [span] and [span'] are equal. *)
5454+5555+ val compare : span -> span -> int
5656+ (** [compare span span'] orders spans by increasing duration. *)
5757+5858+ val is_shorter : span -> than:span -> bool
5959+ (** [is_shorter span ~than] is [true] iff [span] lasts less than [than]. *)
6060+6161+ val is_longer : span -> than:span -> bool
6262+ (** [is_longer span ~than] is [true] iff [span] lasts more than [than]. *)
6363+6464+ (** {1:arith Arithmetic} *)
6565+6666+ val add : span -> span -> span
6767+ (** [add span span'] is [span + span'].
6868+6969+ {b Warning.} Rolls over on overflow. *)
7070+7171+ val abs_diff : span -> span -> span
7272+ (** [abs_diff span span'] is the absolute difference between
7373+ [span] and [span']. *)
7474+7575+ (** {1:const Durations} *)
7676+7777+ val ( * ) : int -> span -> span
7878+ (** [n * dur] is [n] times duration [dur].
7979+8080+ {b Warning.} Does not check for overflow or that [n] is
8181+ positive. *)
8282+8383+ val ns : span
8484+ (** [ns] is a nanosecond duration, 1·10{^-9}s.
8585+ @since 1.4.0 *)
8686+8787+ val us : span
8888+ (** [us] is a microsecond duration, 1·10{^-6}s.
8989+ @since 1.4.0 *)
9090+9191+ val ms : span
9292+ (** [ms] is a millisecond duration, 1·10{^-3}s.
9393+ @since 1.4.0 *)
9494+9595+ val s : span
9696+ (** [s] is a second duration, 1s.
9797+ @since 1.4.0 *)
9898+9999+ val min : span
100100+ (** [min] is a minute duration, 60s.
101101+ @since 1.4.0 *)
102102+103103+ val hour : span
104104+ (** [hour] is an hour duration, 3600s.
105105+ @since 1.4.0 *)
106106+107107+ val day : span
108108+ (** [day] is a day duration, 86'400s.
109109+ @since 1.4.0 *)
110110+111111+ val year : span
112112+ (** [year] is a Julian year duration (365.25 days), 31'557'600s. *)
113113+114114+ (** {1:convert Converting} *)
115115+116116+ val to_uint64_ns : span -> int64
117117+ (** [to_uint64_ns span] is [span] as an {e unsigned} 64-bit integer
118118+ nanosecond span. *)
119119+120120+ val of_uint64_ns : int64 -> span
121121+ (** [of_uint64_ns u] is the {e unsigned} 64-bit integer nanosecond
122122+ span [u] as a span. *)
123123+124124+ val of_float_ns : float -> span option
125125+ (** [of_float_ns f] is the positive floating point nanosecond span [f] as
126126+ a span. This is [None] if [f] is negative, non finite, or
127127+ larger or equal than 2{^53} (~104 days, the largest exact floating point
128128+ integer).
129129+ @since 2.0.0 *)
130130+131131+ val to_float_ns : span -> float
132132+ (** [to_float_ns s] is [span] as a nanosecond floating point span.
133133+ Note that if [s] is larger than 2{^53} (~104 days, the largest
134134+ exact floating point integer) the result is an approximation and
135135+ will not round trip with {!of_float_ns}.
136136+ @since 2.0.0 *)
137137+138138+ (** {1:fmt Formatters} *)
139139+140140+ val pp : Format.formatter -> span -> unit
141141+ (** [pp] formats spans according to their magnitude using SI
142142+ prefixes on seconds and accepted non-SI units. Years are counted
143143+ in Julian years (365.25 SI-accepted days) as
144144+ {{:http://www.iau.org/publications/proceedings_rules/units/}defined}
145145+ by the International Astronomical Union.
146146+147147+ Rounds towards positive infinity, i.e. over approximates, no
148148+ duration is formatted shorter than it is.
149149+150150+ The output is UTF-8 encoded, it uses U+03BC for [µs]
151151+ (10{^-6}[s]). *)
152152+153153+ val dump : Format.formatter -> t -> unit
154154+ (** [dump ppf span] formats an unspecified raw representation of [span]
155155+ on [ppf]. *)
156156+157157+ (**/**)
158158+159159+ val unsafe_of_uint64_ns_option : int64 option -> t option
160160+end
161161+162162+(** {1:timestamps Monotonic timestamps}
163163+164164+ {b Note.} Only use timestamps if you need inter-process time
165165+ correlation, otherwise prefer {!Mtime_clock.elapsed} and
166166+ {{!Mtime_clock.counters}counters}. *)
167167+168168+type t
169169+(** The type for monotonic timestamps relative to an indeterminate
170170+ system-wide event (e.g. last startup). Their absolute value has no
171171+ meaning but can be used for inter-process time correlation. *)
172172+173173+val to_uint64_ns : t -> int64
174174+(** [to_uint64_ns t] is [t] as an {e unsigned} 64-bit integer
175175+ nanosecond timestamp. The absolute value is meaningless. *)
176176+177177+val of_uint64_ns : int64 -> t
178178+(** [to_uint64_ns t] is [t] is an {e unsigned} 64-bit integer
179179+ nanosecond timestamp as a timestamp.
180180+181181+ {b Warning.} Timestamps returned by this function should only be
182182+ used with other timestamp values that are know to come from the
183183+ same operating system run. *)
184184+185185+val min_stamp : t
186186+(** [min_stamp] is the earliest timestamp. *)
187187+188188+val max_stamp : t
189189+(** [max_stamp] is the latest timestamp. *)
190190+191191+(** {2:preds Predicates} *)
192192+193193+val equal : t -> t -> bool
194194+(** [equal t t'] is [true] iff [t] and [t'] are equal. *)
195195+196196+val compare : t -> t -> int
197197+(** [compare t t'] orders timestamps by increasing time. *)
198198+199199+val is_earlier : t -> than:t -> bool
200200+(** [is_earlier t ~than] is [true] iff [t] occurred before [than]. *)
201201+202202+val is_later : t -> than:t -> bool
203203+(** [is_later t ~than] is [true] iff [t] occurred after [than]. *)
204204+205205+(** {2:arith Arithmetic} *)
206206+207207+val span : t -> t -> span
208208+(** [span t t'] is the span between [t] and [t'] regardless of the
209209+ order between [t] and [t']. *)
210210+211211+val add_span : t -> span -> t option
212212+(** [add_span t s] is the timestamp [s] units later than [t] or [None] if
213213+ the result overflows. *)
214214+215215+val sub_span : t -> span -> t option
216216+(** [sub_span t s] is the timestamp [s] units earlier than [t] or
217217+ [None] if the result underflows. *)
218218+219219+(** {2:fmt Formatting} *)
220220+221221+val pp : Format.formatter -> t -> unit
222222+(** [pp] formats [t] as an {e unsigned} 64-bit integer
223223+ nanosecond timestamp. Note that the absolute value is
224224+ meaningless. *)
225225+226226+val dump : Format.formatter -> t -> unit
227227+(** [dump ppf t] formats an unspecified raw representation of [t] on
228228+ [ppf]. *)