Profiler.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. Copyright (c) 2013 Daniele Bartolini, Michele Rossi
  3. Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
  4. Permission is hereby granted, free of charge, to any person
  5. obtaining a copy of this software and associated documentation
  6. files (the "Software"), to deal in the Software without
  7. restriction, including without limitation the rights to use,
  8. copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the
  10. Software is furnished to do so, subject to the following
  11. conditions:
  12. The above copyright notice and this permission notice shall be
  13. included in all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  16. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  19. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21. OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. #pragma once
  24. #include "OS.h"
  25. #include "Memory.h"
  26. #include "Mutex.h"
  27. #include "ScopedMutex.h"
  28. #include "Macros.h"
  29. namespace crown
  30. {
  31. namespace profiler
  32. {
  33. const char* const GLOBAL_FLOAT = "global.float";
  34. struct EventType
  35. {
  36. enum Enum
  37. {
  38. ENTER_PROFILE_SCOPE = 0,
  39. LEAVE_PROFILE_SCOPE = 1,
  40. RECORD_FLOAT = 2,
  41. RECORD_VECTOR3 = 3
  42. };
  43. };
  44. struct RecordFloat
  45. {
  46. const char* name;
  47. float value;
  48. };
  49. struct RecordVector3
  50. {
  51. const char* name;
  52. Vector3 value;
  53. };
  54. struct EnterProfileScope
  55. {
  56. const char* name;
  57. double time;
  58. };
  59. struct LeaveProfileScope
  60. {
  61. double time;
  62. };
  63. static Array<char> g_buffer(default_allocator());
  64. static Mutex g_buffer_mutex;
  65. #define THREAD_BUFFER_SIZE 1024
  66. CE_THREAD char t_buffer[THREAD_BUFFER_SIZE];
  67. CE_THREAD uint32_t t_buffer_size = 0;
  68. inline void flush_local_buffer()
  69. {
  70. ScopedMutex sm(g_buffer_mutex);
  71. //cg_buffer.push(t_buffer, t_buffer_size);
  72. uint32_t size = t_buffer_size;
  73. t_buffer_size = 0;
  74. uint32_t cur = 0;
  75. // TODO TODO TODO TODO TODO TODO
  76. // while (cur < size)
  77. // {
  78. // char* p = t_buffer + cur;
  79. // uint32_t event_type = *(uint32_t*) p;
  80. // RecordFloat event = *(RecordFloat*)(p + sizeof(uint32_t));
  81. // CE_LOGD("ev type = %d, name = %s, value = %f\n", event_type, event.name, 1.0 / event.value);
  82. // cur += sizeof(uint32_t) + sizeof(RecordFloat);
  83. // }
  84. }
  85. inline void enter_profile_scope(const char* name)
  86. {
  87. if (t_buffer_size + sizeof(uint32_t) + sizeof(EnterProfileScope) >= THREAD_BUFFER_SIZE)
  88. {
  89. flush_local_buffer();
  90. }
  91. char* p = t_buffer + t_buffer_size;
  92. *(uint32_t*) p = EventType::ENTER_PROFILE_SCOPE;
  93. (*(EnterProfileScope*)(p + sizeof(uint32_t))).name = name;
  94. (*(EnterProfileScope*)(p + sizeof(uint32_t))).time = os::milliseconds();
  95. t_buffer_size += sizeof(uint32_t) + sizeof(EnterProfileScope);
  96. }
  97. inline void leave_profile_scope()
  98. {
  99. if (t_buffer_size + sizeof(uint32_t) + sizeof(LeaveProfileScope) >= THREAD_BUFFER_SIZE)
  100. {
  101. flush_local_buffer();
  102. }
  103. char* p = t_buffer + t_buffer_size;
  104. *(uint32_t*) p = EventType::LEAVE_PROFILE_SCOPE;
  105. (*(LeaveProfileScope*)(p + sizeof(uint32_t))).time = os::milliseconds();
  106. t_buffer_size += sizeof(uint32_t) + sizeof(LeaveProfileScope);
  107. }
  108. inline void record_float(const char* name, float value)
  109. {
  110. if (t_buffer_size + sizeof(uint32_t) + sizeof(RecordFloat) >= THREAD_BUFFER_SIZE)
  111. {
  112. flush_local_buffer();
  113. }
  114. char* p = t_buffer + t_buffer_size;
  115. *(uint32_t*) p = EventType::RECORD_FLOAT;
  116. (*(RecordFloat*)(p + sizeof(uint32_t))).name = name;
  117. (*(RecordFloat*)(p + sizeof(uint32_t))).value = value;
  118. t_buffer_size += sizeof(uint32_t) + sizeof(RecordFloat);
  119. }
  120. inline void record_vector3(const char* name, const Vector3& value)
  121. {
  122. if (t_buffer_size + sizeof(uint32_t) + sizeof(RecordVector3) >= THREAD_BUFFER_SIZE)
  123. {
  124. flush_local_buffer();
  125. }
  126. char* p = t_buffer + t_buffer_size;
  127. *(uint32_t*) p = EventType::RECORD_VECTOR3;
  128. (*(RecordVector3*)(p + sizeof(uint32_t))).name = name;
  129. (*(RecordVector3*)(p + sizeof(uint32_t))).value = value;
  130. t_buffer_size += sizeof(uint32_t) + sizeof(RecordVector3);
  131. }
  132. }
  133. } // namespace crown