profiler.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. void enter_profile_scope(const char* name)
  44. {
  45. if (_thread_buffer_size + 2*sizeof(uint32_t) + sizeof(EnterProfileScope) >= THREAD_BUFFER_SIZE)
  46. flush_local_buffer();
  47. char* p = _thread_buffer + _thread_buffer_size;
  48. *(uint32_t*) p = EventType::ENTER_PROFILE_SCOPE;
  49. (*(uint32_t*)(p + sizeof(uint32_t))) = sizeof(EnterProfileScope);
  50. (*(EnterProfileScope*)(p + 2*sizeof(uint32_t))).name = name;
  51. (*(EnterProfileScope*)(p + 2*sizeof(uint32_t))).time = os::clocktime();
  52. _thread_buffer_size += sizeof(uint32_t) + sizeof(EnterProfileScope);
  53. }
  54. void leave_profile_scope()
  55. {
  56. if (_thread_buffer_size + 2*sizeof(uint32_t) + sizeof(LeaveProfileScope) >= THREAD_BUFFER_SIZE)
  57. flush_local_buffer();
  58. char* p = _thread_buffer + _thread_buffer_size;
  59. *(uint32_t*) p = EventType::LEAVE_PROFILE_SCOPE;
  60. (*(uint32_t*)(p + sizeof(uint32_t))) = sizeof(LeaveProfileScope);
  61. (*(LeaveProfileScope*)(p + 2*sizeof(uint32_t))).time = os::clocktime();
  62. _thread_buffer_size += sizeof(uint32_t) + sizeof(LeaveProfileScope);
  63. }
  64. void record_float(const char* name, float value)
  65. {
  66. if (_thread_buffer_size + 2*sizeof(uint32_t) + sizeof(RecordFloat) >= THREAD_BUFFER_SIZE)
  67. flush_local_buffer();
  68. char* p = _thread_buffer + _thread_buffer_size;
  69. *(uint32_t*) p = EventType::RECORD_FLOAT;
  70. (*(uint32_t*)(p + sizeof(uint32_t))) = sizeof(RecordFloat);
  71. (*(RecordFloat*)(p + 2*sizeof(uint32_t))).name = name;
  72. (*(RecordFloat*)(p + 2*sizeof(uint32_t))).value = value;
  73. _thread_buffer_size += sizeof(uint32_t) + sizeof(RecordFloat);
  74. }
  75. void record_vector3(const char* name, const Vector3& value)
  76. {
  77. if (_thread_buffer_size + 2*sizeof(uint32_t) + sizeof(RecordVector3) >= THREAD_BUFFER_SIZE)
  78. flush_local_buffer();
  79. char* p = _thread_buffer + _thread_buffer_size;
  80. *(uint32_t*) p = EventType::RECORD_VECTOR3;
  81. (*(uint32_t*)(p + sizeof(uint32_t))) = sizeof(RecordVector3);
  82. (*(RecordVector3*)(p + 2*sizeof(uint32_t))).name = name;
  83. (*(RecordVector3*)(p + 2*sizeof(uint32_t))).value = value;
  84. _thread_buffer_size += sizeof(uint32_t) + sizeof(RecordVector3);
  85. }
  86. void allocate_memory(const char* name, uint32_t size)
  87. {
  88. if (_thread_buffer_size + 2*sizeof(uint32_t) + sizeof(AllocateMemory) >= THREAD_BUFFER_SIZE)
  89. flush_local_buffer();
  90. char* p = _thread_buffer + _thread_buffer_size;
  91. *(uint32_t*) p = EventType::ALLOCATE_MEMORY;
  92. (*(uint32_t*)(p + sizeof(uint32_t))) = sizeof(AllocateMemory);
  93. (*(AllocateMemory*)(p + 2*sizeof(uint32_t))).name = name;
  94. (*(AllocateMemory*)(p + 2*sizeof(uint32_t))).size = size;
  95. _thread_buffer_size += sizeof(uint32_t) + sizeof(AllocateMemory);
  96. }
  97. void deallocate_memory(const char* name, uint32_t size)
  98. {
  99. if (_thread_buffer_size + 2*sizeof(uint32_t) + sizeof(DeallocateMemory) >= THREAD_BUFFER_SIZE)
  100. flush_local_buffer();
  101. char* p = _thread_buffer + _thread_buffer_size;
  102. *(uint32_t*) p = EventType::DEALLOCATE_MEMORY;
  103. (*(uint32_t*)(p + sizeof(uint32_t))) = sizeof(DeallocateMemory);
  104. (*(DeallocateMemory*)(p + 2*sizeof(uint32_t))).name = name;
  105. (*(DeallocateMemory*)(p + 2*sizeof(uint32_t))).size = size;
  106. _thread_buffer_size += sizeof(uint32_t) + sizeof(DeallocateMemory);
  107. }
  108. } // namespace profiler
  109. namespace profiler_globals
  110. {
  111. void flush()
  112. {
  113. profiler::flush_local_buffer();
  114. uint32_t end = profiler::EventType::COUNT;
  115. array::push(*_buffer, (const char*)&end, (uint32_t)sizeof(end));
  116. }
  117. void clear()
  118. {
  119. array::clear(*_buffer);
  120. }
  121. }
  122. } // namespace crown