]> git.ipfire.org Git - thirdparty/openssl.git/blob - include/internal/time.h
Make OSSL_TIME a structure
[thirdparty/openssl.git] / include / internal / time.h
1 /*
2 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #ifndef OSSL_INTERNAL_TIME_H
11 # define OSSL_INTERNAL_TIME_H
12 # pragma once
13
14 # include <openssl/e_os2.h> /* uint64_t */
15 # include "internal/e_os.h" /* for struct timeval */
16 # include "internal/safe_math.h"
17
18 /*
19 * Internal type defining a time.
20 * This should be treated as an opaque structure.
21 *
22 * The time datum is Unix's 1970 and at nanosecond precision, this gives
23 * a range of 584 years roughly.
24 */
25 typedef struct {
26 uint64_t t; /* Ticks since the epoch */
27 } OSSL_TIME;
28
29 /* The precision of times allows this many values per second */
30 # define OSSL_TIME_SECOND ((uint64_t)1000000000)
31
32 /* One millisecond. */
33 # define OSSL_TIME_MS (OSSL_TIME_SECOND / 1000)
34
35 /* One microsecond. */
36 # define OSSL_TIME_US (OSSL_TIME_MS / 1000)
37
38 /* Convert a tick count into a time */
39 static ossl_unused ossl_inline OSSL_TIME ossl_ticks2time(uint64_t ticks)
40 {
41 OSSL_TIME r;
42
43 r.t = ticks;
44 return r;
45 }
46
47 /* Convert a time to a tick count */
48 static ossl_unused ossl_inline uint64_t ossl_time2ticks(OSSL_TIME t)
49 {
50 return t.t;
51 }
52
53 /* Get current time */
54 OSSL_TIME ossl_time_now(void);
55
56 /* The beginning and end of the time range */
57 static ossl_unused ossl_inline OSSL_TIME ossl_time_zero(void)
58 {
59 return ossl_ticks2time(0);
60 }
61
62 static ossl_unused ossl_inline OSSL_TIME ossl_time_infinite(void)
63 {
64 return ossl_ticks2time(~(uint64_t)0);
65 }
66
67
68 /* Convert time to timeval */
69 static ossl_unused ossl_inline
70 void ossl_time_time_to_timeval(OSSL_TIME t, struct timeval *out)
71 {
72 #ifdef _WIN32
73 out->tv_sec = (long int)(t.t / OSSL_TIME_SECOND);
74 #else
75 out->tv_sec = (time_t)(t.t / OSSL_TIME_SECOND);
76 #endif
77 out->tv_usec = (t.t % OSSL_TIME_SECOND) / (OSSL_TIME_SECOND / 1000000);
78 }
79
80 /* Compare two time values, return -1 if less, 1 if greater and 0 if equal */
81 static ossl_unused ossl_inline
82 int ossl_time_compare(OSSL_TIME a, OSSL_TIME b)
83 {
84 if (a.t > b.t)
85 return 1;
86 if (a.t < b.t)
87 return -1;
88 return 0;
89 }
90
91 /*
92 * Arithmetic operations on times.
93 * These operations are saturating, in that an overflow or underflow returns
94 * the largest or smallest value respectively.
95 */
96 OSSL_SAFE_MATH_UNSIGNED(time, uint64_t)
97
98 static ossl_unused ossl_inline
99 OSSL_TIME ossl_time_add(OSSL_TIME a, OSSL_TIME b)
100 {
101 OSSL_TIME r;
102 int err = 0;
103
104 r.t = safe_add_time(a.t, b.t, &err);
105 return err ? ossl_time_infinite() : r;
106 }
107
108 static ossl_unused ossl_inline
109 OSSL_TIME ossl_time_subtract(OSSL_TIME a, OSSL_TIME b)
110 {
111 OSSL_TIME r;
112 int err = 0;
113
114 r.t = safe_sub_time(a.t, b.t, &err);
115 return err ? ossl_time_zero() : r;
116 }
117
118 /* Returns |a - b|. */
119 static ossl_unused ossl_inline
120 OSSL_TIME ossl_time_abs_difference(OSSL_TIME a, OSSL_TIME b)
121 {
122 return a.t > b.t ? ossl_time_subtract(a, b)
123 : ossl_time_subtract(b, a);
124 }
125
126 static ossl_unused ossl_inline
127 OSSL_TIME ossl_time_multiply(OSSL_TIME a, uint64_t b)
128 {
129 OSSL_TIME r;
130 int err = 0;
131
132 r.t = safe_mul_time(a.t, b, &err);
133 return err ? ossl_time_infinite() : r;
134 }
135
136 static ossl_unused ossl_inline
137 OSSL_TIME ossl_time_divide(OSSL_TIME a, uint64_t b)
138 {
139 OSSL_TIME r;
140 int err = 0;
141
142 r.t = safe_div_time(a.t, b, &err);
143 return err ? ossl_time_zero() : r;
144 }
145
146 /* Return higher of the two given time values. */
147 static ossl_unused ossl_inline
148 OSSL_TIME ossl_time_max(OSSL_TIME a, OSSL_TIME b)
149 {
150 return a.t > b.t ? a : b;
151 }
152
153 /* Return the lower of the two given time values. */
154 static ossl_unused ossl_inline
155 OSSL_TIME ossl_time_min(OSSL_TIME a, OSSL_TIME b)
156 {
157 return a.t < b.t ? a : b;
158 }
159
160 #endif