profiler.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. char _mem[sizeof(Buffer)];
  15. Buffer* _buffer = NULL;
  16. void init()
  17. {
  18. _buffer = new (_mem)Buffer(default_allocator());
  19. }
  20. void shutdown()
  21. {
  22. _buffer->~Buffer();
  23. _buffer = NULL;
  24. }
  25. const Buffer& buffer()
  26. {
  27. return *_buffer;
  28. }
  29. } // namespace profiler_globals
  30. namespace profiler
  31. {
  32. enum { THREAD_BUFFER_SIZE = 4 * 1024 };
  33. char _thread_buffer[THREAD_BUFFER_SIZE];
  34. uint32_t _thread_buffer_size = 0;
  35. Mutex _buffer_mutex;
  36. void flush_local_buffer()
  37. {
  38. ScopedMutex sm(_buffer_mutex);
  39. array::push(*profiler_globals::_buffer, _thread_buffer, _thread_buffer_size);
  40. _thread_buffer_size = 0;
  41. }
  42. void enter_profile_scope(const char* name)
  43. {
  44. if (_thread_buffer_size + sizeof(uint32_t) + sizeof(EnterProfileScope) >= THREAD_BUFFER_SIZE)
  45. flush_local_buffer();
  46. char* p = _thread_buffer + _thread_buffer_size;
  47. *(uint32_t*) p = EventType::ENTER_PROFILE_SCOPE;
  48. (*(EnterProfileScope*)(p + sizeof(uint32_t))).name = name;
  49. (*(EnterProfileScope*)(p + sizeof(uint32_t))).time = os::clocktime();
  50. _thread_buffer_size += sizeof(uint32_t) + sizeof(EnterProfileScope);
  51. }
  52. void leave_profile_scope()
  53. {
  54. if (_thread_buffer_size + sizeof(uint32_t) + sizeof(LeaveProfileScope) >= THREAD_BUFFER_SIZE)
  55. flush_local_buffer();
  56. char* p = _thread_buffer + _thread_buffer_size;
  57. *(uint32_t*) p = EventType::LEAVE_PROFILE_SCOPE;
  58. (*(LeaveProfileScope*)(p + sizeof(uint32_t))).time = os::clocktime();
  59. _thread_buffer_size += sizeof(uint32_t) + sizeof(LeaveProfileScope);
  60. }
  61. void record_float(const char* name, float value)
  62. {
  63. if (_thread_buffer_size + sizeof(uint32_t) + sizeof(RecordFloat) >= THREAD_BUFFER_SIZE)
  64. flush_local_buffer();
  65. char* p = _thread_buffer + _thread_buffer_size;
  66. *(uint32_t*) p = EventType::RECORD_FLOAT;
  67. (*(RecordFloat*)(p + sizeof(uint32_t))).name = name;
  68. (*(RecordFloat*)(p + sizeof(uint32_t))).value = value;
  69. _thread_buffer_size += sizeof(uint32_t) + sizeof(RecordFloat);
  70. }
  71. void record_vector3(const char* name, const Vector3& value)
  72. {
  73. if (_thread_buffer_size + sizeof(uint32_t) + sizeof(RecordVector3) >= THREAD_BUFFER_SIZE)
  74. flush_local_buffer();
  75. char* p = _thread_buffer + _thread_buffer_size;
  76. *(uint32_t*) p = EventType::RECORD_VECTOR3;
  77. (*(RecordVector3*)(p + sizeof(uint32_t))).name = name;
  78. (*(RecordVector3*)(p + sizeof(uint32_t))).value = value;
  79. _thread_buffer_size += sizeof(uint32_t) + sizeof(RecordVector3);
  80. }
  81. } // namespace profiler
  82. namespace profiler_globals
  83. {
  84. void flush()
  85. {
  86. profiler::flush_local_buffer();
  87. }
  88. void clear()
  89. {
  90. array::clear(*_buffer);
  91. }
  92. }
  93. } // namespace crown