QueryProfiler.h 1.7 KB
Newer Older
1 2
#pragma once

N
Nikita Lapkov 已提交
3
#include <Core/Types.h>
4 5

#include <signal.h>
N
Nikita Lapkov 已提交
6
#include <time.h>
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

namespace Poco
{
    class Logger;
}

namespace DB
{

enum class TimerType : UInt8
{
    Real,
    Cpu,
};

N
Nikita Lapkov 已提交
22 23 24 25 26 27 28 29 30 31 32
/**
  * Query profiler implementation for selected thread.
  *
  * This class installs timer and signal handler on creation to:
  *  1. periodically pause given thread
  *  2. collect thread's current stack trace
  *  3. write collected stack trace to trace_pipe for TraceCollector
  *
  * Desctructor tries to unset timer and restore previous signal handler.
  * Note that signal handler implementation is defined by template parameter. See QueryProfilerReal and QueryProfilerCpu.
  */
33 34 35 36
template <typename ProfilerImpl>
class QueryProfilerBase
{
public:
N
Nikita Lapkov 已提交
37 38 39
    QueryProfilerBase(const Int32 thread_id, const int clock_type, const UInt32 period, const int pause_signal = SIGALRM);

    ~QueryProfilerBase();
40 41

private:
N
Nikita Lapkov 已提交
42 43
    void tryCleanup();

44 45 46 47 48 49 50 51 52 53 54 55
    Poco::Logger * log;

    /// Timer id from timer_create(2)
    timer_t timer_id = nullptr;

    /// Pause signal to interrupt threads to get traces
    int pause_signal;

    /// Previous signal handler to restore after query profiler exits
    struct sigaction * previous_handler = nullptr;
};

N
Nikita Lapkov 已提交
56
/// Query profiler with timer based on real clock
57 58 59
class QueryProfilerReal : public QueryProfilerBase<QueryProfilerReal>
{
public:
N
Nikita Lapkov 已提交
60 61 62
    QueryProfilerReal(const Int32 thread_id, const UInt32 period);

    static void signalHandler(int sig, siginfo_t * info, void * context);
63 64
};

N
Nikita Lapkov 已提交
65
/// Query profiler with timer based on CPU clock
66 67 68
class QueryProfilerCpu : public QueryProfilerBase<QueryProfilerCpu>
{
public:
N
Nikita Lapkov 已提交
69 70 71
    QueryProfilerCpu(const Int32 thread_id, const UInt32 period);

    static void signalHandler(int sig, siginfo_t * info, void * context);
72 73 74
};

}