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