1#pragma once
2
3#include <Core/Types.h>
4#include <Common/config.h>
5#include <common/config_common.h>
6#include <signal.h>
7#include <time.h>
8
9
10namespace Poco
11{
12 class Logger;
13}
14
15namespace DB
16{
17
18enum class TimerType : UInt8
19{
20 Real,
21 Cpu,
22};
23
24/**
25 * Query profiler implementation for selected thread.
26 *
27 * This class installs timer and signal handler on creation to:
28 * 1. periodically pause given thread
29 * 2. collect thread's current stack trace
30 * 3. write collected stack trace to trace_pipe for TraceCollector
31 *
32 * Desctructor tries to unset timer and restore previous signal handler.
33 * Note that signal handler implementation is defined by template parameter. See QueryProfilerReal and QueryProfilerCpu.
34 */
35template <typename ProfilerImpl>
36class QueryProfilerBase
37{
38public:
39 QueryProfilerBase(const Int32 thread_id, const int clock_type, UInt32 period, const int pause_signal_);
40 ~QueryProfilerBase();
41
42private:
43 void tryCleanup();
44
45 Poco::Logger * log;
46
47#if USE_UNWIND
48 /// Timer id from timer_create(2)
49 timer_t timer_id = nullptr;
50#endif
51
52 /// Pause signal to interrupt threads to get traces
53 int pause_signal;
54
55 /// Previous signal handler to restore after query profiler exits
56 struct sigaction * previous_handler = nullptr;
57};
58
59/// Query profiler with timer based on real clock
60class QueryProfilerReal : public QueryProfilerBase<QueryProfilerReal>
61{
62public:
63 QueryProfilerReal(const Int32 thread_id, const UInt32 period);
64
65 static void signalHandler(int sig, siginfo_t * info, void * context);
66};
67
68/// Query profiler with timer based on CPU clock
69class QueryProfilerCpu : public QueryProfilerBase<QueryProfilerCpu>
70{
71public:
72 QueryProfilerCpu(const Int32 thread_id, const UInt32 period);
73
74 static void signalHandler(int sig, siginfo_t * info, void * context);
75};
76
77}
78