#include <sys/types.h>
#include <time.h>
#include <sys/time.h>
#include <sys/fcntl.h>
#include <asm/unistd.h>
#include <sys/stat.h>
#include <stdio.h>

#define rdtsc() ({ unsigned long a, d; asm volatile("rdtsc":"=a" (a), "=d" (d)) ; a; })

// for testing _just_ system call overhead.
//#define __NR_syscall __NR_stat64
#define __NR_syscall __NR_getpid

#define NR (100000)

int main()
{
        int i, ret;
        unsigned long fast = ~0UL, slow = ~0UL, overhead = ~0UL;
        struct timeval x,y;
        char *filename = "test";
        struct stat st;
        int j;

        for (i = 0; i < NR; i++) {
                unsigned long cycles = rdtsc();
                asm volatile("");
                cycles = rdtsc() - cycles;
                if (cycles < overhead)
                        overhead = cycles;
        }

        printf("overhead: %6d\n", overhead);

        for (j = 0; j < 10; j++)
        for (i = 0; i < NR; i++) {
                unsigned long cycles = rdtsc();
                asm volatile("call 0xffffe000"
                        :"=a" (ret)
                        :"0" (__NR_syscall),
                         "b" (filename),
                         "c" (&st));
                cycles = rdtsc() - cycles;
                if (cycles < fast)
                        fast = cycles;
        }

        fast -= overhead;
        printf("sysenter: %6d cycles\n", fast);

        for (j = 0; j < 10; j++)
        for (i = 0; i < NR; i++) {
                unsigned long cycles = rdtsc();
                asm volatile("int $0x80"
                        :"=a" (ret)
                        :"0" (__NR_syscall),
                         "b" (filename),
                         "c" (&st));
                cycles = rdtsc() - cycles;
                if (cycles < slow)
                        slow = cycles;
        }

        slow -= overhead;
        printf("int0x80:  %6d cycles\n", slow);
        printf("          %6d cycles difference\n", slow-fast);
        printf("factor %f\n", (double) slow / fast);
}

