#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;
}