]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
util: add conversion between intervals and NTP 64-bit format
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 21 Sep 2023 12:02:11 +0000 (14:02 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 26 Sep 2023 13:00:06 +0000 (15:00 +0200)
This will be needed to save PTP correction in NTP timestamp format.

test/unit/util.c
util.c
util.h

index fa294c4528d42a64dc4b57c38e16eaf56214d4b3..f434671f87408a7d93fd767ed7cb2f460c2c5a2e 100644 (file)
@@ -253,6 +253,47 @@ test_unit(void)
   TEST_CHECK(UTI_IsEqualAnyNtp64(&ntp_ts, NULL, NULL, &ntp_ts));
   TEST_CHECK(!UTI_IsEqualAnyNtp64(&ntp_ts, &ntp_fuzz, &ntp_fuzz, &ntp_fuzz));
 
+  ntp_ts.hi = htonl(0);
+  ntp_ts.lo = htonl(0);
+  x = UTI_Ntp64ToDouble(&ntp_ts);
+  TEST_CHECK(fabs(x) < 1e-10);
+  UTI_DoubleToNtp64(x, &ntp_ts2);
+  TEST_CHECK(UTI_CompareNtp64(&ntp_ts, &ntp_ts2) == 0);
+
+  ntp_ts.hi = htonl(0);
+  ntp_ts.lo = htonl(0xffffffff);
+  x = UTI_Ntp64ToDouble(&ntp_ts);
+  TEST_CHECK(fabs(x - 1.0 + 0.23e-9) < 1e-10);
+  UTI_DoubleToNtp64(x, &ntp_ts2);
+  TEST_CHECK(fabs(UTI_DiffNtp64ToDouble(&ntp_ts, &ntp_ts2)) < 0.3e-9);
+
+  ntp_ts.hi = htonl(0xffffffff);
+  ntp_ts.lo = htonl(0xffffffff);
+  x = UTI_Ntp64ToDouble(&ntp_ts);
+  TEST_CHECK(fabs(x + 0.23e-9) < 1e-10);
+  UTI_DoubleToNtp64(x, &ntp_ts2);
+  TEST_CHECK(fabs(UTI_DiffNtp64ToDouble(&ntp_ts, &ntp_ts2)) < 0.3e-9);
+
+  ntp_ts.hi = htonl(0x80000000);
+  ntp_ts.lo = htonl(0);
+  x = UTI_Ntp64ToDouble(&ntp_ts);
+  TEST_CHECK(fabs(x + 0x80000000) < 1e-10);
+  UTI_DoubleToNtp64(x, &ntp_ts2);
+  TEST_CHECK(fabs(UTI_DiffNtp64ToDouble(&ntp_ts, &ntp_ts2)) < 0.3e-9);
+
+  ntp_ts.hi = htonl(0x7fffffff);
+  ntp_ts.lo = htonl(0xffffffff);
+  x = UTI_Ntp64ToDouble(&ntp_ts);
+  TEST_CHECK(fabs(x - 2147483648) < 1.0);
+
+  ntp_ts.lo = htonl(0);
+  ntp_ts.hi = htonl(0x7fffffff);
+  UTI_DoubleToNtp64(0x7fffffff + 0.1, &ntp_ts2);
+  TEST_CHECK(UTI_CompareNtp64(&ntp_ts, &ntp_ts2) == 0);
+  ntp_ts.hi = htonl(0x80000000);
+  UTI_DoubleToNtp64(0x80000000 - 0.1, &ntp_ts);
+  TEST_CHECK(UTI_CompareNtp64(&ntp_ts, &ntp_ts2) == 0);
+
   ts.tv_sec = 1;
   ts.tv_nsec = 2;
   ts2.tv_sec = 1;
diff --git a/util.c b/util.c
index a240e3edfdf1b6f2ed868c83575a36003c253e70..a4c8288b38ca11b6e5a81076afcfbbd02d7540cb 100644 (file)
--- a/util.c
+++ b/util.c
@@ -818,6 +818,33 @@ UTI_DiffNtp64ToDouble(const NTP_int64 *a, const NTP_int64 *b)
 
 /* ================================================== */
 
+double
+UTI_Ntp64ToDouble(NTP_int64 *src)
+{
+  NTP_int64 zero;
+
+  UTI_ZeroNtp64(&zero);
+  return UTI_DiffNtp64ToDouble(src, &zero);
+}
+
+/* ================================================== */
+
+void
+UTI_DoubleToNtp64(double src, NTP_int64 *dest)
+{
+  int32_t hi;
+
+  src = CLAMP(INT32_MIN, src, INT32_MAX);
+  hi = round(src);
+  if (hi > src)
+    hi -= 1;
+
+  dest->hi = htonl(hi);
+  dest->lo = htonl((src - hi) * (1.0e9 * NSEC_PER_NTP64));
+}
+
+/* ================================================== */
+
 /* Maximum offset between two sane times */
 #define MAX_OFFSET 4294967296.0
 
diff --git a/util.h b/util.h
index d38abf063c8a6adbbb7223362b50f0ab51879b75..9f11ba6a02850800cc11e13962a4709b4d4d5a25 100644 (file)
--- a/util.h
+++ b/util.h
@@ -163,6 +163,10 @@ extern void UTI_Ntp64ToTimespec(const NTP_int64 *src, struct timespec *dest);
 /* Calculate a - b in any epoch */
 extern double UTI_DiffNtp64ToDouble(const NTP_int64 *a, const NTP_int64 *b);
 
+/* Convert a difference in double (not a timestamp) from and to NTP format */
+extern double UTI_Ntp64ToDouble(NTP_int64 *src);
+extern void UTI_DoubleToNtp64(double src, NTP_int64 *dest);
+
 /* Check if time + offset is sane */
 extern int UTI_IsTimeOffsetSane(const struct timespec *ts, double offset);