From ea426585d663b462d93fc0546ce01119504dee4b Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 4 Jun 2013 15:10:51 -0400 Subject: [PATCH] perf2: add stats gathering Signed-off-by: Jeff Layton --- perf2.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/perf2.c b/perf2.c index 5b0ae85..6c04738 100644 --- a/perf2.c +++ b/perf2.c @@ -8,6 +8,10 @@ * locks are generally uncontended. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + #include #include #include @@ -17,17 +21,24 @@ #include #include #include +#include +#include + +#include "timespec.h" #define NRPROC (128) #define NRLOCK (10240) +static struct timespec *diff; + static int -lockunlock(int nrlock) +lockunlock(int nrlock, struct timespec *slot) { int fd, i, ret; struct flock lck = { .l_whence = SEEK_SET }; pid_t pid = getpid(); char name[10]; /* big enough for pid_t in hex + NULL */ + struct timespec start, end; ret = snprintf(name, sizeof(name), "%x", pid); if (ret >= (int)sizeof(name)) { @@ -41,6 +52,12 @@ lockunlock(int nrlock) return fd; } + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &start); + if (ret) { + perror("clock_gettime"); + return ret; + } + for (i = 0; i < nrlock; ++i) { lck.l_type = F_WRLCK; ret = fcntl(fd, F_SETLKW, &lck); @@ -55,7 +72,15 @@ lockunlock(int nrlock) break; } } + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &end); + if (ret) { + perror("clock_gettime"); + return ret; + } + close(fd); + *slot = timespec_sub(end, start); return ret; } @@ -68,11 +93,13 @@ usage(char *prog) int main(int argc, char **argv) { - int i, opt; + int i, opt, valid = 0; int nproc = NRPROC; int nlock = NRLOCK; pid_t *pids; char *dirname; + struct timespec total = { .tv_sec = 0, + .tv_nsec = 0 }; while ((opt = getopt(argc, argv, "l:n:")) != -1) { switch (opt) { @@ -110,18 +137,39 @@ main(int argc, char **argv) return 1; } + diff = mmap(0, nproc * sizeof(*diff), PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, -1, 0); + if (diff == (struct timespec *)-1) { + fprintf(stderr, "Unable to allocate timespec array!"); + return 1; + } + for (i = 0; i < nproc; ++i) { pids[i] = fork(); if (!pids[i]) - return lockunlock(nlock); + return lockunlock(nlock, &diff[i]); } for (i = 0; i < nproc; ++i) { - if (pids[i] < 0) - printf("process %d failed to fork\n", i); - else - waitpid(-1, NULL, 0); + int status; + + if (pids[i] < 0) { + fprintf(stderr, "process %d failed to fork\n", i); + continue; + } + if (waitpid(pids[i], &status, 0) < 0) { + fprintf(stderr, "unable to reap pid %d\n", pids[i]); + continue; + } + if (!WIFEXITED(status) || WEXITSTATUS(status)) { + fprintf(stderr, "pid %d exited abnormally(0x%x)\n", pids[i],status); + continue; + } + total = timespec_add(total, diff[i]); + ++valid; } + printf("Number of processes that ran normally:\t%d\n", valid); + printf("Total time spent in lock/unlock code:\t%ld.%ld\n", total.tv_sec, total.tv_nsec); return 0; } -- 2.34.1