1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * Copyright (C) 2017 Cyril Hrubis <chrubis@suse.cz> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci/* 7f08c3bdfSopenharmony_ci * DESCRIPTION 8f08c3bdfSopenharmony_ci * Testcase to check the basic functionality of the times() system call. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * ALGORITHM 11f08c3bdfSopenharmony_ci * This testcase checks the values that times(2) system call returns. 12f08c3bdfSopenharmony_ci * Start a process, and spend some CPU time by performing a spin in 13f08c3bdfSopenharmony_ci * a for-loop. Then use the times() system call, to determine the 14f08c3bdfSopenharmony_ci * cpu time/sleep time, and other statistics. 15f08c3bdfSopenharmony_ci * 16f08c3bdfSopenharmony_ci * History 17f08c3bdfSopenharmony_ci * 07/2001 John George 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#include <sys/types.h> 21f08c3bdfSopenharmony_ci#include <sys/times.h> 22f08c3bdfSopenharmony_ci#include <errno.h> 23f08c3bdfSopenharmony_ci#include <sys/wait.h> 24f08c3bdfSopenharmony_ci#include <time.h> 25f08c3bdfSopenharmony_ci#include <signal.h> 26f08c3bdfSopenharmony_ci#include <stdlib.h> 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_ci#include "tst_test.h" 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_cistatic volatile int timeout; 31f08c3bdfSopenharmony_ci 32f08c3bdfSopenharmony_cistatic void sighandler(int signal) 33f08c3bdfSopenharmony_ci{ 34f08c3bdfSopenharmony_ci if (signal == SIGALRM) 35f08c3bdfSopenharmony_ci timeout = 1; 36f08c3bdfSopenharmony_ci} 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_cistatic volatile int k; 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_cistatic void work(void) 41f08c3bdfSopenharmony_ci{ 42f08c3bdfSopenharmony_ci int i, j; 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci while (!timeout) 45f08c3bdfSopenharmony_ci for (i = 0; i < 10000; i++) 46f08c3bdfSopenharmony_ci for (j = 0; j < 100; j++) 47f08c3bdfSopenharmony_ci k = i * j; 48f08c3bdfSopenharmony_ci timeout = 0; 49f08c3bdfSopenharmony_ci} 50f08c3bdfSopenharmony_ci 51f08c3bdfSopenharmony_cistatic void generate_utime(void) 52f08c3bdfSopenharmony_ci{ 53f08c3bdfSopenharmony_ci alarm(1); 54f08c3bdfSopenharmony_ci work(); 55f08c3bdfSopenharmony_ci} 56f08c3bdfSopenharmony_ci 57f08c3bdfSopenharmony_cistatic void generate_stime(void) 58f08c3bdfSopenharmony_ci{ 59f08c3bdfSopenharmony_ci time_t start_time, end_time; 60f08c3bdfSopenharmony_ci struct tms buf; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_ci /* 63f08c3bdfSopenharmony_ci * At least some CPU time must be used in system space. This is 64f08c3bdfSopenharmony_ci * achieved by executing the times(2) call for 65f08c3bdfSopenharmony_ci * at least 2 secs. This logic makes it independent 66f08c3bdfSopenharmony_ci * of the processor speed. 67f08c3bdfSopenharmony_ci */ 68f08c3bdfSopenharmony_ci start_time = time(NULL); 69f08c3bdfSopenharmony_ci for (;;) { 70f08c3bdfSopenharmony_ci if (times(&buf) == -1) 71f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "times failed"); 72f08c3bdfSopenharmony_ci end_time = time(NULL); 73f08c3bdfSopenharmony_ci if ((end_time - start_time) > 2) 74f08c3bdfSopenharmony_ci return; 75f08c3bdfSopenharmony_ci } 76f08c3bdfSopenharmony_ci} 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_cistatic void verify_times(void) 79f08c3bdfSopenharmony_ci{ 80f08c3bdfSopenharmony_ci int pid; 81f08c3bdfSopenharmony_ci struct tms buf1, buf2, buf3; 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_ci if (times(&buf1) == -1) 84f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "times()"); 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_ci if (buf1.tms_utime > 5) 87f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf1.tms_utime = %li", buf1.tms_utime); 88f08c3bdfSopenharmony_ci else 89f08c3bdfSopenharmony_ci tst_res(TPASS, "buf1.tms_utime <= 5"); 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci if (buf1.tms_stime > 5) 92f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf1.tms_stime = %li", buf1.tms_stime); 93f08c3bdfSopenharmony_ci else 94f08c3bdfSopenharmony_ci tst_res(TPASS, "buf1.tms_stime <= 5"); 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ci generate_utime(); 97f08c3bdfSopenharmony_ci generate_stime(); 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci if (times(&buf2) == -1) 100f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "times()"); 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_ci if (buf2.tms_utime == 0) 103f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf2.tms_utime = 0"); 104f08c3bdfSopenharmony_ci else 105f08c3bdfSopenharmony_ci tst_res(TPASS, "buf2.tms_utime = %li", buf2.tms_utime); 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci if (buf1.tms_utime >= buf2.tms_utime) { 108f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf1.tms_utime (%li) >= buf2.tms_utime (%li)", 109f08c3bdfSopenharmony_ci buf1.tms_utime, buf2.tms_utime); 110f08c3bdfSopenharmony_ci } else { 111f08c3bdfSopenharmony_ci tst_res(TPASS, "buf1.tms_utime (%li) < buf2.tms_utime (%li)", 112f08c3bdfSopenharmony_ci buf1.tms_utime, buf2.tms_utime); 113f08c3bdfSopenharmony_ci } 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_ci if (buf2.tms_stime == 0) 116f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf2.tms_stime = 0"); 117f08c3bdfSopenharmony_ci else 118f08c3bdfSopenharmony_ci tst_res(TPASS, "buf2.tms_stime = %li", buf2.tms_stime); 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci if (buf1.tms_stime >= buf2.tms_stime) { 121f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf1.tms_stime (%li) >= buf2.tms_stime (%li)", 122f08c3bdfSopenharmony_ci buf1.tms_stime, buf2.tms_stime); 123f08c3bdfSopenharmony_ci } else { 124f08c3bdfSopenharmony_ci tst_res(TPASS, "buf1.tms_stime (%li) < buf2.tms_stime (%li)", 125f08c3bdfSopenharmony_ci buf1.tms_stime, buf2.tms_stime); 126f08c3bdfSopenharmony_ci } 127f08c3bdfSopenharmony_ci 128f08c3bdfSopenharmony_ci if (buf2.tms_cutime != 0) 129f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf2.tms_cutime = %li", buf2.tms_cutime); 130f08c3bdfSopenharmony_ci else 131f08c3bdfSopenharmony_ci tst_res(TPASS, "buf2.tms_cutime = 0"); 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci if (buf2.tms_cstime != 0) 134f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf2.tms_cstime = %li", buf2.tms_cstime); 135f08c3bdfSopenharmony_ci else 136f08c3bdfSopenharmony_ci tst_res(TPASS, "buf2.tms_cstime = 0"); 137f08c3bdfSopenharmony_ci 138f08c3bdfSopenharmony_ci pid = SAFE_FORK(); 139f08c3bdfSopenharmony_ci 140f08c3bdfSopenharmony_ci if (!pid) { 141f08c3bdfSopenharmony_ci generate_utime(); 142f08c3bdfSopenharmony_ci generate_stime(); 143f08c3bdfSopenharmony_ci exit(0); 144f08c3bdfSopenharmony_ci } 145f08c3bdfSopenharmony_ci 146f08c3bdfSopenharmony_ci SAFE_WAITPID(pid, NULL, 0); 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_ci if (times(&buf3) == -1) 149f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "times()"); 150f08c3bdfSopenharmony_ci 151f08c3bdfSopenharmony_ci if (buf2.tms_utime > buf3.tms_utime) { 152f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf2.tms_utime (%li) > buf3.tms_utime (%li)", 153f08c3bdfSopenharmony_ci buf2.tms_utime, buf3.tms_utime); 154f08c3bdfSopenharmony_ci } else { 155f08c3bdfSopenharmony_ci tst_res(TPASS, "buf2.tms_utime (%li) <= buf3.tms_utime (%li)", 156f08c3bdfSopenharmony_ci buf2.tms_utime, buf3.tms_utime); 157f08c3bdfSopenharmony_ci } 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_ci if (buf2.tms_stime > buf3.tms_stime) { 160f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf2.tms_stime (%li) > buf3.tms_stime (%li)", 161f08c3bdfSopenharmony_ci buf2.tms_stime, buf3.tms_stime); 162f08c3bdfSopenharmony_ci } else { 163f08c3bdfSopenharmony_ci tst_res(TPASS, "buf2.tms_stime (%li) <= buf3.tms_stime (%li)", 164f08c3bdfSopenharmony_ci buf2.tms_stime, buf3.tms_stime); 165f08c3bdfSopenharmony_ci } 166f08c3bdfSopenharmony_ci 167f08c3bdfSopenharmony_ci if (buf3.tms_cutime == 0) 168f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf3.tms_cutime = 0"); 169f08c3bdfSopenharmony_ci else 170f08c3bdfSopenharmony_ci tst_res(TPASS, "buf3.tms_cutime = %ld", buf3.tms_cutime); 171f08c3bdfSopenharmony_ci 172f08c3bdfSopenharmony_ci if (buf3.tms_cstime == 0) 173f08c3bdfSopenharmony_ci tst_res(TFAIL, "buf3.tms_cstime = 0"); 174f08c3bdfSopenharmony_ci else 175f08c3bdfSopenharmony_ci tst_res(TPASS, "buf3.tms_cstime = %ld", buf3.tms_cstime); 176f08c3bdfSopenharmony_ci 177f08c3bdfSopenharmony_ci exit(0); 178f08c3bdfSopenharmony_ci} 179f08c3bdfSopenharmony_ci 180f08c3bdfSopenharmony_ci/* 181f08c3bdfSopenharmony_ci * Run the test in a child to reset times in case of -i option. 182f08c3bdfSopenharmony_ci */ 183f08c3bdfSopenharmony_cistatic void do_test(void) 184f08c3bdfSopenharmony_ci{ 185f08c3bdfSopenharmony_ci int pid = SAFE_FORK(); 186f08c3bdfSopenharmony_ci 187f08c3bdfSopenharmony_ci if (!pid) 188f08c3bdfSopenharmony_ci verify_times(); 189f08c3bdfSopenharmony_ci} 190f08c3bdfSopenharmony_ci 191f08c3bdfSopenharmony_cistatic void setup(void) 192f08c3bdfSopenharmony_ci{ 193f08c3bdfSopenharmony_ci SAFE_SIGNAL(SIGALRM, sighandler); 194f08c3bdfSopenharmony_ci} 195f08c3bdfSopenharmony_ci 196f08c3bdfSopenharmony_cistatic struct tst_test test = { 197f08c3bdfSopenharmony_ci .setup = setup, 198f08c3bdfSopenharmony_ci .forks_child = 1, 199f08c3bdfSopenharmony_ci .test_all = do_test, 200f08c3bdfSopenharmony_ci}; 201