/*----------------------------------------------------------------------------
   Copyright 2012-2021, Microsoft Research, Daan Leijen

   Licensed under the Apache License, Version 2.0 ("The Licence"). You may not
   use this file except in compliance with the License. A copy of the License
   can be found in the LICENSE file at the root of this distribution.
----------------------------------------------------------------------------*/

/* High resolution timer.
*/
module std/time/timerstd/time/timer

import std/num/float64std/num/float64
import std/num/ddoublestd/num/ddouble
import std/time/durationstd/time/duration
import std/time/instantstd/time/instant

extern import
  c  file "timer-inline.c"
  cs file "timer-inline.cs"
  js file "timer-inline.js"

// -----------------------------------------------------------
// Ticks
// -----------------------------------------------------------

// Return a high-resolution time stamp in fractional SI seconds.
// The duration is guaranteed to be monotonically increasing
// and have at least millisecond resolution.
pub fun ticksstd/time/timer/ticks: () -> ndet duration()result: -> ndet duration : ndetstd/core/types/ndet: X durationstd/time/duration/duration: V
  val (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)secssecs: float64,fracfrac: float64)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) = xticksstd/time/timer/xticks: () -> ndet (float64, float64)()
  durationstd/time/duration/float64frac/duration: (secs : float64, frac : float64) -> ndet duration(secssecs: float64,fracfrac: float64)

extern xticksstd/time/timer/xticks: () -> ndet (float64, float64)() : ndetstd/core/types/ndet: X (std/core/types/tuple2: (V, V) -> Vfloat64std/core/types/float64: V,float64std/core/types/float64: V)
  c  "kk_timer_ticks_tuple"
  cs "_Timer.Ticks"
  js "_ticks"

// Return the smallest time difference in seconds that `ticks` can measure.
pub fun ticks-resolutionstd/time/timer/ticks-resolution: () -> ndet duration()result: -> ndet duration : ndetstd/core/types/ndet: X durationstd/time/duration/duration: V
  durationstd/time/duration/float64/duration: (secs : float64) -> ndet duration(xticks-resolutionstd/time/timer/xticks-resolution: () -> ndet float64())

// Return the smallest time difference in seconds that `ticks` can measure.
extern xticks-resolutionstd/time/timer/xticks-resolution: () -> ndet float64() : ndetstd/core/types/ndet: X float64std/core/types/float64: V
  c  "kk_timer_dresolution"
  cs "_Timer.TicksResolution"
  js "_ticks_resolution"

// Return the number of fractional seconds that it takes to evaluate `action`.
pub fun elapsedstd/time/timer/elapsed: forall<a,e> (action : () -> <ndet|e> a) -> <ndet|e> (duration, a)( actionaction: () -> <ndet|$82> $81 : () -> <ndetstd/core/types/ndet: X|std/core/types/effect-extend: (X, E) -> Eee: E> aa: V )result: -> <ndet|116> (duration, 115) : <ndetstd/core/types/ndet: X|std/core/types/effect-extend: (X, E) -> Eee: E> (std/core/types/tuple2: (V, V) -> Vdurationstd/time/duration/duration: V,aa: V)
  val t0t0: duration = ticksstd/time/timer/ticks: () -> <ndet|$82> duration()
  val xx: $81 = actionaction: () -> <ndet|$82> $81()
  val t1t1: duration = ticksstd/time/timer/ticks: () -> <ndet|$82> duration()
  (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)t1t1: duration -std/time/duration/(-): (d : duration, e : duration) -> <ndet|$82> duration t0t0: duration, xx: $81)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)

// Measure the number of fractional seconds that it takes to evaluate `action`, and print `msg` postfixed with the
// measured time in millisecond resolution.
pub fun print-elapsedstd/time/timer/print-elapsed: forall<a,e> (action : () -> <ndet,console|e> a, msg : ? string) -> <ndet,console|e> a( actionaction: () -> <ndet,console|$124> $123 : () -> <ndetstd/core/types/ndet: X,consolestd/core/console/console: X|std/core/types/effect-extend: (X, E) -> Eee: E> aa: V, msgmsg: ? string : stringstd/core/types/string: V = "elapsed"literal: string
count= 7
)result: -> <ndet,console|256> 255 : <ndetstd/core/types/ndet: X,consolestd/core/console/console: X|std/core/types/effect-extend: (X, E) -> Eee: E> aa: V val (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)tt: duration,xx: $123)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) = elapsedstd/time/timer/elapsed: (action : () -> <ndet,console|$124> $123) -> <ndet,console|$124> (duration, $123)(actionaction: () -> <ndet,console|$124> $123) printlnstd/core/console/string/println: (s : string) -> <console,ndet|$124> ()( msgmsg: string ++std/core/types/(++): (x : string, y : string) -> <console,ndet|$124> string " "literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> <console,ndet|$124> string tt: duration.showstd/time/duration/show: (d : duration, max-prec : ? int) -> <console,ndet|$124> string(3literal: int
dec = 3
hex8 = 0x03
bit8 = 0b00000011
) )
xx: $123