PerformanceEventBuffer.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <Kernel/API/KResult.h>
  8. #include <Kernel/KBuffer.h>
  9. namespace Kernel {
  10. class KBufferBuilder;
  11. struct [[gnu::packed]] MallocPerformanceEvent {
  12. size_t size;
  13. FlatPtr ptr;
  14. };
  15. struct [[gnu::packed]] FreePerformanceEvent {
  16. size_t size;
  17. FlatPtr ptr;
  18. };
  19. struct [[gnu::packed]] MmapPerformanceEvent {
  20. size_t size;
  21. FlatPtr ptr;
  22. char name[64];
  23. };
  24. struct [[gnu::packed]] MunmapPerformanceEvent {
  25. size_t size;
  26. FlatPtr ptr;
  27. };
  28. struct [[gnu::packed]] ProcessCreatePerformanceEvent {
  29. pid_t parent_pid;
  30. char executable[64];
  31. };
  32. struct [[gnu::packed]] ProcessExecPerformanceEvent {
  33. char executable[64];
  34. };
  35. struct [[gnu::packed]] ThreadCreatePerformanceEvent {
  36. pid_t parent_tid;
  37. };
  38. struct [[gnu::packed]] ContextSwitchPerformanceEvent {
  39. pid_t next_pid;
  40. u32 next_tid;
  41. };
  42. struct [[gnu::packed]] KMallocPerformanceEvent {
  43. size_t size;
  44. FlatPtr ptr;
  45. };
  46. struct [[gnu::packed]] KFreePerformanceEvent {
  47. size_t size;
  48. FlatPtr ptr;
  49. };
  50. struct [[gnu::packed]] SignpostPerformanceEvent {
  51. FlatPtr arg1;
  52. FlatPtr arg2;
  53. };
  54. struct [[gnu::packed]] PerformanceEvent {
  55. u16 type { 0 };
  56. u8 stack_size { 0 };
  57. u32 pid { 0 };
  58. u32 tid { 0 };
  59. u64 timestamp;
  60. u32 lost_samples;
  61. union {
  62. MallocPerformanceEvent malloc;
  63. FreePerformanceEvent free;
  64. MmapPerformanceEvent mmap;
  65. MunmapPerformanceEvent munmap;
  66. ProcessCreatePerformanceEvent process_create;
  67. ProcessExecPerformanceEvent process_exec;
  68. ThreadCreatePerformanceEvent thread_create;
  69. ContextSwitchPerformanceEvent context_switch;
  70. KMallocPerformanceEvent kmalloc;
  71. KFreePerformanceEvent kfree;
  72. SignpostPerformanceEvent signpost;
  73. } data;
  74. static constexpr size_t max_stack_frame_count = 64;
  75. FlatPtr stack[max_stack_frame_count];
  76. };
  77. enum class ProcessEventType {
  78. Create,
  79. Exec
  80. };
  81. class PerformanceEventBuffer {
  82. public:
  83. static OwnPtr<PerformanceEventBuffer> try_create_with_size(size_t buffer_size);
  84. KResult append(int type, FlatPtr arg1, FlatPtr arg2, const StringView& arg3, Thread* current_thread = Thread::current());
  85. KResult append_with_ip_and_bp(ProcessID pid, ThreadID tid, FlatPtr eip, FlatPtr ebp,
  86. int type, u32 lost_samples, FlatPtr arg1, FlatPtr arg2, const StringView& arg3);
  87. void clear()
  88. {
  89. m_count = 0;
  90. }
  91. size_t capacity() const { return m_buffer->size() / sizeof(PerformanceEvent); }
  92. size_t count() const { return m_count; }
  93. const PerformanceEvent& at(size_t index) const
  94. {
  95. return const_cast<PerformanceEventBuffer&>(*this).at(index);
  96. }
  97. bool to_json(KBufferBuilder&) const;
  98. void add_process(const Process&, ProcessEventType event_type);
  99. KResultOr<FlatPtr> register_string(NonnullOwnPtr<KString>);
  100. private:
  101. explicit PerformanceEventBuffer(NonnullOwnPtr<KBuffer>);
  102. template<typename Serializer>
  103. bool to_json_impl(Serializer&) const;
  104. PerformanceEvent& at(size_t index);
  105. size_t m_count { 0 };
  106. NonnullOwnPtr<KBuffer> m_buffer;
  107. NonnullOwnPtrVector<KString> m_strings;
  108. };
  109. extern bool g_profiling_all_threads;
  110. extern PerformanceEventBuffer* g_global_perf_events;
  111. extern u64 g_profiling_event_mask;
  112. }