diff options
-rw-r--r-- | regress/sys/kern/nanosleep/Makefile | 20 | ||||
-rw-r--r-- | regress/sys/kern/nanosleep/nanosleep.c | 220 |
2 files changed, 240 insertions, 0 deletions
diff --git a/regress/sys/kern/nanosleep/Makefile b/regress/sys/kern/nanosleep/Makefile new file mode 100644 index 00000000000..b81a0876cb1 --- /dev/null +++ b/regress/sys/kern/nanosleep/Makefile @@ -0,0 +1,20 @@ +# $OpenBSD: Makefile,v 1.1 2002/02/16 00:47:55 art Exp $ + +PROG= nanosleep +SRCS= nanosleep.c + +trivial: nanosleep + ./nanosleep -t + +with_signal: nanosleep + ./nanosleep -s + +time_elapsed: nanosleep + ./nanosleep -e + +time_elapsed_with_signal: nanosleep + ./nanosleep -E + +REGRESSTARGETS=trivial with_signal time_elapsed time_elapsed_with_signal + +.include <bsd.regress.mk> diff --git a/regress/sys/kern/nanosleep/nanosleep.c b/regress/sys/kern/nanosleep/nanosleep.c new file mode 100644 index 00000000000..08ddba13390 --- /dev/null +++ b/regress/sys/kern/nanosleep/nanosleep.c @@ -0,0 +1,220 @@ +/* $OpenBSD: nanosleep.c,v 1.1 2002/02/16 00:47:55 art Exp $ */ +/* + * Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain. + */ +#include <sys/types.h> +#include <sys/time.h> + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <time.h> +#include <err.h> +#include <signal.h> + +int trivial(void); +int with_signal(void); +int time_elapsed(void); +int time_elapsed_with_signal(void); + +void sighandler(int); + +int +main(int argc, char **argv) +{ + int ch, ret; + + ret = 0; + + while ((ch = getopt(argc, argv, "tseE")) != -1) { + switch (ch) { + case 't': + ret |= trivial(); + break; + case 's': + ret |= with_signal(); + break; + case 'e': + ret |= time_elapsed(); + break; + case 'E': + ret |= time_elapsed_with_signal(); + break; + default: + fprintf(stderr, "Usage: nanosleep [-tse]\n"); + exit(1); + } + } + + return (ret); +} + +void +sighandler(int signum) +{ +} + +int +trivial(void) +{ + struct timespec ts, rts; + + ts.tv_sec = 0; + ts.tv_nsec = 30000000; + rts.tv_sec = 4711; /* Just add to the confusion */ + rts.tv_nsec = 4711; + if (nanosleep(&ts, &rts) < 0) { + warn("trivial: nanosleep"); + return 1; + } + + /* + * Just check that we don't get any leftover time if we sleep the + * amount of time we want to sleep. + * If we receive any signal, something is wrong anyway. + */ + if (rts.tv_sec != 0 || rts.tv_nsec != 0) { + warnx("trivial: non-zero time? %d/%d", rts.tv_sec, + rts.tv_nsec); + return 1; + } + + return 0; +} + +int +with_signal(void) +{ + struct timespec ts, rts; + pid_t pid; + int status; + + signal(SIGUSR1, sighandler); + + pid = getpid(); + + switch(fork()) { + case -1: + err(1, "fork"); + default: + ts.tv_sec = 1; + ts.tv_nsec = 0; + nanosleep(&ts, NULL); + kill(pid, SIGUSR1); + exit(0); + } + + ts.tv_sec = 10; + ts.tv_nsec = 0; + rts.tv_sec = 0; + rts.tv_nsec = 0; + if (nanosleep(&ts, &rts) == 0) { + warn("with-signal: nanosleep"); + return 1; + } + if (rts.tv_sec == 0 && rts.tv_nsec == 0) { + warnx("with-signal: zero time"); + return 1; + } + + if (wait(&status) < 0) + err(1, "wait"); + + return 0; +} + +int +time_elapsed(void) +{ + struct timespec ts; + struct timeval stv, etv; + + ts.tv_sec = 0; + ts.tv_nsec = 500000000; + + if (gettimeofday(&stv, NULL) < 0) { + warn("gettimeofday"); + return 1; + } + + if (nanosleep(&ts, NULL) < 0) { + warn("nanosleep"); + return 1; + } + + if (gettimeofday(&etv, NULL) < 0) { + warn("gettimeofday"); + return 1; + } + + timersub(&etv, &stv, &stv); + + if (stv.tv_sec == 0 && stv.tv_usec < 500000) { + warnx("slept less than 0.5 sec"); + return 1; + } + + return 0; +} + +int +time_elapsed_with_signal(void) +{ + struct timespec ts, rts; + struct timeval stv, etv; + pid_t pid; + int status; + + signal(SIGUSR1, sighandler); + + pid = getpid(); + + switch(fork()) { + case -1: + err(1, "fork"); + default: + ts.tv_sec = 1; + ts.tv_nsec = 0; + nanosleep(&ts, NULL); + kill(pid, SIGUSR1); + exit(0); + } + + ts.tv_sec = 10; + ts.tv_nsec = 0; + rts.tv_sec = 0; + rts.tv_nsec = 0; + + if (gettimeofday(&stv, NULL) < 0) { + warn("gettimeofday"); + return 1; + } + + if (nanosleep(&ts, &rts) == 0) { + warn("nanosleep"); + return 1; + } + + if (gettimeofday(&etv, NULL) < 0) { + warn("gettimeofday"); + return 1; + } + + timersub(&etv, &stv, &stv); + + etv.tv_sec = rts.tv_sec; + etv.tv_usec = rts.tv_nsec / 1000 + 1; /* the '+ 1' is a "roundup" */ + + timeradd(&etv, &stv, &stv); + + if (stv.tv_sec == 0 && stv.tv_usec < 500000) { + warnx("slept less than 0.5 sec"); + return 1; + } + + + if (wait(&status) < 0) + err(1, "wait"); + + return 0; +} |