1/* 2 * Copyright (C) 2002 Andi Kleen 3 * Copyright (C) 2017 Cyril Hrubis <chrubis@suse.cz> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20/* 21 * DESCRIPTION 22 * Check if gettimeofday is monotonous 23 * 24 * ALGORITHM 25 * Call gettimeofday() to get a t1 (fist value) 26 * call it again to get t2, see if t2 < t1, set t2 = t1, repeat for 10 sec 27 */ 28 29#include <stdint.h> 30#include <sys/time.h> 31#include <stdlib.h> 32#include <sys/syscall.h> 33#include <unistd.h> 34#include <time.h> 35#include <errno.h> 36 37#include "tst_test.h" 38 39#define gettimeofday(a,b) syscall(__NR_gettimeofday,a,b) 40 41static volatile sig_atomic_t done; 42static char *str_rtime; 43static int rtime = 10; 44 45static struct tst_option options[] = { 46 {"T:", &str_rtime, "-T len Test iteration runtime in seconds"}, 47 {NULL, NULL, NULL}, 48}; 49 50static void breakout(int sig) 51{ 52 done = sig; 53} 54 55static void verify_gettimeofday(void) 56{ 57 struct timeval tv1, tv2; 58 unsigned long long cnt = 0; 59 60 done = 0; 61 62 alarm(rtime); 63 64 if (gettimeofday(&tv1, NULL)) { 65 tst_res(TBROK | TERRNO, "gettimeofday() failed"); 66 return; 67 } 68 69 while (!done) { 70 if (gettimeofday(&tv2, NULL)) { 71 tst_res(TBROK | TERRNO, "gettimeofday() failed"); 72 return; 73 } 74 75 if (tv2.tv_sec < tv1.tv_sec || 76 (tv2.tv_sec == tv1.tv_sec && tv2.tv_usec < tv1.tv_usec)) { 77 tst_res(TFAIL, 78 "Time is going backwards: old %jd.%jd vs new %jd.%jd!", 79 (intmax_t) tv1.tv_sec, (intmax_t) tv1.tv_usec, 80 (intmax_t) tv2.tv_sec, (intmax_t) tv2.tv_usec); 81 return; 82 } 83 84 tv1 = tv2; 85 cnt++; 86 } 87 88 89 tst_res(TINFO, "gettimeofday() called %llu times", cnt); 90 tst_res(TPASS, "gettimeofday() monotonous in %i seconds", rtime); 91} 92 93static void setup(void) 94{ 95 if (str_rtime) { 96 rtime = atoi(str_rtime); 97 if (rtime <= 0) 98 tst_brk(TBROK, "Invalid runtime '%s'", str_rtime); 99 tst_set_timeout(rtime + 60); 100 } 101 102 SAFE_SIGNAL(SIGALRM, breakout); 103} 104 105static struct tst_test test = { 106 .setup = setup, 107 .options = options, 108 .test_all = verify_gettimeofday, 109}; 110