profiler.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright (c) 2012-2014 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "profiler.h"
  6. #include "os.h"
  7. #include "array.h"
  8. #include "mutex.h"
  9. #include "memory.h"
  10. #include "vector3.h"
  11. namespace crown
  12. {
  13. namespace profiler_globals
  14. {
  15. typedef Array<char> Buffer;
  16. char _mem[sizeof(Buffer)];
  17. Buffer* _buffer = NULL;
  18. void init()
  19. {
  20. _buffer = new (_mem)Buffer(default_allocator());
  21. }
  22. void shutdown()
  23. {
  24. _buffer->~Buffer();
  25. _buffer = NULL;
  26. }
  27. const char* buffer()
  28. {
  29. return array::begin(*_buffer);
  30. }
  31. } // namespace profiler_globals
  32. namespace profiler
  33. {
  34. enum { THREAD_BUFFER_SIZE = 4 * 1024 };
  35. char _thread_buffer[THREAD_BUFFER_SIZE];
  36. uint32_t _thread_buffer_size = 0;
  37. Mutex _buffer_mutex;
  38. void flush_local_buffer()
  39. {
  40. ScopedMutex sm(_buffer_mutex);
  41. array::push(*profiler_globals::_buffer, _thread_buffer, _thread_buffer_size);
  42. _thread_buffer_size = 0;
  43. }
  44. template <typename T>
  45. void push(EventType::Enum type, const T& ev)
  46. {
  47. if (_thread_buffer_size + 2*sizeof(uint32_t) + sizeof(ev) >= THREAD_BUFFER_SIZE)
  48. flush_local_buffer();
  49. char* p = _thread_buffer + _thread_buffer_size;
  50. *(uint32_t*)p = type;
  51. p += sizeof(uint32_t);
  52. *(uint32_t*)p = sizeof(ev);
  53. p += sizeof(uint32_t);
  54. *(T*)p = ev;
  55. _thread_buffer_size += 2*sizeof(uint32_t) + sizeof(ev);
  56. }
  57. void enter_profile_scope(const char* name)
  58. {
  59. EnterProfileScope ev;
  60. ev.name = name;
  61. ev.time = os::clocktime();
  62. push(EventType::ENTER_PROFILE_SCOPE, ev);
  63. }
  64. void leave_profile_scope()
  65. {
  66. LeaveProfileScope ev;
  67. ev.time = os::clocktime();
  68. push(EventType::LEAVE_PROFILE_SCOPE, ev);
  69. }
  70. void record_float(const char* name, float value)
  71. {
  72. RecordFloat ev;
  73. ev.name = name;
  74. ev.value = value;
  75. push(EventType::RECORD_FLOAT, ev);
  76. }
  77. void record_vector3(const char* name, const Vector3& value)
  78. {
  79. RecordVector3 ev;
  80. ev.name = name;
  81. ev.value = value;
  82. push(EventType::RECORD_VECTOR3, ev);
  83. }
  84. void allocate_memory(const char* name, uint32_t size)
  85. {
  86. AllocateMemory ev;
  87. ev.name = name;
  88. ev.size = size;
  89. push(EventType::ALLOCATE_MEMORY, ev);
  90. }
  91. void deallocate_memory(const char* name, uint32_t size)
  92. {
  93. DeallocateMemory ev;
  94. ev.name = name;
  95. ev.size = size;
  96. push(EventType::DEALLOCATE_MEMORY, ev);
  97. }
  98. } // namespace profiler
  99. namespace profiler_globals
  100. {
  101. void flush()
  102. {
  103. profiler::flush_local_buffer();
  104. uint32_t end = profiler::EventType::COUNT;
  105. array::push(*_buffer, (const char*)&end, (uint32_t)sizeof(end));
  106. }
  107. void clear()
  108. {
  109. array::clear(*_buffer);
  110. }
  111. }
  112. } // namespace crown