From e69717d9e0cd107f461abff85f255be82d7bd69b Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 3 Sep 2019 18:07:28 +0000 Subject: Big wallclock/stopwatch refactor. It was long overdue. * --enable-clock and --enable-monotonic are gone * tain_sysclock() has been renamed tain_wallclock_read() * tain_wallclock_read() reads from CLOCK_REALTIME (or gettimeofday()) * tain_clockmon[_init]() have been renamed to tain_stopwatch_[read|init]() and now accept a monotonic clock name as an extra argument * tain_now() points to the system (wall) clock by default * tain_now_set_[stopwatch|wallclock]() can be used to switch Now to make a pass on all skarnet.org programs and add a tain_now_set_stopwatch() call everywhere needed... >.> --- AUTHORS | 2 + NEWS | 5 ++ configure | 37 ++-------- doc/flags.html | 30 -------- doc/libstddjb/tai.html | 124 ++++++++++++++++----------------- doc/upgrade.html | 6 ++ package/deps.mak | 12 ++-- src/include/skalibs/tai.h | 23 +++--- src/libstddjb/sysclock_get.c | 10 +-- src/libstddjb/sysclock_set.c | 14 +--- src/libstddjb/tain_clockmon.c | 47 ------------- src/libstddjb/tain_now.c | 44 +----------- src/libstddjb/tain_now_set_stopwatch.c | 36 ++++++++++ src/libstddjb/tain_now_set_wallclock.c | 10 +++ src/libstddjb/tain_stopwatch.c | 50 +++++++++++++ src/libstddjb/tain_sysclock.c | 10 --- src/libstddjb/tain_wallclock_read.c | 10 +++ src/libstddjb/timestamp_r.c | 2 +- src/sysdeps/tryclockboot.c | 10 +++ 19 files changed, 224 insertions(+), 258 deletions(-) delete mode 100644 src/libstddjb/tain_clockmon.c create mode 100644 src/libstddjb/tain_now_set_stopwatch.c create mode 100644 src/libstddjb/tain_now_set_wallclock.c create mode 100644 src/libstddjb/tain_stopwatch.c delete mode 100644 src/libstddjb/tain_sysclock.c create mode 100644 src/libstddjb/tain_wallclock_read.c create mode 100644 src/sysdeps/tryclockboot.c diff --git a/AUTHORS b/AUTHORS index cc2b7ee..d89bd8f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -34,3 +34,5 @@ Thanks to: Samuel Holland Jan Bramkamp Johannes Nixdorf + Casper Ti. Vector + Guillermo diff --git a/NEWS b/NEWS index 6d05a58..8aa085e 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,11 @@ In 2.9.0.0 that means better autotools emulation). - Build more friendly to recent glibc. - Refactoring and optimization of scanning and formatting functions. + - Refactoring of stopwatch/wallclock functions. The --enable-clock +and --enable-monotonic configure switches have been removed. +tain_now() can now be set at run time to use a wall clock (default, +or via tain_now_set_wallclock()) or a stopwatch (via +tain_now_set_stopwatch()), instead of it being fixed at build time. In 2.8.1.0 diff --git a/configure b/configure index 151662f..b8c76fc 100755 --- a/configure +++ b/configure @@ -42,8 +42,6 @@ $package options: --disable-ipv6 do not build IPv6 support [enabled] --enable-iopause-select prefer select() over poll() for iopause implementation [disabled] --enable-tai-clock assume the system clock is TAI-10 instead of UTC [disabled] - --enable-clock use clock_gettime() instead of gettimeofday() [disabled] - --enable-monotonic count time with CLOCK_MONOTONIC instead of CLOCK_REALTIME --with-default-path=PATH default executable search path [/usr/bin:/bin] EOF @@ -241,8 +239,6 @@ slashpackage=false ipv6=true select=false taiclock=false -clockrt=false -clockmon=false ddefaultpath=/usr/bin:/bin defaultpath=$ddefaultpath dpathorig=true @@ -284,10 +280,8 @@ for arg ; do --disable-iopause-select|--enable-iopause-select=no) select=false ;; --enable-tai-clock|--enable-tai-clock=yes) taiclock=true ;; --disable-tai-clock|--enable-tai-clock=no) taiclock=false ;; - --enable-clock|--enable-clock=yes) clockrt=true ;; - --disable-clock|--enable-clock=no) clockrt=false ;; - --enable-monotonic|--enable-monotonic=yes) clockmon=true ;; - --disable-monotonic|--enable-monotonic=no) clockmon=false ;; + --enable-monotonic|--enable-monotonic=yes) echo "$0: warning: --enable-monotonic is now obsolete" 1>&2 ;; + --disable-monotonic|--enable-monotonic=no) ;; --with-default-path=*) defaultpath=${arg#*=} ; dpathorig=false ;; --without-default-path) defaultpath=$ddefaultpath ; dpathorig=true ;; --enable-*|--disable-*|--with-*|--without-*|--*dir=*) ;; @@ -458,11 +452,6 @@ else #undef SKALIBS_TARGET #define SKALIBS_TARGET "$target" -#undef SKALIBS_BSD_SUCKS -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__DragonFly__) -# define SKALIBS_BSD_SUCKS -#endif - EOF exec 3>&1 @@ -474,23 +463,19 @@ EOF hasclock=true sysclock_lib=`trylibs clockrt 'clock_gettime()' -lrt` || hasclock=false - if $clockrt ; then - tainnow_lib=$sysclock_lib - else - tainnow_lib= - fi + tainnow_lib=$sysclock_lib echo "$sysclock_lib" > $sysdeps/sysclock.lib echo "$tainnow_lib" > $sysdeps/tainnow.lib echo "#undef ${package_macro_name}_HASCLOCKRT" >> $sysdeps/sysdeps.h if $hasclock ; then echo 'clockrt: yes' >> $sysdeps/sysdeps echo "#define ${package_macro_name}_HASCLOCKRT" >> $sysdeps/sysdeps.h - echo >> $sysdeps/sysdeps.h - choose cl clockmon CLOCKMON CLOCK_MONOTONIC $sysclock_lib else echo 'clockrt: no' >> $sysdeps/sysdeps - echo >> $sysdeps/sysdeps.h fi + echo >> $sysdeps/sysdeps.h + choose cl clockmon CLOCKMON CLOCK_MONOTONIC $sysclock_lib + choose cl clockboot CLOCKBOOT CLOCK_BOOTTIME $sysclock_lib hasspawn=true spawn_lib=`trylibs posixspawn 'posix_spawn()' -lrt` || hasspawn=false @@ -664,16 +649,6 @@ if $taiclock ; then else echo "#undef ${package_macro_name}_FLAG_CLOCKISTAI" fi -if $clockrt ; then - echo "#define ${package_macro_name}_FLAG_USERT" -else - echo "#undef ${package_macro_name}_FLAG_USERT" -fi -if $clockmon ; then - echo "#define ${package_macro_name}_FLAG_USEMON" -else - echo "#undef ${package_macro_name}_FLAG_USEMON" -fi if $ipv6 ; then echo "#define ${package_macro_name}_FLAG_WANTIPV6" else diff --git a/doc/flags.html b/doc/flags.html index c901b1c..b74d344 100644 --- a/doc/flags.html +++ b/doc/flags.html @@ -175,36 +175,6 @@ and settimeofday() interfaces will be used. This is the default, and it's usually safe.

-

--enable-monotonic

- -

- Unless you have an accurate hardware system clock and you set it -on a linear time scale such as TAI-10 instead of UTC (see above), it is -generally a bad idea to trust the system clock for precise time interval -measurements. Single Unix recommends the use of clock_gettime() -with the CLOCK_MONOTONIC option to do such measurements: a stopwatch, not -a wall clock. However: -

- -
    -
  • CLOCK_MONOTONIC is even less portable than CLOCK_REALTIME.
  • -
  • It's a bit tricky to emulate absolute time calculations based on -CLOCK_MONOTONIC.
  • -
- -

- If --enable-monotonic is set, then the absolute time given by the -tain_now() call will be computed with CLOCK_MONOTONIC. This -will ensure precise time arithmetic but may drift away from the system -clock. -

- -

- Otherwise, tain_now() will -return a time based on the system clock, and not use CLOCK_MONOTONIC. -This is the default. -

-

--disable-ipv6

diff --git a/doc/libstddjb/tai.html b/doc/libstddjb/tai.html index 8440c78..3826e80 100644 --- a/doc/libstddjb/tai.html +++ b/doc/libstddjb/tai.html @@ -130,12 +130,9 @@ it fails.

int sysclock_get (tain_t *a)
-Reads the current value of the system clock into *a, with -a 1-nanosecond (resp. 1-microsecond ) precision if skalibs has been -configured with (resp. without) the ---enable-clock option. -Returns 1 if it succeeds or 0 (and sets errno) if it -fails. Note that despite being a tain_t, *a +Reads the current value of the system clock (as in CLOCK_REALTIME) into *a. +Returns 1 if it succeeds or 0 (and sets errno) if it fails. +Note that despite being a tain_t, *a does not contain a TAI value - it only contains an internal, Y2038-safe representation of the value of the system clock, which should be either TAI-10 or UTC. You should not use @@ -150,103 +147,106 @@ function directly unless you know exactly what you are doing.

- int tain_sysclock (tain_t *a)
-Reads the current time into *a, as a TAI64N value, -with a 1-nanosecond (resp. 1-microsecond) precision if skalibs -has been configured with (resp. without) the ---enable-clock -option. Returns 1 if it succeeds or 0 (and sets errno) if it -fails. - Here a contains a valid TAI64N stamp, no matter what the + int tain_wallclock_read (tain_t *a)
+Reads the current time into *a, as a TAI64N value. +Returns 1 if it succeeds or 0 (and sets errno) if it fails. +Here a contains a valid TAI64N stamp, no matter what the system clock is set to: arithmetic operations can be performed on it.

int tain_setnow (tain_t const *a)
-Sets the current time to *a, with a 1-nanosecond -(resp. 1-microsecond) precision if skalibs has been configured -with (resp. without) the ---enable-clock -option. Returns 1 if it succeeds or 0 (and sets errno) if it -fails. a must contain a valid TAI64N stamp; proper +Sets the current time to *a. +Returns 1 if it succeeds or 0 (and sets errno) if it fails. +a must contain a valid TAI64N stamp; proper operations will be automatically run to convert that stamp into the right format for the system clock.

+

+ void tain_now_set_wallclock (void)
+Tells skalibs that future invocations of tain_now() +(see below) should use a wall clock, i.e. the system time +as returned by clock_gettime(CLOCK_REALTIME) or +gettimeofday(). This is the default: it is not necessary +to call this function before invoking tain_now() at the +start of a program. +

+

Stopwatch operations

- The following 3 operations are only defined if your system -provides the +The following two operations can only succeed if your system provides the clock_gettime() -primitive with the CLOCK_MONOTONIC option. +primitive with at least one of the CLOCK_MONOTONIC or CLOCK_BOOTTIME clocks. +Otherwise, they will fail with errno set to ENOSYS.

- int tain_clockmon_init (tain_t *offset)
-Initializes a stopwatch in *offset. The actual value of + int tain_stopwatch_init (clock_t cl, tain_t *offset)
+Initializes a stopwatch in *offset, using a clock named cl. +Typically, cl is something like CLOCK_MONOTONIC, when it is defined +by the system. The actual value of *offset is meaningless to the user; offset's only -use is to be given as a second parameter to tain_clockmon(). +use is to be given as a second parameter to tain_stopwatch_read(). The function returns 1 if it succeeds or 0 (and sets errno) if it fails.

- What tain_clockmon_init() does is synchronize the "stopwatch -clock" (CLOCK_MONOTONIC) to the system clock. Right after -tain_clockmon_init() has been called, the absolute times given -by tain_clockmon() and tain_sysclock() are similar. Then, -depending on the accuracy of the system clock, a drift may appear; calling -tain_clockmon_init() again resets that drift to zero. + What tain_stopwatch_init() does is synchronize the "stopwatch +clock" to the system clock. Right after tain_stopwatch_init() +has been called, the absolute times given +by tain_stopwatch_read() and tain_wallclock_read() are +the same. Then, depending on the accuracy of the system clock, a drift +may appear; calling tain_stopwatch_init() again resets that drift +to zero.

- int tain_clockmon (tain_t *a, tain_t const *offset)
+ int tain_stopwatch_read (tain_t *a, clock_t cl, tain_t const *offset)
Gives the absolute time, as a TAI64N value, in *a. This absolute time is computed as a linear increase (as measured with -CLOCK_MONOTONIC) since the last time tain_clockmon_init() -was called with parameter offset. tain_clockmon() +the cl clock, which should be a monotonic clock such as +CLOCK_MONOTONIC) since the last time tain_stopwatch_init() +was called with parameter offset. tain_stopwatch_read() guarantees precise time interval measurements; however, the time it -gives can slightly differ from the result of tain_sysclock(). +gives can slightly differ from the result of tain_wallclock_read(). The function returns 1 if it succeeds or 0 (and sets errno) if it fails.

-

All-purpose time reading

-

- int tain_init (void)
-If skalibs has been configured with the ---enable-monotonic option: this -function initializes a process-global stopwatch, that future -tain_now invocations will depend on. -Without the --enable-monotonic option: this -function does nothing. -The function returns 1 if it succeeds or 0 (and sets errno) if it fails. + void tain_now_set_stopwatch (void)
+Tells skalibs that future invocations of tain_now() +(see below) should use a stopwatch, i.e. the system time +as returned by clock_gettime(CLOCK_MONOTONIC) or similar, +if supported by the system. This is useful when it is more important +for a program to compute unchanging time intervals no matter what the +system clock does, than to display absolute time that is in sync with a +human view of time (which is the cause and reason of most system clock +jumps).
+If no monotonic clock is supported by the system, this function does +nothing (and tain_now() will keep using a wall clock).

+

All-purpose time reading

+

int tain_now (tain_t *a)
Writes the current time, as a TAI value, to *a. This is the -function you should use to read time by default. It returns 1 if it succeeds or +function you should use by default. It returns 1 if it succeeds or 0 (and sets errno) if it fails.

- If skalibs has been configured with the ---enable-monotonic option: -tain_now() is computed as a linear increase from the last time -tain_init() was called. (If tain_init() has never -been called before, the first invocation of tain_now() -automatically calls tain_init().) - Without the --enable-monotonic option: -tain_now() is the same as tain_sysclock(). -

- -

- If the above is unclear to you: just use tain_now() -everytime you need to read time, and you will always get a reasonable -approximation of the current time, in a format suited for arithmetic -computations. + tain_now() relies on the concept that there is One True Time Source +for the process, and that is where it reads time from. By default, the +One True Time Source is the system clock (a wall clock), and tain_now() +is actually an alias to tain_wallclock_read(). At the start of a +program, calling tain_now_set_stopwatch() will define a monotonic +clock (if supported by the system) as the One True Time Source, which will +make tain_now() resistant to system clock jumps, but will also +make it unsuitable for timestamping.

Converting to/from libc representations

diff --git a/doc/upgrade.html b/doc/upgrade.html index f56629e..76c1973 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -23,6 +23,12 @@
  • The configure script now emulates autotools-created configure scripts more closely. In particular, it's now possible to declare an out-of-path compiler in CC.
  • +
  • tain_* functions dealing with wall clocks and stopwatches +have been refactored. The --enable-clock and --enable-monotonic +configure switches have been removed. tain_now() can now be told at run +time to use a wall clock (default, or via tain_now_set_wallclock()) or a +stopwatch (via tain_now_set_stopwatch()), instead of it being fixed at +build time.
  • in 2.8.1.0

    diff --git a/package/deps.mak b/package/deps.mak index 4fc5850..24d7436 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -598,8 +598,8 @@ src/libstddjb/sysclock_from_ltm64.o src/libstddjb/sysclock_from_ltm64.lo: src/li src/libstddjb/sysclock_from_tai.o src/libstddjb/sysclock_from_tai.lo: src/libstddjb/sysclock_from_tai.c src/include/skalibs/config.h src/include/skalibs/djbtime.h src/include/skalibs/tai.h src/libstddjb/sysclock_from_tain.o src/libstddjb/sysclock_from_tain.lo: src/libstddjb/sysclock_from_tain.c src/include/skalibs/tai.h src/libstddjb/sysclock_from_utc.o src/libstddjb/sysclock_from_utc.lo: src/libstddjb/sysclock_from_utc.c src/include/skalibs/config.h src/include/skalibs/djbtime.h src/include/skalibs/uint64.h -src/libstddjb/sysclock_get.o src/libstddjb/sysclock_get.lo: src/libstddjb/sysclock_get.c src/include/skalibs/config.h src/include/skalibs/sysdeps.h src/include/skalibs/tai.h -src/libstddjb/sysclock_set.o src/libstddjb/sysclock_set.lo: src/libstddjb/sysclock_set.c src/include/skalibs/config.h src/include/skalibs/nonposix.h src/include/skalibs/sysdeps.h src/include/skalibs/tai.h +src/libstddjb/sysclock_get.o src/libstddjb/sysclock_get.lo: src/libstddjb/sysclock_get.c src/include/skalibs/sysdeps.h src/include/skalibs/tai.h +src/libstddjb/sysclock_set.o src/libstddjb/sysclock_set.lo: src/libstddjb/sysclock_set.c src/include/skalibs/nonposix.h src/include/skalibs/sysdeps.h src/include/skalibs/tai.h src/libstddjb/tai_add.o src/libstddjb/tai_add.lo: src/libstddjb/tai_add.c src/include/skalibs/tai.h src/libstddjb/tai_from_localtm.o src/libstddjb/tai_from_localtm.lo: src/libstddjb/tai_from_localtm.c src/include/skalibs/djbtime.h src/include/skalibs/uint64.h src/libstddjb/tai_from_ltm64.o src/libstddjb/tai_from_ltm64.lo: src/libstddjb/tai_from_ltm64.c src/libstddjb/djbtime-internal.h src/include/skalibs/djbtime.h @@ -615,7 +615,6 @@ src/libstddjb/tai_unpack_little.o src/libstddjb/tai_unpack_little.lo: src/libstd src/libstddjb/tain_add.o src/libstddjb/tain_add.lo: src/libstddjb/tain_add.c src/include/skalibs/tai.h src/libstddjb/tain_addsec.o src/libstddjb/tain_addsec.lo: src/libstddjb/tain_addsec.c src/include/skalibs/tai.h src/include/skalibs/uint64.h src/libstddjb/tain_approx.o src/libstddjb/tain_approx.lo: src/libstddjb/tain_approx.c src/include/skalibs/tai.h -src/libstddjb/tain_clockmon.o src/libstddjb/tain_clockmon.lo: src/libstddjb/tain_clockmon.c src/include/skalibs/sysdeps.h src/include/skalibs/tai.h src/libstddjb/tain_fmt.o src/libstddjb/tain_fmt.lo: src/libstddjb/tain_fmt.c src/include/skalibs/fmtscan.h src/include/skalibs/tai.h src/libstddjb/tain_frac.o src/libstddjb/tain_frac.lo: src/libstddjb/tain_frac.c src/include/skalibs/tai.h src/libstddjb/tain_from_localtmn.o src/libstddjb/tain_from_localtmn.lo: src/libstddjb/tain_from_localtmn.c src/include/skalibs/djbtime.h @@ -630,19 +629,22 @@ src/libstddjb/tain_half.o src/libstddjb/tain_half.lo: src/libstddjb/tain_half.c src/libstddjb/tain_infinite_relative.o src/libstddjb/tain_infinite_relative.lo: src/libstddjb/tain_infinite_relative.c src/include/skalibs/tai.h src/libstddjb/tain_less.o src/libstddjb/tain_less.lo: src/libstddjb/tain_less.c src/include/skalibs/tai.h src/libstddjb/tain_nano500.o src/libstddjb/tain_nano500.lo: src/libstddjb/tain_nano500.c src/include/skalibs/tai.h -src/libstddjb/tain_now.o src/libstddjb/tain_now.lo: src/libstddjb/tain_now.c src/include/skalibs/config.h src/include/skalibs/sysdeps.h src/include/skalibs/tai.h +src/libstddjb/tain_now.o src/libstddjb/tain_now.lo: src/libstddjb/tain_now.c src/include/skalibs/tai.h +src/libstddjb/tain_now_set_stopwatch.o src/libstddjb/tain_now_set_stopwatch.lo: src/libstddjb/tain_now_set_stopwatch.c src/include/skalibs/tai.h +src/libstddjb/tain_now_set_wallclock.o src/libstddjb/tain_now_set_wallclock.lo: src/libstddjb/tain_now_set_wallclock.c src/include/skalibs/tai.h src/libstddjb/tain_pack.o src/libstddjb/tain_pack.lo: src/libstddjb/tain_pack.c src/include/skalibs/tai.h src/include/skalibs/uint32.h src/libstddjb/tain_pack_little.o src/libstddjb/tain_pack_little.lo: src/libstddjb/tain_pack_little.c src/include/skalibs/tai.h src/include/skalibs/uint32.h src/libstddjb/tain_relative_from_timespec.o src/libstddjb/tain_relative_from_timespec.lo: src/libstddjb/tain_relative_from_timespec.c src/include/skalibs/tai.h src/libstddjb/tain_relative_from_timeval.o src/libstddjb/tain_relative_from_timeval.lo: src/libstddjb/tain_relative_from_timeval.c src/include/skalibs/tai.h src/libstddjb/tain_scan.o src/libstddjb/tain_scan.lo: src/libstddjb/tain_scan.c src/include/skalibs/fmtscan.h src/include/skalibs/tai.h src/libstddjb/tain_setnow.o src/libstddjb/tain_setnow.lo: src/libstddjb/tain_setnow.c src/include/skalibs/tai.h +src/libstddjb/tain_stopwatch.o src/libstddjb/tain_stopwatch.lo: src/libstddjb/tain_stopwatch.c src/include/skalibs/sysdeps.h src/include/skalibs/tai.h src/libstddjb/tain_sub.o src/libstddjb/tain_sub.lo: src/libstddjb/tain_sub.c src/include/skalibs/tai.h -src/libstddjb/tain_sysclock.o src/libstddjb/tain_sysclock.lo: src/libstddjb/tain_sysclock.c src/include/skalibs/tai.h src/libstddjb/tain_to_millisecs.o src/libstddjb/tain_to_millisecs.lo: src/libstddjb/tain_to_millisecs.c src/include/skalibs/tai.h src/include/skalibs/uint64.h src/libstddjb/tain_ulong.o src/libstddjb/tain_ulong.lo: src/libstddjb/tain_ulong.c src/include/skalibs/tai.h src/libstddjb/tain_unpack.o src/libstddjb/tain_unpack.lo: src/libstddjb/tain_unpack.c src/include/skalibs/tai.h src/include/skalibs/uint32.h src/libstddjb/tain_unpack_little.o src/libstddjb/tain_unpack_little.lo: src/libstddjb/tain_unpack_little.c src/include/skalibs/tai.h src/include/skalibs/uint32.h +src/libstddjb/tain_wallclock_read.o src/libstddjb/tain_wallclock_read.lo: src/libstddjb/tain_wallclock_read.c src/include/skalibs/tai.h src/libstddjb/tain_zero.o src/libstddjb/tain_zero.lo: src/libstddjb/tain_zero.c src/include/skalibs/tai.h src/libstddjb/time_from_tai.o src/libstddjb/time_from_tai.lo: src/libstddjb/time_from_tai.c src/include/skalibs/bsdsnowflake.h src/include/skalibs/sysdeps.h src/include/skalibs/tai.h src/include/skalibs/uint64.h src/libstddjb/time_from_tai_relative.o src/libstddjb/time_from_tai_relative.lo: src/libstddjb/time_from_tai_relative.c src/include/skalibs/bsdsnowflake.h src/include/skalibs/sysdeps.h src/include/skalibs/tai.h diff --git a/src/include/skalibs/tai.h b/src/include/skalibs/tai.h index f3699ce..2bdf524 100644 --- a/src/include/skalibs/tai.h +++ b/src/include/skalibs/tai.h @@ -86,19 +86,24 @@ extern int timespec_from_tain_relative (struct timespec *, tain_t const *) ; extern int timespec_from_tain (struct timespec *, tain_t const *) ; extern int timespec_sysclock_from_tain (struct timespec *, tain_t const *) ; -extern int sysclock_get (tain_t *) ; -extern int tain_sysclock (tain_t *) ; +typedef int tain_clockread_func_t (tain_t *) ; +typedef tain_clockread_func_t *tain_clockread_func_t_ref ; + extern int tain_from_sysclock (tain_t *, tain_t const *) ; extern int sysclock_from_tain (tain_t *, tain_t const *) ; -#define tain_sysclock_g() tain_sysclock(&STAMP) -extern int tain_clockmon_init (tain_t *) ; -extern int tain_clockmon (tain_t *, tain_t const *) ; -#define tain_clockmon_g(offset) tain_clockmon(&STAMP, (offset)) -extern int tain_init (void) ; -extern int tain_now (tain_t *) ; -#define tain_now_g() tain_now(&STAMP) +extern tain_clockread_func_t sysclock_get ; +extern tain_clockread_func_t tain_wallclock_read ; +#define tain_wallclock_read_g() tain_wallclock_read(&STAMP) +extern int tain_stopwatch_init (clock_t, tain_t *) ; +extern int tain_stopwatch_read (tain_t *, clock_t, tain_t const *) ; +#define tain_stopwatch_read_g(cl, offset) tain_stopwatch_read(&STAMP, (cl), offset) +extern tain_clockread_func_t_ref tain_now ; +#define tain_now_g() (*tain_now)(&STAMP) #define tain_copynow(t) (*(t) = STAMP) +extern void tain_now_set_wallclock (void) ; +extern void tain_now_set_stopwatch (void) ; + extern int sysclock_set (tain_t const *) ; extern int tain_setnow (tain_t const *) ; diff --git a/src/libstddjb/sysclock_get.c b/src/libstddjb/sysclock_get.c index 3d14f96..6c5041d 100644 --- a/src/libstddjb/sysclock_get.c +++ b/src/libstddjb/sysclock_get.c @@ -1,17 +1,9 @@ /* ISC license. */ -#include #include #include -#ifdef SKALIBS_FLAG_USERT -# ifndef SKALIBS_HASCLOCKRT -# undef SKALIBS_FLAG_USERT -# warning "SKALIBS_FLAG_USERT set but SKALIBS_HASCLOCKRT not found. Clearing SKALIBS_FLAG_USERT." -# endif -#endif - -#ifdef SKALIBS_FLAG_USERT +#ifdef SKALIBS_HASCLOCKRT #include diff --git a/src/libstddjb/sysclock_set.c b/src/libstddjb/sysclock_set.c index 0ec51c6..57e2abe 100644 --- a/src/libstddjb/sysclock_set.c +++ b/src/libstddjb/sysclock_set.c @@ -2,24 +2,16 @@ /* MT-unsafe */ -#include #include -#ifdef SKALIBS_FLAG_USERT -# ifndef SKALIBS_HASCLOCKRT -# undef SKALIBS_FLAG_USERT -# warning "SKALIBS_FLAG_USERT set but SKALIBS_HASCLOCKRT not found. Clearing SKALIBS_FLAG_USERT." -# endif -#endif - -#ifndef SKALIBS_FLAG_USERT +#ifndef SKALIBS_HASCLOCKRT # ifndef SKALIBS_HASSETTIMEOFDAY -# error "SKALIBS_FLAG_USERT clear but SKALIBS_HASSETTIMEOFDAY not found. How do your set your system clock?" +# error "neither clockrt nor settimeofday sysdeps are present. How do your set your system clock?" # endif #endif -#ifdef SKALIBS_FLAG_USERT +#ifdef SKALIBS_HASCLOCKRT #include #include diff --git a/src/libstddjb/tain_clockmon.c b/src/libstddjb/tain_clockmon.c deleted file mode 100644 index f14cd31..0000000 --- a/src/libstddjb/tain_clockmon.c +++ /dev/null @@ -1,47 +0,0 @@ -/* ISC license. */ - -#include -#include - -#ifdef SKALIBS_HASCLOCKMON - -#include - -int tain_clockmon_init (tain_t *offset) -{ - tain_t a, b ; - struct timespec ts ; - if (!tain_sysclock(&a)) return 0 ; - if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) return 0 ; - if (!tain_from_timespec(&b, &ts)) return 0 ; - tain_add(&a, &a, &tain_nano500) ; - tain_sub(offset, &a, &b) ; - return 1 ; -} - -int tain_clockmon (tain_t *a, tain_t const *offset) -{ - struct timespec ts ; - if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) return 0 ; - if (!tain_from_timespec(a, &ts)) return 0 ; - tain_add(a, a, offset) ; - return 1 ; -} - -#else - -#include - -int tain_clockmon_init (tain_t *offset) -{ - (void)offset ; - return (errno = ENOSYS, 0) ; -} - -int tain_clockmon (tain_t *a, tain_t const *offset) -{ - (void)a ; (void)offset ; - return (errno = ENOSYS, 0) ; -} - -#endif diff --git a/src/libstddjb/tain_now.c b/src/libstddjb/tain_now.c index 157087a..d6625d6 100644 --- a/src/libstddjb/tain_now.c +++ b/src/libstddjb/tain_now.c @@ -2,48 +2,6 @@ /* MT-unsafe */ -#include -#include #include -#ifdef SKALIBS_FLAG_USEMON -# ifndef SKALIBS_HASCLOCKMON -# undef SKALIBS_FLAG_USEMON -# warning "SKALIBS_FLAG_USEMON set but SKALIBS_HASCLOCKMON not found. Clearing SKALIBS_FLAG_USEMON." -# endif -#endif - - -#ifdef SKALIBS_FLAG_USEMON - -static tain_t offset ; - -int tain_init () -{ - return tain_clockmon_init(&offset) ; -} - -int tain_now (tain_t *a) -{ - static int initted = 0 ; - if (!initted) - { - if (!tain_clockmon_init(&offset)) return 0 ; - initted = 1 ; - } - return tain_clockmon(a, &offset) ; -} - -#else - -int tain_init () -{ - return 1 ; -} - -int tain_now (tain_t *a) -{ - return tain_sysclock(a) ; -} - -#endif +tain_clockread_func_t_ref tain_now = &tain_wallclock_read ; diff --git a/src/libstddjb/tain_now_set_stopwatch.c b/src/libstddjb/tain_now_set_stopwatch.c new file mode 100644 index 0000000..184a40a --- /dev/null +++ b/src/libstddjb/tain_now_set_stopwatch.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include + +#if defined(SKALIBS_HAS_CLOCKRT) && (defined(SKALIBS_HAS_CLOCKMON) || defined(SKALIBS_HAS_CLOCKBOOT)) + +#include + +#ifdef SKALIBS_HAS_CLOCKMON +# define SKALIBS_STOPWATCH CLOCK_MONOTONIC +#else +# define SKALIBS_STOPWATCH CLOCK_BOOTTIME +#endif + +static tain_t offset ; + +static int tain_now_stopwatch (tain_t *a) +{ + return tain_stopwatch_read(a, SKALIBS_STOPWATCH, &offset) ; +} + +void tain_now_set_stopwatch (void) +{ + if (!tain_stopwatch_init(SKALIBS_STOPWATCH, &offset)) return ; + tain_now = &tain_now_stopwatch ; +} + +#else + +void tain_now_set_stopwatch (void) +{ +} + +#endif diff --git a/src/libstddjb/tain_now_set_wallclock.c b/src/libstddjb/tain_now_set_wallclock.c new file mode 100644 index 0000000..a3d8b61 --- /dev/null +++ b/src/libstddjb/tain_now_set_wallclock.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include + +void tain_now_set_wallclock (void) +{ + tain_now = &tain_wallclock_read ; +} diff --git a/src/libstddjb/tain_stopwatch.c b/src/libstddjb/tain_stopwatch.c new file mode 100644 index 0000000..2bb4974 --- /dev/null +++ b/src/libstddjb/tain_stopwatch.c @@ -0,0 +1,50 @@ +/* ISC license. */ + +#include +#include + +#if defined(SKALIBS_HASCLOCKRT) && (defined(SKALIBS_HASCLOCKMON) || defined(SKALIBS_HASCLOCKBOOT)) + +#include + +int tain_stopwatch_init (clock_t cl, tain_t *offset) +{ + tain_t a, b ; + struct timespec ts ; + if (!tain_wallclock_read(&a)) return 0 ; + if (clock_gettime(cl, &ts) < 0) return 0 ; + if (!tain_from_timespec(&b, &ts)) return 0 ; + tain_add(&a, &a, &tain_nano500) ; + tain_sub(offset, &a, &b) ; + return 1 ; +} + +int tain_stopwatch_read (tain_t *a, clock_t cl, tain_t const *offset) +{ + struct timespec ts ; + if (clock_gettime(cl, &ts) < 0) return 0 ; + if (!tain_from_timespec(a, &ts)) return 0 ; + tain_add(a, a, offset) ; + return 1 ; +} + +#else + +#include + +int tain_stopwatch_init (clock_t cl, tain_t *offset) +{ + (void)cl ; + (void)offset ; + return (errno = ENOSYS, 0) ; +} + +int tain_stopwatch_read (tain_t *a, clock_t cl, tain_t const *offset) +{ + (void)a ; + (void)cl ; + (void)offset ; + return (errno = ENOSYS, 0) ; +} + +#endif diff --git a/src/libstddjb/tain_sysclock.c b/src/libstddjb/tain_sysclock.c deleted file mode 100644 index 3b98eb1..0000000 --- a/src/libstddjb/tain_sysclock.c +++ /dev/null @@ -1,10 +0,0 @@ -/* ISC license. */ - -#include - -int tain_sysclock (tain_t *a) -{ - tain_t aa ; - if (!sysclock_get(&aa)) return 0 ; - return tain_from_sysclock(a, &aa) ; -} diff --git a/src/libstddjb/tain_wallclock_read.c b/src/libstddjb/tain_wallclock_read.c new file mode 100644 index 0000000..96ed861 --- /dev/null +++ b/src/libstddjb/tain_wallclock_read.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include + +int tain_wallclock_read (tain_t *a) +{ + tain_t aa ; + if (!sysclock_get(&aa)) return 0 ; + return tain_from_sysclock(a, &aa) ; +} diff --git a/src/libstddjb/timestamp_r.c b/src/libstddjb/timestamp_r.c index 6eb8ab7..46be7a4 100644 --- a/src/libstddjb/timestamp_r.c +++ b/src/libstddjb/timestamp_r.c @@ -4,7 +4,7 @@ int timestamp_r (char *s, tain_t *stamp) { - if (!tain_sysclock(stamp)) return 0 ; + if (!tain_wallclock_read(stamp)) return 0 ; timestamp_fmt(s, stamp) ; return 1 ; } diff --git a/src/sysdeps/tryclockboot.c b/src/sysdeps/tryclockboot.c new file mode 100644 index 0000000..de8bf5c --- /dev/null +++ b/src/sysdeps/tryclockboot.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include + +int main (void) +{ + struct timespec ts ; + if (clock_gettime(CLOCK_BOOTTIME, &ts) < 0) return 111 ; + return 0 ; +} -- cgit v1.2.3