profiler.cpp 2.5 KB

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