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 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 22 void usage(const char *cmd) { 23 fprintf(stderr, "usage: %s <iterations>\n", cmd); 24 } 25 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