PerformanceEventBuffer.h 3.5 KB

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