/*
 * time trials.
 * 
 * Use of Intel cycle counting register
 */
#include <unistd.h>
#include <stdio.h>

static __inline unsigned long long
rdtsc(void)
{
        unsigned long long rv;
        
        __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
        return (rv);
}

main()
{
	volatile unsigned long long ticks;
	volatile unsigned long long ticks2;
	volatile unsigned long long a,b;
	int volatile rc;

    	ticks = rdtsc(); 
	malloc(10000);
    	ticks2 = rdtsc(); 
	printf("malloc time: %llu\n", ticks2-ticks);

	/* test 1. printf
	*/
    	ticks = rdtsc(); 
	printf("hello world\n");
    	ticks2 = rdtsc(); 
	printf("printf time: %llu\n", ticks2-ticks);

	/* test 2. printf again
	*/ 
    	ticks = rdtsc(); 
	printf("hola terra\n");
    	ticks2 = rdtsc(); 
	printf("printf time: %llu\n", ticks2-ticks);
	
	/* test 3. we sleep for 1 sec in a loop
	*/
	sleep_loop();

	/* test 4. getpid system call.  AST homage.
	*/
    	ticks = rdtsc(); 
	getpid();
    	ticks2 = rdtsc(); 
	printf("getpid: %llu\n", ticks2-ticks);

	/* test 5. bsd usleep - may work on linux
	*/
	ticks = rdtsc(); 
        usleep(1000000);
        ticks2 = rdtsc(); 
        printf("usleep 1 sec: %llu\n", ticks2-ticks);

	ticks = rdtsc(); 
        usleep(1000);
        ticks2 = rdtsc(); 
        printf("usleep 1 ms: %llu\n", ticks2-ticks);

	ticks = rdtsc(); 
        usleep(1);
        ticks2 = rdtsc(); 
	a = ticks2 - ticks;
        printf("usleep 1 us: %llu\n", a);
	printf("usleep 1 us: used * 1000000 %llu\n", a * 1000000);

	/* test 6. function call
	*/
    	ticks = rdtsc(); 
	rc = foo(2,2);
    	ticks2 = rdtsc(); 
	printf("function call: %llu\n", ticks2-ticks);

	/* test 7. fork as weighty system call
	*/
    	ticks = rdtsc(); 
	if (fork() == 0) {
    		ticks2 = rdtsc(); 
		printf("fork: in child: %llu\n", ticks2-ticks);
		exit(0);
	}
	printf("\nfork: in parent: %llu\n", ticks2-ticks);
	wait();
}

/* trivial function
 */
foo(int x, int y)
{
	return(x+y);
}

/* compare to usleep call
*/
sleep_loop()
{
	int i;
	unsigned long long ticks;
	unsigned long long ticks2;

	for (i = 0; i < 10; i++) {
		ticks = rdtsc(); 
		sleep(1);
		ticks2 = rdtsc(); 
		printf("sleep[%d]: %llu\n", i, ticks2-ticks);
	}
}
