123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
- /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/wait.h>
- #include <sys/time.h>
- #include <math.h>
- /*
- * USAGE:
- * ./test_start [prefixes to the program ...]
- *
- * EXAMPLES:
- * ./test_start => native start time
- * ./test_start ./libpal.so => graphene start time
- */
- #define OVERHEAD_TIMES 30000
- #define TEST_TIMES 1000
- void get_time (char * time_arg, unsigned long overhead)
- {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- unsigned long long msec = tv.tv_sec * 1000000ULL + tv.tv_usec;
- snprintf(time_arg, 30, "%llu", msec + overhead);
- }
- int main (int argc, char ** argv, char ** envp)
- {
- char * new_argv[argc + 1];
- char time_arg[30];
- for (int i = 1 ; i < argc ; i++)
- new_argv[i - 1] = argv[i];
- new_argv[argc] = NULL;
- unsigned long long times[TEST_TIMES];
- unsigned long long sum = 0, ssum = 0;
- memset(times, 0, sizeof(times));
- for (int i = 1 ; i < TEST_TIMES ; i++) {
- int pipes[2];
- if (pipe(pipes) < 0)
- break;
- pid_t pid = fork();
- if (pid < 0)
- break;
- if (!pid) {
- struct timeval tv1, tv2;
- gettimeofday(&tv1, NULL);
- for (int j = 0 ; j < OVERHEAD_TIMES ; j++)
- get_time(time_arg, 0);
- gettimeofday(&tv2, NULL);
- unsigned long long msec1 = tv1.tv_sec * 1000000ULL + tv1.tv_usec;
- unsigned long long msec2 = tv2.tv_sec * 1000000ULL + tv2.tv_usec;
- unsigned long long overhead = (msec2 - msec1) / OVERHEAD_TIMES;
- get_time(time_arg, overhead);
- close(pipes[0]);
- write(pipes[1], time_arg, 30);
- close(pipes[1]);
- execve(new_argv[0], new_argv, envp);
- exit(-1);
- }
- close(pipes[1]);
- int status;
- waitpid(pid, &status, 0);
- struct timeval tv;
- gettimeofday(&tv, NULL);
- unsigned long long msec = tv.tv_sec * 1000000ULL + tv.tv_usec;
- struct timeval tv1, tv2;
- gettimeofday(&tv1, NULL);
- for (int j = 0 ; j < OVERHEAD_TIMES ; j++)
- gettimeofday(&tv, NULL);
- gettimeofday(&tv2, NULL);
- unsigned long long msec3 = tv1.tv_sec * 1000000ULL + tv1.tv_usec;
- unsigned long long msec4 = tv2.tv_sec * 1000000ULL + tv2.tv_usec;
- unsigned long long overhead = (msec4 - msec3) / OVERHEAD_TIMES;
- if (read(pipes[0], time_arg, 30) < 0)
- break;
- times[i] = msec - atoll(time_arg);
- sum += times[i];
- ssum += times[i] * times[i];
- close(pipes[0]);
- }
- int compar (const void * arg1, const void * arg2)
- {
- register unsigned long long a1 = *((unsigned long long *) arg1);
- register unsigned long long a2 = *((unsigned long long *) arg2);
- return a1 < a2 ? -1 : (a1 == a2 ? 0 : 1);
- }
- qsort(times, TEST_TIMES, sizeof(unsigned long long), compar);
- double median =
- (TEST_TIMES % 2) ? (double) times[TEST_TIMES / 2] :
- (double) (times[TEST_TIMES / 2 - 1] + times[TEST_TIMES / 2]) / 2;
- double mean = (double) sum / TEST_TIMES;
- double stddev = sqrt((double) ssum / TEST_TIMES - mean * mean);
- double ci = 1.96 * stddev / sqrt((double) TEST_TIMES);
- printf("median = %lf, mean = %lf (+/-%lf)\n", median, mean, ci);
- return 0;
- }
|