1*cdfa2a7eSchristos /* $NetBSD: bug-2803.c,v 1.2 2020/05/25 20:47:37 christos Exp $ */
2067f5680Schristos
3f17b710fSchristos #include <config.h>
4f17b710fSchristos
5f17b710fSchristos #include <stdio.h>
6f17b710fSchristos #include <sys/time.h>
7f17b710fSchristos
8f17b710fSchristos #include <ntp_fp.h>
9f17b710fSchristos #include <timevalops.h>
10f17b710fSchristos
11f17b710fSchristos /* microseconds per second */
12f17b710fSchristos #define MICROSECONDS 1000000
13f17b710fSchristos
14f17b710fSchristos
15f17b710fSchristos static int verbose = 1; // if not 0, also print results if test passed
16f17b710fSchristos static int exit_on_err = 0; // if not 0, exit if test failed
17f17b710fSchristos
18f17b710fSchristos
19f17b710fSchristos /*
20f17b710fSchristos * Test function calling the old and new code mentioned in
21f17b710fSchristos * http://bugs.ntp.org/show_bug.cgi?id=2803#c22
22f17b710fSchristos */
23f17b710fSchristos static
do_test(struct timeval timetv,struct timeval tvlast)24f17b710fSchristos int do_test( struct timeval timetv, struct timeval tvlast )
25f17b710fSchristos {
26f17b710fSchristos struct timeval tvdiff_old;
27f17b710fSchristos struct timeval tvdiff_new;
28f17b710fSchristos
29f17b710fSchristos int cond_old;
30f17b710fSchristos int cond_new;
31f17b710fSchristos int failed;
32f17b710fSchristos
33f17b710fSchristos cond_old = 0;
34f17b710fSchristos cond_new = 0;
35f17b710fSchristos
36f17b710fSchristos // Here is the old code:
37f17b710fSchristos tvdiff_old = abs_tval(sub_tval(timetv, tvlast));
38f17b710fSchristos if (tvdiff_old.tv_sec > 0) {
39f17b710fSchristos cond_old = 1;
40f17b710fSchristos }
41f17b710fSchristos
42f17b710fSchristos // Here is the new code:
43f17b710fSchristos tvdiff_new = sub_tval(timetv, tvlast);
44f17b710fSchristos if (tvdiff_new.tv_sec != 0) {
45f17b710fSchristos cond_new = 1;
46f17b710fSchristos }
47f17b710fSchristos
48f17b710fSchristos failed = cond_new != cond_old;
49f17b710fSchristos
50f17b710fSchristos if ( failed || verbose )
51f17b710fSchristos printf( "timetv %lli|%07li, tvlast %lli|%07li: tvdiff_old: %lli|%07li -> %i, tvdiff_new: %lli|%07li -> %i, same cond: %s\n",
52f17b710fSchristos (long long) timetv.tv_sec, timetv.tv_usec,
53f17b710fSchristos (long long) tvlast.tv_sec, tvlast.tv_usec,
54f17b710fSchristos (long long) tvdiff_old.tv_sec, tvdiff_old.tv_usec, cond_old,
55f17b710fSchristos (long long) tvdiff_new.tv_sec, tvdiff_new.tv_usec, cond_new,
56f17b710fSchristos failed ? "NO <<" : "yes" );
57f17b710fSchristos
58f17b710fSchristos return failed ? -1 : 0;
59f17b710fSchristos }
60f17b710fSchristos
61f17b710fSchristos
62f17b710fSchristos
63f17b710fSchristos /*
64f17b710fSchristos * Call the test function in a loop for a given set of parameters.
65f17b710fSchristos * Both timetv and tvlast iterate over the given range, in all combinations.
66f17b710fSchristos */
67f17b710fSchristos static
test_loop(long long start_sec,long start_usec,long long stop_sec,long stop_usec,long long step_sec,long step_usec)68f17b710fSchristos int test_loop( long long start_sec, long start_usec,
69f17b710fSchristos long long stop_sec, long stop_usec,
70f17b710fSchristos long long step_sec, long step_usec )
71f17b710fSchristos {
72f17b710fSchristos struct timeval timetv;
73f17b710fSchristos struct timeval tvlast;
74f17b710fSchristos
75f17b710fSchristos for ( timetv.tv_sec = start_sec; timetv.tv_sec <= stop_sec; timetv.tv_sec += step_sec )
76f17b710fSchristos for ( timetv.tv_usec = start_usec; timetv.tv_usec <= stop_usec; timetv.tv_usec += step_usec )
77f17b710fSchristos for ( tvlast.tv_sec = start_sec; tvlast.tv_sec <= stop_sec; tvlast.tv_sec += step_sec )
78f17b710fSchristos for ( tvlast.tv_usec = start_usec; tvlast.tv_usec <= stop_usec; tvlast.tv_usec += step_usec )
79f17b710fSchristos {
80f17b710fSchristos int rc = do_test( timetv, tvlast );
81f17b710fSchristos if (rc < 0 && exit_on_err )
82f17b710fSchristos return rc;
83f17b710fSchristos }
84f17b710fSchristos
85f17b710fSchristos return 0;
86f17b710fSchristos }
87f17b710fSchristos
88f17b710fSchristos
89f17b710fSchristos
main2(void)90f17b710fSchristos int main2( void )
91f17b710fSchristos {
92f17b710fSchristos
93f17b710fSchristos // loop from {0.0} to {1.1000000} stepping by tv_sec by 1 and tv_usec by 100000
94f17b710fSchristos test_loop( 0, 0, 1, MICROSECONDS, 1, MICROSECONDS / 10 );
95f17b710fSchristos
96f17b710fSchristos // test_loop( 0, 0, 5, MICROSECONDS, 1, MICROSECONDS / 1000 );
97f17b710fSchristos // test_loop( 0, 0, -5, -MICROSECONDS, -1, -MICROSECONDS / 1000 );
98f17b710fSchristos
99f17b710fSchristos return 0;
100f17b710fSchristos }
101f17b710fSchristos
102