#define _GNU_SOURCE #include <sys/syscall.h> #include <sys/types.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <unistd.h> #include <time.h> void ts_subtract(struct timespec *result, const struct timespec *time1, const struct timespec *time2) { *result = *time1; result->tv_sec -= time2->tv_sec ; if (result->tv_nsec < time2->tv_nsec) { /* borrow a second */ result->tv_nsec += 1000000000L; result->tv_sec--; } result->tv_nsec -= time2->tv_nsec; } void usage(const char *cmd) { fprintf(stderr, "usage: %s <iterations>\n", cmd); } int main (int argc, char *argv[]) { struct timespec start_time, end_time, elapsed_time; uid_t uid; long iterations, i; double per_call; if (argc != 2) { usage(argv[0]); return 1; } iterations = atol(argv[1]); if (iterations < 0) { usage(argv[0]); return 1; } if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time)) { perror("clock_gettime"); return errno; } for (i = iterations; i; i--) uid = syscall(SYS_getuid); if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time)) { perror("clock_gettime"); return errno; } ts_subtract(&elapsed_time, &end_time, &start_time); per_call = (elapsed_time.tv_sec * 1000000000.0L + elapsed_time.tv_nsec) / (double)iterations; printf("%ld calls in %ld.%09ld s (%lf ns/call)\n", iterations, elapsed_time.tv_sec, elapsed_time.tv_nsec, per_call); return 0; }