#include #include #include #include #include #include #include #include #define timespecsub(vvp, uvp) \ do { \ (vvp)->tv_sec -= (uvp)->tv_sec; \ (vvp)->tv_nsec -= (uvp)->tv_nsec; \ if ((vvp)->tv_nsec < 0) { \ (vvp)->tv_sec--; \ (vvp)->tv_nsec += 1000000000; \ } \ } while (0) void inittest(int nprocs) { int i; int val; if (setpgid(getpid(), getpid()) != 0) err(1, "setpgid"); val = 99999; if (sysctlbyname("kern.randompid", NULL, NULL, &val, sizeof(int)) != 0) err(1, "sysctlbyname(\"kern.randompid\")"); for (i = 0; i < nprocs; i++) { switch (fork()) { case 0: pause(); exit(0); default: break; case -1: err(1, "fork"); } } val = 0; if (sysctlbyname("kern.randompid", NULL, NULL, &val, sizeof(int)) != 0) err(1, "sysctlbyname(\"kern.randompid\")"); } void runtest(void) { pid_t pid; int dummy; switch (pid = fork()) { case 0: exit(0); default: wait4(pid, &dummy, 0, NULL); break; case -1: err(1, "fork"); } } void cleantest(void) { int dummy; killpg(0, SIGINT); /* XXX doesn't work */ } int main(int argc, char *argv[]) { struct timespec start, end; int i, iters, nprocs; if (argc != 3) errx(1, "usage: %s processes iterations", argv[0]); nprocs = atoi(argv[1]); if (nprocs < 0) errx(1, "number of processes must be nonnegative"); iters = atoi(argv[2]); if (iters <= 0) errx(1, "iterations must be positive"); inittest(nprocs); if (clock_gettime(CLOCK_REALTIME, &start) != 0) err(1, "clock_gettime"); for (i = 0; i < iters; i++) runtest(); if (clock_gettime(CLOCK_REALTIME, &end) != 0) err(1, "clock_gettime"); timespecsub(&end, &start); printf("%ju.%09ju\n", (uintmax_t)end.tv_sec, (uintmax_t)end.tv_nsec); fflush(stdout); cleantest(); exit(0); }