Coverage Report

Created: 2026-02-26 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ntp-dev/include/timespecops.h
Line
Count
Source
1
/*
2
 * timespecops.h -- calculations on 'struct timespec' values
3
 *
4
 * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
5
 * The contents of 'html/copyright.html' apply.
6
 *
7
 * Rationale
8
 * ---------
9
 *
10
 * Doing basic arithmetic on a 'struct timespec' is not exceedingly
11
 * hard, but it requires tedious and repetitive code to keep the result
12
 * normalised. We consider a timespec normalised when the nanosecond
13
 * fraction is in the interval [0 .. 10^9[ ; there are multiple value
14
 * pairs of seconds and nanoseconds that denote the same time interval,
15
 * but the normalised representation is unique. No two different
16
 * intervals can have the same normalised representation.
17
 *
18
 * Another topic is the representation of negative time intervals.
19
 * There's more than one way to this, since both the seconds and the
20
 * nanoseconds of a timespec are signed values. IMHO, the easiest way is
21
 * to use a complement representation where the nanoseconds are still
22
 * normalised, no matter what the sign of the seconds value. This makes
23
 * normalisation easier, since the sign of the integer part is
24
 * irrelevant, and it removes several sign decision cases during the
25
 * calculations.
26
 *
27
 * As long as no signed integer overflow can occur with the nanosecond
28
 * part of the operands, all operations work as expected and produce a
29
 * normalised result.
30
 *
31
 * The exception to this are functions fix a '_fast' suffix, which do no
32
 * normalisation on input data and therefore expect the input data to be
33
 * normalised.
34
 *
35
 * Input and output operands may overlap; all input is consumed before
36
 * the output is written to.
37
 */
38
#ifndef TIMESPECOPS_H
39
#define TIMESPECOPS_H
40
41
#include <sys/types.h>
42
#include <stdio.h>
43
#include <math.h>
44
45
#include "ntp.h"
46
#include "timetoa.h"
47
48
49
/* nanoseconds per second */
50
#define NANOSECONDS 1000000000
51
52
/* predicate: returns TRUE if the nanoseconds are in nominal range */
53
#define timespec_isnormal(x) \
54
  ((x)->tv_nsec >= 0 && (x)->tv_nsec < NANOSECONDS)
55
56
/* predicate: returns TRUE if the nanoseconds are out-of-bounds */
57
#define timespec_isdenormal(x)  (!timespec_isnormal(x))
58
59
60
61
62
/* make sure nanoseconds are in nominal range */
63
extern struct timespec normalize_tspec(struct timespec x);
64
65
/* x = a + b */
66
static inline struct timespec
67
add_tspec(
68
  struct timespec a,
69
  struct timespec b
70
  )
71
0
{
72
0
  struct timespec x;
73
0
74
0
  x = a;
75
0
  x.tv_sec += b.tv_sec;
76
0
  x.tv_nsec += b.tv_nsec;
77
0
78
0
  return normalize_tspec(x);
79
0
}
Unexecuted instantiation: ntp_io.c:add_tspec
Unexecuted instantiation: ntp_refclock.c:add_tspec
Unexecuted instantiation: refclock_gpsdjson.c:add_tspec
Unexecuted instantiation: refclock_nmea.c:add_tspec
Unexecuted instantiation: refclock_shm.c:add_tspec
Unexecuted instantiation: systime.c:add_tspec
Unexecuted instantiation: timespecops.c:add_tspec
Unexecuted instantiation: work_thread.c:add_tspec
80
81
/* x = a + b, b is fraction only */
82
static inline struct timespec
83
add_tspec_ns(
84
  struct timespec a,
85
  long    b
86
  )
87
28
{
88
28
  struct timespec x;
89
90
28
  x = a;
91
28
  x.tv_nsec += b;
92
93
28
  return normalize_tspec(x);
94
28
}
Unexecuted instantiation: ntp_io.c:add_tspec_ns
Unexecuted instantiation: ntp_refclock.c:add_tspec_ns
Unexecuted instantiation: refclock_gpsdjson.c:add_tspec_ns
Unexecuted instantiation: refclock_nmea.c:add_tspec_ns
Unexecuted instantiation: refclock_shm.c:add_tspec_ns
systime.c:add_tspec_ns
Line
Count
Source
87
28
{
88
28
  struct timespec x;
89
90
28
  x = a;
91
28
  x.tv_nsec += b;
92
93
28
  return normalize_tspec(x);
94
28
}
Unexecuted instantiation: timespecops.c:add_tspec_ns
Unexecuted instantiation: work_thread.c:add_tspec_ns
95
96
/* x = a - b */
97
static inline struct timespec
98
sub_tspec(
99
  struct timespec a,
100
  struct timespec b
101
  )
102
0
{ 
103
0
  struct timespec x;
104
105
0
  x = a;
106
0
  x.tv_sec -= b.tv_sec;
107
0
  x.tv_nsec -= b.tv_nsec;
108
109
0
  return normalize_tspec(x);
110
0
}
Unexecuted instantiation: ntp_io.c:sub_tspec
Unexecuted instantiation: ntp_refclock.c:sub_tspec
Unexecuted instantiation: refclock_gpsdjson.c:sub_tspec
Unexecuted instantiation: refclock_nmea.c:sub_tspec
Unexecuted instantiation: refclock_shm.c:sub_tspec
Unexecuted instantiation: systime.c:sub_tspec
Unexecuted instantiation: timespecops.c:sub_tspec
Unexecuted instantiation: work_thread.c:sub_tspec
111
112
/* x = a - b, b is fraction only */
113
static inline struct timespec
114
sub_tspec_ns(
115
  struct timespec a,
116
  long    b
117
  )
118
0
{
119
0
  struct timespec x;
120
0
121
0
  x = a;
122
0
  x.tv_nsec -= b;
123
0
124
0
  return normalize_tspec(x);
125
0
}
Unexecuted instantiation: ntp_io.c:sub_tspec_ns
Unexecuted instantiation: ntp_refclock.c:sub_tspec_ns
Unexecuted instantiation: refclock_gpsdjson.c:sub_tspec_ns
Unexecuted instantiation: refclock_nmea.c:sub_tspec_ns
Unexecuted instantiation: refclock_shm.c:sub_tspec_ns
Unexecuted instantiation: systime.c:sub_tspec_ns
Unexecuted instantiation: timespecops.c:sub_tspec_ns
Unexecuted instantiation: work_thread.c:sub_tspec_ns
126
127
/* x = -a */
128
static inline struct timespec
129
neg_tspec(
130
  struct timespec a
131
  )
132
0
{ 
133
0
  struct timespec x;
134
0
135
0
  x.tv_sec = -a.tv_sec;
136
0
  x.tv_nsec = -a.tv_nsec;
137
0
138
0
  return normalize_tspec(x);
139
0
}
Unexecuted instantiation: ntp_io.c:neg_tspec
Unexecuted instantiation: ntp_refclock.c:neg_tspec
Unexecuted instantiation: refclock_gpsdjson.c:neg_tspec
Unexecuted instantiation: refclock_nmea.c:neg_tspec
Unexecuted instantiation: refclock_shm.c:neg_tspec
Unexecuted instantiation: systime.c:neg_tspec
Unexecuted instantiation: timespecops.c:neg_tspec
Unexecuted instantiation: work_thread.c:neg_tspec
140
141
/* x = abs(a) */
142
struct timespec abs_tspec(struct timespec a);
143
144
/*
145
 * compare previously-normalised a and b
146
 * return 1 / 0 / -1 if a < / == / > b
147
 */
148
extern int cmp_tspec(struct timespec a, struct timespec b);
149
150
/*
151
 * compare possibly-denormal a and b
152
 * return 1 / 0 / -1 if a < / == / > b
153
 */
154
static inline int
155
cmp_tspec_denorm(
156
  struct timespec a,
157
  struct timespec b
158
  )
159
0
{
160
0
  return cmp_tspec(normalize_tspec(a), normalize_tspec(b));
161
0
}
Unexecuted instantiation: ntp_io.c:cmp_tspec_denorm
Unexecuted instantiation: ntp_refclock.c:cmp_tspec_denorm
Unexecuted instantiation: refclock_gpsdjson.c:cmp_tspec_denorm
Unexecuted instantiation: refclock_nmea.c:cmp_tspec_denorm
Unexecuted instantiation: refclock_shm.c:cmp_tspec_denorm
Unexecuted instantiation: systime.c:cmp_tspec_denorm
Unexecuted instantiation: timespecops.c:cmp_tspec_denorm
Unexecuted instantiation: work_thread.c:cmp_tspec_denorm
162
163
/*
164
 * test previously-normalised a
165
 * return 1 / 0 / -1 if a < / == / > 0
166
 */
167
extern int test_tspec(struct timespec a);
168
169
/*
170
 * test possibly-denormal a
171
 * return 1 / 0 / -1 if a < / == / > 0
172
 */
173
static inline int
174
test_tspec_denorm(
175
  struct timespec a
176
  )
177
0
{
178
0
  return test_tspec(normalize_tspec(a));
179
0
}
Unexecuted instantiation: ntp_io.c:test_tspec_denorm
Unexecuted instantiation: ntp_refclock.c:test_tspec_denorm
Unexecuted instantiation: refclock_gpsdjson.c:test_tspec_denorm
Unexecuted instantiation: refclock_nmea.c:test_tspec_denorm
Unexecuted instantiation: refclock_shm.c:test_tspec_denorm
Unexecuted instantiation: systime.c:test_tspec_denorm
Unexecuted instantiation: timespecops.c:test_tspec_denorm
Unexecuted instantiation: work_thread.c:test_tspec_denorm
180
181
/* return LIB buffer ptr to string rep */
182
static inline const char *
183
tspectoa(
184
  struct timespec x
185
  )
186
0
{
187
0
  return format_time_fraction(x.tv_sec, x.tv_nsec, 9);
188
0
}
Unexecuted instantiation: ntp_io.c:tspectoa
Unexecuted instantiation: ntp_refclock.c:tspectoa
Unexecuted instantiation: refclock_gpsdjson.c:tspectoa
Unexecuted instantiation: refclock_nmea.c:tspectoa
Unexecuted instantiation: refclock_shm.c:tspectoa
Unexecuted instantiation: systime.c:tspectoa
Unexecuted instantiation: timespecops.c:tspectoa
Unexecuted instantiation: work_thread.c:tspectoa
189
190
/*
191
 *  convert to l_fp type, relative and absolute
192
 */
193
194
/* convert from timespec duration to l_fp duration */
195
extern l_fp tspec_intv_to_lfp(struct timespec x);
196
197
/* x must be UN*X epoch, output will be in NTP epoch */
198
static inline l_fp
199
tspec_stamp_to_lfp(
200
  struct timespec x
201
  )
202
14
{
203
14
  l_fp    y;
204
205
14
  y = tspec_intv_to_lfp(x);
206
14
  y.l_ui += JAN_1970;
207
208
14
  return y;
209
14
}
Unexecuted instantiation: ntp_io.c:tspec_stamp_to_lfp
Unexecuted instantiation: ntp_refclock.c:tspec_stamp_to_lfp
Unexecuted instantiation: refclock_gpsdjson.c:tspec_stamp_to_lfp
Unexecuted instantiation: refclock_nmea.c:tspec_stamp_to_lfp
Unexecuted instantiation: refclock_shm.c:tspec_stamp_to_lfp
systime.c:tspec_stamp_to_lfp
Line
Count
Source
202
14
{
203
14
  l_fp    y;
204
205
14
  y = tspec_intv_to_lfp(x);
206
14
  y.l_ui += JAN_1970;
207
208
14
  return y;
209
14
}
Unexecuted instantiation: timespecops.c:tspec_stamp_to_lfp
Unexecuted instantiation: work_thread.c:tspec_stamp_to_lfp
210
211
/* convert from l_fp type, relative signed/unsigned and absolute */
212
extern struct timespec lfp_intv_to_tspec(l_fp x);
213
extern struct timespec lfp_uintv_to_tspec(l_fp x);
214
215
/*
216
 * absolute (timestamp) conversion. Input is time in NTP epoch, output
217
 * is in UN*X epoch. The NTP time stamp will be expanded around the
218
 * pivot time *p or the current time, if p is NULL.
219
 */
220
extern struct timespec lfp_stamp_to_tspec(l_fp x, const time_t *pivot);
221
222
#endif  /* TIMESPECOPS_H */