1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2002 Andi Kleen
4 * Copyright (C) 2017 Cyril Hrubis <chrubis@suse.cz>
5 */
6
7/*
8 * DESCRIPTION
9 *	Check if gettimeofday is monotonous
10 *
11 * ALGORITHM
12 *	Call gettimeofday() to get a t1 (fist value)
13 *	call it again to get t2, see if t2 < t1, set t2 = t1, repeat for 10 sec
14 */
15
16#include <stdint.h>
17#include <sys/time.h>
18#include <stdlib.h>
19#include <unistd.h>
20#include <time.h>
21#include <errno.h>
22
23#include "tst_test.h"
24#include "tst_timer.h"
25#include "lapi/syscalls.h"
26
27static volatile sig_atomic_t done;
28
29static void breakout(int sig)
30{
31	done = sig;
32}
33
34static void verify_gettimeofday(void)
35{
36	struct __kernel_old_timeval tv1, tv2;
37	unsigned long long cnt = 0;
38	int rtime = tst_remaining_runtime();
39
40	done = 0;
41
42	alarm(rtime);
43
44	if (tst_syscall(__NR_gettimeofday, &tv1, NULL))
45		tst_brk(TFAIL | TERRNO, "gettimeofday() failed");
46
47	while (!done) {
48		if (tst_syscall(__NR_gettimeofday, &tv2, NULL))
49			tst_brk(TFAIL | TERRNO, "gettimeofday() failed");
50
51		if (tv2.tv_sec < tv1.tv_sec ||
52		    (tv2.tv_sec == tv1.tv_sec && tv2.tv_usec < tv1.tv_usec)) {
53			tst_res(TFAIL,
54				"Time is going backwards: old %jd.%jd vs new %jd.%jd!",
55				(intmax_t) tv1.tv_sec, (intmax_t) tv1.tv_usec,
56				(intmax_t) tv2.tv_sec, (intmax_t) tv2.tv_usec);
57			return;
58		}
59
60		tv1 = tv2;
61		cnt++;
62	}
63
64	tst_res(TINFO, "gettimeofday() called %llu times", cnt);
65	tst_res(TPASS, "gettimeofday() monotonous in %i seconds", rtime);
66}
67
68static void setup(void)
69{
70	SAFE_SIGNAL(SIGALRM, breakout);
71}
72
73static struct tst_test test = {
74	.setup = setup,
75	.max_runtime = 10,
76	.test_all = verify_gettimeofday,
77};
78