2 * Copyright (c) 2015 Eugene Syromyatnikov <evgsyr@gmail.com>
3 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
4 * Copyright (c) 2015-2017 The strace developers.
7 * SPDX-License-Identifier: GPL-2.0-or-later
12 * This test burns some CPU cycles in user space and kernel space in order to
13 * get some non-zero values returned by times(2).
22 #include <asm/unistd.h>
23 #include <sys/times.h>
27 NUM_USER_ITERS = 1000000,
28 PARENT_CPUTIME_LIMIT_NSEC = 200000000,
29 CHILD_CPUTIME_LIMIT_NSEC = 300000000
36 volatile int dummy = 0;
41 perror_msg_and_fail("fork");
43 const long cputime_limit =
44 pid ? PARENT_CPUTIME_LIMIT_NSEC : CHILD_CPUTIME_LIMIT_NSEC;
46 /* Enjoying my user time */
47 while (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == 0) {
48 if (ts.tv_sec || ts.tv_nsec >= cputime_limit)
51 if (i && !(ts.tv_sec || ts.tv_nsec))
52 error_msg_and_skip("clock_gettime(CLOCK_PROCESS_CPUTIME_ID, {0, 0})");
54 for (i = 0; i < NUM_USER_ITERS; ++i)
58 /* Enjoying my system time */
59 while (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == 0) {
60 if (ts.tv_sec || ts.tv_nsec >= cputime_limit * 2)
73 unsigned long long llres;
76 * On systems where user's and kernel's long types are the same,
77 * prefer direct times syscall over libc's times function because
78 * the latter is more prone to return value truncation.
80 #undef USE_LIBC_SYSCALL
81 #if defined __NR_times && \
82 !defined(LINUX_MIPSN32) && \
83 !(defined __x86_64__ && defined __ILP32__)
84 # define USE_LIBC_SYSCALL 1
87 #if defined USE_LIBC_SYSCALL
88 long res = syscall(__NR_times, &tbuf);
91 perror_msg_and_skip("times");
93 llres = (unsigned long) res;
94 #elif defined __NR_times && defined __x86_64__ && defined __ILP32__
95 register long arg asm("rdi") = (long) &tbuf;
96 asm volatile("syscall\n\t"
98 : "0"(__NR_times), "r"(arg)
99 : "memory", "cc", "r11", "cx");
100 if (llres > 0xfffffffffffff000)
103 clock_t res = times(&tbuf);
105 if ((clock_t) -1 == res)
106 perror_msg_and_skip("times");
107 if (sizeof(res) < sizeof(unsigned long long))
108 llres = (unsigned long) res;
113 printf("times({tms_utime=%llu, tms_stime=%llu, ",
114 (unsigned long long) tbuf.tms_utime,
115 (unsigned long long) tbuf.tms_stime);
116 printf("tms_cutime=%llu, tms_cstime=%llu}) = %llu\n",
117 (unsigned long long) tbuf.tms_cutime,
118 (unsigned long long) tbuf.tms_cstime,
120 puts("+++ exited with 0 +++");