get_time.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/time.h>
  6. #include <sys/types.h>
  7. #include <sys/wait.h>
  8. #include <unistd.h>
  9. /*
  10. * USAGE:
  11. * ./test_start [prefixes to the program ...]
  12. *
  13. * EXAMPLES:
  14. * ./test_start => native start time
  15. * ./test_start ./libpal.so => graphene start time
  16. */
  17. #define OVERHEAD_TIMES 30000
  18. #define TEST_TIMES 1000
  19. void get_time(char* time_arg, unsigned long overhead) {
  20. struct timeval tv;
  21. gettimeofday(&tv, NULL);
  22. unsigned long long msec = tv.tv_sec * 1000000ULL + tv.tv_usec;
  23. snprintf(time_arg, 30, "%llu", msec + overhead);
  24. }
  25. int main(int argc, char** argv, char** envp) {
  26. char* new_argv[argc + 1];
  27. char time_arg[30];
  28. for (int i = 1; i < argc; i++) {
  29. new_argv[i - 1] = argv[i];
  30. }
  31. new_argv[argc] = NULL;
  32. unsigned long long times[TEST_TIMES];
  33. unsigned long long sum = 0, ssum = 0;
  34. memset(times, 0, sizeof(times));
  35. for (int i = 1; i < TEST_TIMES; i++) {
  36. int pipes[2];
  37. if (pipe(pipes) < 0)
  38. break;
  39. pid_t pid = fork();
  40. if (pid < 0)
  41. break;
  42. if (!pid) {
  43. struct timeval tv1, tv2;
  44. gettimeofday(&tv1, NULL);
  45. for (int j = 0; j < OVERHEAD_TIMES; j++) {
  46. get_time(time_arg, 0);
  47. }
  48. gettimeofday(&tv2, NULL);
  49. unsigned long long msec1 = tv1.tv_sec * 1000000ULL + tv1.tv_usec;
  50. unsigned long long msec2 = tv2.tv_sec * 1000000ULL + tv2.tv_usec;
  51. unsigned long long overhead = (msec2 - msec1) / OVERHEAD_TIMES;
  52. get_time(time_arg, overhead);
  53. close(pipes[0]);
  54. if (write(pipes[1], time_arg, 30) != 30) {
  55. perror("write error");
  56. return 1;
  57. }
  58. close(pipes[1]);
  59. execve(new_argv[0], new_argv, envp);
  60. exit(1);
  61. }
  62. close(pipes[1]);
  63. int status;
  64. waitpid(pid, &status, 0);
  65. struct timeval tv;
  66. gettimeofday(&tv, NULL);
  67. unsigned long long msec = tv.tv_sec * 1000000ULL + tv.tv_usec;
  68. if (read(pipes[0], time_arg, 30) < 0)
  69. break;
  70. times[i] = msec - atoll(time_arg);
  71. sum += times[i];
  72. ssum += times[i] * times[i];
  73. close(pipes[0]);
  74. }
  75. int compar(const void* arg1, const void* arg2) {
  76. register unsigned long long a1 = *((unsigned long long*)arg1);
  77. register unsigned long long a2 = *((unsigned long long*)arg2);
  78. return a1 < a2 ? -1 : (a1 == a2 ? 0 : 1);
  79. }
  80. qsort(times, TEST_TIMES, sizeof(unsigned long long), compar);
  81. double median = (TEST_TIMES % 2)
  82. ? (double)times[TEST_TIMES / 2]
  83. : (double)(times[TEST_TIMES / 2 - 1] + times[TEST_TIMES / 2]) / 2;
  84. double mean = (double)sum / TEST_TIMES;
  85. double stddev = sqrt((double)ssum / TEST_TIMES - mean * mean);
  86. double ci = 1.96 * stddev / sqrt((double)TEST_TIMES);
  87. printf("median = %lf, mean = %lf (+/-%lf)\n", median, mean, ci);
  88. return 0;
  89. }