diff --git a/tests/.gitignore b/tests/.gitignore index 8500ca74..d9a0a757 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -47,6 +47,7 @@ stat32 statfs sysinfo time +times uid uid16 uid32 diff --git a/tests/Makefile.am b/tests/Makefile.am index 0ba7ca72..24e255eb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -60,6 +60,7 @@ check_PROGRAMS = \ statfs \ sysinfo \ time \ + times \ uid \ uid16 \ uid32 \ @@ -80,6 +81,7 @@ mq_LDADD = -lrt pc_LDADD = $(dl_LIBS) stat_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64 statfs_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64 +times_LDADD = -lrt uio_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64 stack_fcall_SOURCES = stack-fcall.c \ stack-fcall-0.c stack-fcall-1.c stack-fcall-2.c stack-fcall-3.c @@ -138,6 +140,7 @@ TESTS = \ ppoll.test \ sun_path.test \ time.test \ + times.test \ umovestr.test \ umovestr2.test \ unix-yy.test \ diff --git a/tests/times.c b/tests/times.c new file mode 100644 index 00000000..8bdb0ef5 --- /dev/null +++ b/tests/times.c @@ -0,0 +1,83 @@ +/** + * @file + * This test burns some CPU cycles in user space and kernel space in order to + * get some non-zero values returned by times(2). + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include +#include + +enum { + NUM_USER_ITERS = 1000000, + CPUTIME_LIMIT_SEC = 2, +}; + +int +main (void) +{ + struct tms tbuf; + struct timespec ts; + clock_t res; + unsigned long long llres; + volatile int dummy; + pid_t pid; + int i; + + pid = fork(); + + if (pid < 0) + return 77; + + /* Enjoying my user time */ + while (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == 0) { + if (ts.tv_sec >= CPUTIME_LIMIT_SEC) + break; + + for (i = 0; i < NUM_USER_ITERS; i++, dummy++) + ; + } + + /* Enjoying my system time */ + while (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == 0) { + if (ts.tv_sec >= (CPUTIME_LIMIT_SEC * 2)) + break; + + sched_yield(); + } + + if (pid == 0) { + return 0; + } else { + wait(NULL); + } + + res = times(&tbuf); + + if (res == (clock_t) -1) + return 77; + + if (sizeof(llres) > sizeof(res)) + llres = (unsigned long) res; + else + llres = res; + + printf("times({tms_utime=%llu, tms_stime=%llu, ", + (unsigned long long) tbuf.tms_utime, + (unsigned long long) tbuf.tms_stime); + printf("tms_cutime=%llu, tms_cstime=%llu}) = %llu\n", + (unsigned long long) tbuf.tms_cutime, + (unsigned long long) tbuf.tms_cstime, + llres); + puts("+++ exited with 0 +++"); + + return 0; +} diff --git a/tests/times.test b/tests/times.test new file mode 100755 index 00000000..28ecc3e9 --- /dev/null +++ b/tests/times.test @@ -0,0 +1,13 @@ +#!/bin/sh + +# Check decoding of times syscall + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +OUT="$LOG.out" +run_strace -etimes -esignal=none $args > "$OUT" +match_diff "$OUT" "$LOG" +rm -f "$OUT" + +exit 0