Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

147 linhas
4.6 KiB

  1. #pragma once
  2. #ifdef _PROFILING
  3. # include <stdlib.h>
  4. # include <stdio.h>
  5. # include <string.h>
  6. # include <time.h>
  7. #ifdef _MSC_VER
  8. # include <Windows.h>
  9. #else
  10. # include <fcntl.h>
  11. # include <sys/stat.h>
  12. # include <sys/time.h>
  13. # include <sys/time.h>
  14. # include <stdint.h>
  15. # include <stdbool.h>
  16. # include <stddef.h>
  17. /* Helpful conversion constants. */
  18. static const unsigned usec_per_sec = 1000000;
  19. static const unsigned usec_per_msec = 1000;
  20. /* These functions are written to match the win32
  21. signatures and behavior as closely as possible.
  22. */
  23. bool QueryPerformanceFrequency(int64_t *frequency)
  24. {
  25. /* gettimeofday reports to microsecond accuracy. */
  26. *frequency = usec_per_sec;
  27. return true;
  28. }
  29. bool QueryPerformanceCounter(int64_t *performance_count)
  30. {
  31. struct timeval time;
  32. /* Grab the current time. */
  33. gettimeofday(&time, NULL);
  34. *performance_count = time.tv_usec + /* Microseconds. */
  35. time.tv_sec * usec_per_sec; /* Seconds. */
  36. return true;
  37. }
  38. #endif
  39. struct Profiler {
  40. #ifdef _MSC_VER
  41. LARGE_INTEGER tmp_time;
  42. #else
  43. int64_t tmp_time;
  44. #endif
  45. // same for all threads
  46. inline static char file_template[40] = "\0";
  47. // thread local
  48. inline thread_local static bool is_initialized = false;
  49. inline thread_local static size_t thread_id = -1;
  50. inline thread_local static int call_depth = 0;
  51. inline thread_local static FILE* out_file = nullptr;
  52. Profiler(const char* file, const char* name, const int line, const char* comment1, const char* comment2) {
  53. call_depth += 1;
  54. // if we never used this thread before
  55. if (!is_initialized) {
  56. thread_id = (size_t)&thread_id;
  57. time_t t = time(NULL);
  58. tm* tm_i = localtime(&t);
  59. // create folder
  60. #ifdef _MSC_VER
  61. _mkdir("./profiler_reports/");
  62. #else
  63. mkdir("./profiler_reports/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
  64. #endif
  65. // if we never even created the shared file name template
  66. if (!file_template[0]) {
  67. // make sure folder exists
  68. sprintf(file_template, "./profiler_reports/%02d.%02d.%04d-%02d.%02d.%02d-%%zd-profiler.report",
  69. tm_i->tm_mday, tm_i->tm_mon+1, tm_i->tm_year+1900,
  70. tm_i->tm_hour, tm_i->tm_min, tm_i->tm_sec);
  71. }
  72. char file_name[100];
  73. sprintf(file_name, file_template, thread_id);
  74. // printf("Hello I am %zd\n", thread_id);
  75. out_file = fopen(file_name, "w");
  76. if (!out_file) {
  77. printf("could not open %s\n", file_name);
  78. }
  79. // initially write the performance frequency
  80. QueryPerformanceFrequency(&tmp_time);
  81. #ifdef _MSC_VER
  82. fprintf(out_file, "%lld,,,,\n", tmp_time.QuadPart);
  83. #else
  84. fprintf(out_file, "%ld,,,,\n", tmp_time);
  85. #endif
  86. is_initialized = true;
  87. }
  88. QueryPerformanceCounter(&tmp_time);
  89. #ifdef _MSC_VER
  90. fprintf(out_file, "->,%lld,%s,%s,%d,%s,%s\n",
  91. tmp_time.QuadPart, name, file,
  92. line, comment1, comment2);
  93. #else
  94. fprintf(out_file, "->,%ld,%s,%s,%d,%s,%s\n",
  95. tmp_time, name, file,
  96. line, comment1, comment2);
  97. #endif
  98. };
  99. ~Profiler() {
  100. call_depth -= 1;
  101. QueryPerformanceCounter(&tmp_time);
  102. #ifdef _MSC_VER
  103. fprintf(out_file, "<-,%lld,,,,,\n", tmp_time.QuadPart);
  104. #else
  105. fprintf(out_file, "<-,%ld,,,,,\n", tmp_time);
  106. #endif
  107. if (call_depth == 0)
  108. fflush(out_file);
  109. };
  110. };
  111. # define profile_this() Profiler profiler(__FILE__, __FUNCTION__, __LINE__, "", "")
  112. # define profile_with_name(name) Profiler profiler(__FILE__, name, __LINE__, "", "")
  113. # define profile_with_comment(c1) Profiler profiler(__FILE__, __FUNCTION__, __LINE__, c1, "")
  114. # define profile_with_comments(c1,c2) Profiler profiler(__FILE__, __FUNCTION__, __LINE__, c1, c2)
  115. # define profile_with_name_and_comment(name,c1) Profiler profiler(__FILE__, name, __LINE__, c1, "")
  116. # define profile_with_name_and_comments(name,c1,c2) Profiler profiler(__FILE__, name, __LINE__, c1, c2)
  117. #else
  118. # define profile_this() do {} while(0)
  119. # define profile_with_name(name) do {} while(0)
  120. # define profile_with_comment(c1) do {} while(0)
  121. # define profile_with_comments(c1,c2) do {} while(0)
  122. # define profile_with_name_and_comment(name,c1) do {} while(0)
  123. # define profile_with_name_and_comments(name,c1,c2) do {} while(0)
  124. #endif