1 #define _GNU_SOURCE
2 #include <sys/syscall.h>
3 #include <sys/types.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <errno.h>
7 #include <unistd.h>
8 #include <time.h>
9 
ts_subtract(struct timespec * result,const struct timespec * time1,const struct timespec * time2)10 void ts_subtract(struct timespec *result,
11                  const struct timespec *time1, const struct timespec *time2) {
12   *result = *time1;
13   result->tv_sec -= time2->tv_sec ;
14   if (result->tv_nsec < time2->tv_nsec) {
15     /* borrow a second */
16     result->tv_nsec += 1000000000L;
17     result->tv_sec--;
18   }
19   result->tv_nsec -= time2->tv_nsec;
20 }
21 
usage(const char * cmd)22 void usage(const char *cmd) {
23     fprintf(stderr, "usage: %s <iterations>\n", cmd);
24 }
25 
main(int argc,char * argv[])26 int main (int argc, char *argv[]) {
27   struct timespec start_time, end_time, elapsed_time;
28   uid_t uid;
29   long iterations, i;
30   double per_call;
31 
32   if (argc != 2) {
33     usage(argv[0]);
34     return 1;
35   }
36 
37   iterations = atol(argv[1]);
38   if (iterations < 0) {
39     usage(argv[0]);
40     return 1;
41   }
42 
43   if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time)) {
44     perror("clock_gettime");
45     return errno;
46   }
47 
48   for (i = iterations; i; i--)
49     uid = syscall(SYS_getuid);
50 
51   if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time)) {
52     perror("clock_gettime");
53     return errno;
54   }
55 
56   ts_subtract(&elapsed_time, &end_time, &start_time);
57   per_call = (elapsed_time.tv_sec * 1000000000.0L + elapsed_time.tv_nsec) /
58       (double)iterations;
59   printf("%ld calls in %ld.%09ld s (%lf ns/call)\n", iterations,
60          elapsed_time.tv_sec, elapsed_time.tv_nsec, per_call);
61 
62   return 0;
63 }
64