1 /* Test timespec functions.
2 Copyright 2015-2025 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Paul Eggert. */
28 static struct { int s
; int ns
; } const prototype
[] =
32 { INT_MIN
, TIMESPEC_HZ
- 1 },
35 { INT_MIN
+ 1, TIMESPEC_HZ
- 1 },
38 { -1, TIMESPEC_HZ
- 1 },
41 { 0, TIMESPEC_HZ
- 1 },
44 { 1, TIMESPEC_HZ
- 1 },
47 { 1234567890, TIMESPEC_HZ
- 1 },
50 { INT_MAX
- 1, TIMESPEC_HZ
- 1 },
53 { INT_MAX
, TIMESPEC_HZ
- 1 },
54 { INT_MAX
, 2 * TIMESPEC_HZ
}
56 enum { nprototypes
= sizeof prototype
/ sizeof *prototype
};
59 valid (struct timespec a
)
61 return 0 <= a
.tv_nsec
&& a
.tv_nsec
< TIMESPEC_HZ
;
67 return i
< 0 ? -1 : 0 < i
;
71 cmp (struct timespec a
, struct timespec b
)
73 return sign (timespec_cmp (a
, b
));
77 eq (struct timespec a
, struct timespec b
)
79 return timespec_cmp (a
, b
) == 0;
83 extremal (struct timespec a
)
85 return ((a
.tv_sec
== TYPE_MINIMUM (time_t) && a
.tv_nsec
== 0)
86 || (a
.tv_sec
== TYPE_MAXIMUM (time_t)
87 && a
.tv_nsec
== TIMESPEC_HZ
- 1));
94 struct timespec test
[nprototypes
+ 1];
97 struct timespec prevroundtrip
;
99 test
[0] = make_timespec (TYPE_MINIMUM (time_t), -1);
101 for (i
= 0; i
< nprototypes
; i
++)
103 int s
= prototype
[i
].s
;
104 if (TYPE_SIGNED (time_t) || 0 <= s
)
106 time_t t
= (s
<= INT_MIN
+ 1 ? s
- INT_MIN
+ TYPE_MINIMUM (time_t)
107 : INT_MAX
- 1 <= s
? s
- INT_MAX
+ TYPE_MAXIMUM (time_t)
109 test
[ntests
++] = make_timespec (t
, prototype
[i
].ns
);
113 for (i
= 0; i
< LOG10_TIMESPEC_HZ
; i
++)
115 ASSERT (computed_hz
== TIMESPEC_HZ
);
117 for (i
= 0; i
< ntests
; i
++)
119 struct timespec a
= test
[i
];
121 struct timespec roundtrip
= dtotimespec (timespectod (a
));
123 ASSERT (cmp (prevroundtrip
, roundtrip
) <= 0);
124 prevroundtrip
= roundtrip
;
126 ASSERT (sign (timespec_sign (a
)) == cmp (a
, make_timespec (0, 0)));
129 for (j
= 0; j
< ntests
; j
++)
131 struct timespec b
= test
[j
];
134 struct timespec sum
= timespec_add (a
, b
);
135 struct timespec diff
= timespec_sub (a
, b
);
136 struct timespec rdiff
= timespec_sub (b
, a
);
137 ASSERT (cmp (a
, b
) == sign (i
- j
));
138 ASSERT (eq (sum
, timespec_add (b
, a
)));
139 if (! extremal (sum
))
141 ASSERT (eq (a
, timespec_sub (sum
, b
)));
142 ASSERT (eq (b
, timespec_sub (sum
, a
)));
144 for (k
= 0; k
< ntests
; k
++)
146 struct timespec c
= test
[k
];
149 struct timespec sumbc
= timespec_add (b
, c
);
150 if (! extremal (sumbc
))
151 ASSERT (eq (timespec_add (a
, sumbc
),
152 timespec_add (sum
, c
)));
156 if (! extremal (diff
))
157 ASSERT (eq (a
, timespec_add (diff
, b
)));
158 if (! extremal (rdiff
))
159 ASSERT (eq (b
, timespec_add (rdiff
, a
)));
165 return test_exit_status
;