#include #include #include #include #include #include static void* initial_brk; unsigned f_return0() { return 0; } unsigned f_getpid() { return getpid(); } unsigned f_getppid() { return getppid(); } unsigned f_time() { return time(nullptr); } unsigned f_clock_gettime() { timespec ts; clock_gettime(CLOCK_REALTIME, &ts); return ts.tv_nsec; } unsigned f_clock_gettime_coarse() { timespec ts; clock_gettime(CLOCK_REALTIME_COARSE, &ts); return ts.tv_nsec; } unsigned f_sbrk() { return reinterpret_cast(sbrk(0)); } unsigned f_brk() { return brk(initial_brk); } unsigned f_open_close() { int fd = open("/dev/null", O_RDONLY); close(fd); return fd; } unsigned f_close() { return close(0); } void usage() { fprintf(stderr, "Usage: ./syscall [-0pPtcCsbox]\n"); exit(1); } int main(int argc, char** argv) { unsigned (*volatile f)(void) = f_getpid; initial_brk = sbrk(0); int opt; while ((opt = getopt(argc, argv, "0pPtcCsbox")) != -1) { switch (opt) { case '0': f = f_return0; break; case 'p': f = f_getpid; break; case 'P': f = f_getppid; break; case 't': f = f_time; break; case 'c': f = f_clock_gettime; break; case 'C': f = f_clock_gettime_coarse; break; case 's': f = f_sbrk; break; case 'b': f = f_brk; break; case 'o': f = f_open_close; break; case 'x': f = f_close; break; default: usage(); } } if (optind != argc) { usage(); } timespec ts0; clock_gettime(CLOCK_REALTIME, &ts0); unsigned long n = 0; for (unsigned i = 0; i != 1000000; ++i) { n += f(); } timespec ts1; clock_gettime(CLOCK_REALTIME, &ts1); double t0 = ts0.tv_sec + ts0.tv_nsec / 1e9; double t1 = ts1.tv_sec + ts1.tv_nsec / 1e9; printf("result: %lu in %.06fs\n", n, t1 - t0); }