]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
time: add some additional utilities and document everything
authorPauli <pauli@openssl.org>
Mon, 29 Aug 2022 03:41:26 +0000 (13:41 +1000)
committerPauli <pauli@openssl.org>
Tue, 13 Sep 2022 11:13:22 +0000 (21:13 +1000)
Some of the recently added functions were not documents.  This has been addressed.
Also added utility functions for conversions between time_t, seconds and struct timeval
to/from OSSL_TIME.

Reviewed-by: Todd Short <todd.short@me.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19082)

doc/internal/man3/OSSL_TIME.pod
include/internal/time.h
ssl/time.c

index eda5b987442845f40b58c1e32c98f89d07ec422f..29224d8326000484dc1792ada9e51c044d5c414e 100644 (file)
@@ -2,11 +2,16 @@
 
 =head1 NAME
 
-OSSL_TIME, OSSL_TIME_SECOND, ossl_time_infinite, ossl_time_zero,
-ossl_ticks2time, ossl_time2ticks,
-ossl_time_now, ossl_time_time_to_timeval, ossl_time_compare,
-ossl_time_add, ossl_time_subtract, ossl_time_multiply,
-ossl_time_divide, ossl_time_abs_difference, ossl_time_max,
+OSSL_TIME, OSSL_TIME_SECOND, OSSL_TIME_MS, OSSL_TIME_US,
+ossl_time_infinite, ossl_time_zero, ossl_time_now,
+ossl_ticks2time, ossl_time2ticks, ossl_seconds2time, ossl_time2seconds,
+ossl_ms2time, ossl_us2time, ossl_time2ms, ossl_time2us,
+ossl_time_to_timeval, ossl_time_from_timeval,
+ossl_time_to_time_t, ossl_time_from_time_t,
+ossl_time_compare, ossl_time_is_zero, ossl_time_is_infinite,
+ossl_time_add, ossl_time_subtract,
+ossl_time_multiply, ossl_time_divide, ossl_time_muldiv,
+ossl_time_abs_difference, ossl_time_max,
 ossl_time_min - times and durations
 
 =head1 SYNOPSIS
@@ -16,21 +21,36 @@ ossl_time_min - times and durations
  typedef struct OSSL_TIME;
 
  #define OSSL_TIME_SECOND   /* Ticks per second */
+ #define OSSL_TIME_MS       /* Ticks per millisecond */
+ #define OSSL_TIME_US       /* Ticks per microsecond */
 
  OSSL_TIME ossl_ticks2time(uint64_t);
  uint64_t ossl_time2ticks(OSSL_TIME t);
+ OSSL_TIME ossl_seconds2time(uint64_t);
+ uint64_t ossl_time2seconds(OSSL_TIME t);
+ OSSL_TIME ossl_ms2time(uint64_t);
+ uint64_t ossl_time2ms(OSSL_TIME t);
+ OSSL_TIME ossl_us2time(uint64_t);
+ uint64_t ossl_time2us(OSSL_TIME t);
 
  OSSL_TIME ossl_time_zero(void);
  OSSL_TIME ossl_time_infinite(void);
  OSSL_TIME ossl_time_now(void);
 
- void ossl_time_time_to_timeval(OSSL_TIME t, struct timeval *out);
+ struct timeval ossl_time_to_timeval(OSSL_TIME t);
+ OSSL_TIME ossl_time_from_timeval(struct timeval tv);
+ time_t ossl_time_to_time_t(OSSL_TIME t);
+ OSSL_TIME ossl_time_from_time_t(time_t t);
 
  int ossl_time_compare(OSSL_TIME a, OSSL_TIME b);
+ int ossl_time_is_zero(OSSL_TIME t);
+ int ossl_time_is_infinite(OSSL_TIME t);
+
  OSSL_TIME ossl_time_add(OSSL_TIME a, OSSL_TIME b);
  OSSL_TIME ossl_time_subtract(OSSL_TIME a, OSSL_TIME b);
  OSSL_TIME ossl_time_multiply(OSSL_TIME a, uint64_t b);
  OSSL_TIME ossl_time_divide(OSSL_TIME a, uint64_t b);
+ OSSL_TIME ossl_time_muldiv(OSSL_TIME a, uint64_t b, uint64_t c);
  OSSL_TIME ossl_time_abs_difference(OSSL_TIME a, OSSL_TIME b);
  OSSL_TIME ossl_time_max(OSSL_TIME a, OSSL_TIME b);
  OSSL_TIME ossl_time_min(OSSL_TIME a, OSSL_TIME b);
@@ -56,6 +76,15 @@ B<ossl_ticks2time> converts an integral number of counts to a time.
 
 B<ossl_time2ticks> converts a time to an integral number of counts.
 
+B<ossl_seconds2time>, B<ossl_ms2time> and B<ossl_us2time> convert an
+integral number of seconds, milliseconds and microseconds respectively
+to a time.  These functions are implemented as macros.
+
+B<ossl_time2seconds>, B<ossl_time2ms> and B<ossl_time2us> convert a
+time to an integral number of second, milliseconds and microseconds
+respectively.  These functions truncates any fractional seconds and are
+implemented as macros.
+
 B<ossl_time_zero> returns the smallest representable B<OSSL_TIME>.
 This value represents the time Epoch and it is returned when an underflow
 would otherwise occur.
@@ -70,12 +99,22 @@ wall-clock time.  The time returned by this function is useful for
 scheduling timeouts, deadlines and recurring events, but due to its
 undefined Epoch and monotonic nature, is not suitable for other uses.
 
-B<ossl_time_time_to_timeval> converts a time to a I<struct timeval>.
+B<ossl_time_to_timeval> converts a time to a I<struct timeval>.
+
+B<ossl_time_from_timeval> converts a I<struct timeval> to a time.
+
+B<ossl_time_to_time_t> converts a time to a I<time_t>.
+
+B<ossl_time_from_time_t> converts a I<time_t> to a time.
 
 B<ossl_time_compare> compares I<a> with I<b> and returns -1 if I<a>
 is smaller than I<b>, 0 if they are equal and +1 if I<a> is
 larger than I<b>.
 
+B<ossl_time_is_zero> returns 1 if the time I<t> is zero and 0 otherwise.
+
+B<ossl_time_is_infinite> returns 1 if the time I<t> is infinite and 0 otherwise.
+
 B<ossl_time_add> performs a saturating addition of the two times,
 returning I<a> + I<b>.
 If the summation would overflow B<OSSL_TIME_INFINITY> is returned.
@@ -85,10 +124,13 @@ returning I<a> - I<b>.
 If the difference would be negative,  B<0> is returned.
 
 B<ossl_time_multiply> performs a saturating multiplication of a time value by a
-given integer multiplier.
+given integer multiplier returning I<a> &#xD7; I<b>.
+
+B<ossl_time_divide> performs division of a time value by a given integer
+divisor returning &#x230A;I<a> &#xF7; I<b>&#x230B;.
 
-B<ossl_time_divide> performs floor division of a time value by a given integer
-divisor.
+B<ossl_time_muldiv> performs a fused multiplication and division operation.
+The result is equal to &#x230A;I<a> &#xD7; I<b> &#xF7; I<c>&#x230B;.
 
 B<ossl_time_abs_difference> returns the magnitude of the difference between two
 time values.
@@ -109,12 +151,22 @@ B<ossl_time_zero> returns the time of the Epoch.
 
 B<ossl_time_infinite> returns the last representable time.
 
-B<ossl_ticks2time> return the duration specified.
+B<ossl_ticks2time>, B<ossl_seconds2time>, B<ossl_ms2time> and B<ossl_us2time>
+return the duration specified in ticks, seconds, milliseconds and microseconds
+respectively.
 
-B<ossl_time2ticks> returns the ticks since Epoch.
+B<ossl_time2ticks>, B<ossl_time2seconds>, B<ossl_time2ms> and B<ossl_time2us>
+return the number of ticks, seconds, microseconds and microseconds respectively
+that the time object represents.
+
+B<ossl_time_to_timeval>, B<ossl_time_from_timeval>, B<ossl_time_to_time_t> and
+B<ossl_time_from_time_t> all return the converted time.
 
 B<ossl_time_compare> returns -1, 0 or 1 depending on the comparison.
 
+B<ossl_time_is_zero> and B<ossl_time_is_infinite> return 1 if the condition
+is true and 0 otherwise.
+
 B<ossl_time_add> returns the summation of the two times or
 the last representable time on overflow.
 
@@ -127,6 +179,9 @@ given integral multiplier, or B<OSSL_TIME_INFINITY> on overflow.
 B<ossl_time_divide> returns the result of dividing the given time by the given
 integral divisor.
 
+B<ossl_time_muldiv> returns the fused multiplication and division of the given
+time and the two integral values.
+
 B<ossl_time_abs_difference> returns the magnitude of the difference between the
 input time values.
 
index f5c56b6c7b63309efbc3c6a79486603ca0ab84ee..3039327d58ee847c7257b23172b67fcee267773a 100644 (file)
@@ -35,8 +35,16 @@ typedef struct {
 /* One microsecond. */
 # define OSSL_TIME_US     (OSSL_TIME_MS     / 1000)
 
+#define ossl_seconds2time(s) ossl_ticks2time((s) * OSSL_TIME_SECOND)
+#define ossl_time2seconds(t) (ossl_time2ticks(t) / OSSL_TIME_SECOND)
+#define ossl_ms2time(ms) ossl_ticks2time((ms) * OSSL_TIME_MS)
+#define ossl_time2ms(t) (ossl_time2ticks(t) / OSSL_TIME_MS)
+#define ossl_us2time(us) ossl_ticks2time((us) * OSSL_TIME_US)
+#define ossl_time2us(t) (ossl_time2ticks(t) / OSSL_TIME_US)
+
 /* Convert a tick count into a time */
-static ossl_unused ossl_inline OSSL_TIME ossl_ticks2time(uint64_t ticks)
+static ossl_unused ossl_inline
+OSSL_TIME ossl_ticks2time(uint64_t ticks)
 {
     OSSL_TIME r;
 
@@ -45,7 +53,8 @@ static ossl_unused ossl_inline OSSL_TIME ossl_ticks2time(uint64_t ticks)
 }
 
 /* Convert a time to a tick count */
-static ossl_unused ossl_inline uint64_t ossl_time2ticks(OSSL_TIME t)
+static ossl_unused ossl_inline
+uint64_t ossl_time2ticks(OSSL_TIME t)
 {
     return t.t;
 }
@@ -54,12 +63,14 @@ static ossl_unused ossl_inline uint64_t ossl_time2ticks(OSSL_TIME t)
 OSSL_TIME ossl_time_now(void);
 
 /* The beginning and end of the time range */
-static ossl_unused ossl_inline OSSL_TIME ossl_time_zero(void)
+static ossl_unused ossl_inline
+OSSL_TIME ossl_time_zero(void)
 {
     return ossl_ticks2time(0);
 }
 
-static ossl_unused ossl_inline OSSL_TIME ossl_time_infinite(void)
+static ossl_unused ossl_inline
+OSSL_TIME ossl_time_infinite(void)
 {
     return ossl_ticks2time(~(uint64_t)0);
 }
@@ -67,18 +78,41 @@ static ossl_unused ossl_inline OSSL_TIME ossl_time_infinite(void)
 
 /* Convert time to timeval */
 static ossl_unused ossl_inline
-void ossl_time_time_to_timeval(OSSL_TIME t, struct timeval *out)
+struct timeval ossl_time_to_timeval(OSSL_TIME t)
 {
+    struct timeval tv;
+
 #ifdef _WIN32
-    out->tv_sec = (long int)(t.t / OSSL_TIME_SECOND);
+    tv.tv_sec = (long int)(t.t / OSSL_TIME_SECOND);
 #else
-    out->tv_sec = (time_t)(t.t / OSSL_TIME_SECOND);
+    tv.tv_sec = (time_t)(t.t / OSSL_TIME_SECOND);
 #endif
-    out->tv_usec = (t.t % OSSL_TIME_SECOND) / (OSSL_TIME_SECOND / 1000000);
+    tv.tv_usec = (t.t % OSSL_TIME_SECOND) / OSSL_TIME_US;
+    return tv;
+}
+
+/* Convert timeval to time */
+static ossl_unused ossl_inline
+OSSL_TIME ossl_time_from_timeval(struct timeval tv)
+{
+    OSSL_TIME t;
+
+    if (tv.tv_sec < 0)
+        return ossl_time_zero();
+    t.t = tv.tv_sec * OSSL_TIME_SECOND + tv.tv_usec * OSSL_TIME_US;
+    return t;
+}
+
+/* Convert OSSL_TIME to time_t */
+static ossl_unused ossl_inline
+time_t ossl_time_to_time_t(OSSL_TIME t)
+{
+    return (time_t)(t.t / OSSL_TIME_SECOND);
 }
 
 /* Convert time_t to OSSL_TIME */
-static ossl_inline OSSL_TIME ossl_time_from_time_t(time_t t)
+static ossl_unused ossl_inline
+OSSL_TIME ossl_time_from_time_t(time_t t)
 {
     OSSL_TIME ot;
 
@@ -167,6 +201,16 @@ OSSL_TIME ossl_time_divide(OSSL_TIME a, uint64_t b)
     return err ? ossl_time_zero() : r;
 }
 
+static ossl_unused ossl_inline
+OSSL_TIME ossl_time_muldiv(OSSL_TIME a, uint64_t b, uint64_t c)
+{
+    OSSL_TIME r;
+    int err = 0;
+
+    r.t = safe_muldiv_time(a.t, b, c, &err);
+    return err ? ossl_time_zero() : r;
+}
+
 /* Return higher of the two given time values. */
 static ossl_unused ossl_inline
 OSSL_TIME ossl_time_max(OSSL_TIME a, OSSL_TIME b)
index a1b9dc7534d1216ae24022f65bd1cb855e9d4dc4..628aaed7ecfca88225db08cab8b03178d588cc95 100644 (file)
@@ -40,10 +40,9 @@ OSSL_TIME ossl_time_now(void)
         return ossl_time_zero();
     }
     if (t.tv_sec <= 0)
-        r.t = t.tv_usec <= 0 ? 0 : t.tv_usec * (OSSL_TIME_SECOND / 1000000);
+        r.t = t.tv_usec <= 0 ? 0 : t.tv_usec * OSSL_TIME_US;
     else
-        r.t = ((uint64_t)t.tv_sec * 1000000 + t.tv_usec)
-              * (OSSL_TIME_SECOND / 1000000);
+        r.t = ((uint64_t)t.tv_sec * 1000000 + t.tv_usec) * OSSL_TIME_US;
 #endif
     return r;
 }