circular_log.cc 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include "circular_log.h"
  2. #include "log.h"
  3. #include "simulator.h"
  4. #include "hooks_manager.h"
  5. #include <stdarg.h>
  6. CircularLog* CircularLog::g_singleton = NULL;
  7. void CircularLog::init(String filename)
  8. {
  9. g_singleton = new CircularLog(filename);
  10. }
  11. void CircularLog::enableCallbacks()
  12. {
  13. if (g_singleton)
  14. Sim()->getHooksManager()->registerHook(HookType::HOOK_SIGUSR1, CircularLog::hook_sigusr1, 0);
  15. }
  16. void CircularLog::fini()
  17. {
  18. if (g_singleton)
  19. {
  20. delete g_singleton;
  21. g_singleton = NULL;
  22. }
  23. }
  24. void CircularLog::dump()
  25. {
  26. if (g_singleton)
  27. {
  28. ScopedLock sl(g_singleton->m_lock);
  29. g_singleton->writeLog();
  30. }
  31. }
  32. CircularLog::CircularLog(String filename)
  33. : m_filename(filename)
  34. , m_buffer(new event_t[BUFFER_SIZE])
  35. , m_eventnum(0)
  36. , m_time_zero(rdtsc())
  37. {
  38. }
  39. CircularLog::~CircularLog()
  40. {
  41. writeLog();
  42. delete m_buffer;
  43. }
  44. void CircularLog::insert(const char* type, const char* msg, ...)
  45. {
  46. int position = __sync_fetch_and_add(&m_eventnum, 1) % BUFFER_SIZE;
  47. m_buffer[position].time = getTime();
  48. m_buffer[position].type = type;
  49. m_buffer[position].msg = msg;
  50. va_list args;
  51. va_start(args, msg);
  52. for(int i = 0; i < 6; ++i)
  53. m_buffer[position].args[i] = va_arg(args, UInt64);
  54. va_end(args);
  55. }
  56. void CircularLog::writeLog()
  57. {
  58. FILE *fp = fopen(m_filename.c_str(), "w");
  59. UInt64 head = m_eventnum % BUFFER_SIZE;
  60. if (head != m_eventnum)
  61. {
  62. fprintf(fp, "... %" PRIu64 " prior events ...\n", m_eventnum - BUFFER_SIZE);
  63. for(UInt64 idx = head; idx < BUFFER_SIZE; ++idx)
  64. writeEntry(fp, idx);
  65. }
  66. for(UInt64 idx = 0; idx < head; ++idx)
  67. writeEntry(fp, idx);
  68. fclose(fp);
  69. printf("[LOG] Wrote %" PRId64 " out of %" PRId64 " events to sim.clog\n", head < m_eventnum ? BUFFER_SIZE : head, m_eventnum);
  70. }
  71. void CircularLog::writeEntry(FILE *fp, int idx)
  72. {
  73. event_t &e = m_buffer[idx];
  74. fprintf(fp, "%12" PRId64 " [%s] ", e.time, e.type);
  75. fprintf(fp, e.msg, e.args[0], e.args[1], e.args[2], e.args[3], e.args[4], e.args[5]);
  76. fprintf(fp, "\n");
  77. }