1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QBENCHMARK_P_H |
5 | #define QBENCHMARK_P_H |
6 | |
7 | #include <stdlib.h> |
8 | |
9 | // |
10 | // W A R N I N G |
11 | // ------------- |
12 | // |
13 | // This file is not part of the Qt API. It exists purely as an |
14 | // implementation detail. This header file may change from version to |
15 | // version without notice, or even be removed. |
16 | // |
17 | // We mean it. |
18 | // |
19 | |
20 | #include <QtCore/qglobal.h> |
21 | |
22 | #if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) && !defined(Q_OS_ANDROID) |
23 | #define QTESTLIB_USE_PERF_EVENTS |
24 | #else |
25 | #undef QTESTLIB_USE_PERF_EVENTS |
26 | #endif |
27 | |
28 | #include <QtTest/private/qbenchmarkmeasurement_p.h> |
29 | #include <QtCore/QMap> |
30 | #include <QtTest/qttestglobal.h> |
31 | #if QT_CONFIG(valgrind) |
32 | #include <QtTest/private/qbenchmarkvalgrind_p.h> |
33 | #endif |
34 | #ifdef QTESTLIB_USE_PERF_EVENTS |
35 | #include <QtTest/private/qbenchmarkperfevents_p.h> |
36 | #endif |
37 | #include <QtTest/private/qbenchmarkevent_p.h> |
38 | #include <QtTest/private/qbenchmarkmetric_p.h> |
39 | |
40 | QT_BEGIN_NAMESPACE |
41 | |
42 | struct QBenchmarkContext |
43 | { |
44 | // None of the strings below are assumed to contain commas (see toString() below) |
45 | QString slotName; |
46 | QString tag; // from _data() function |
47 | |
48 | int checkpointIndex = -1; |
49 | |
50 | QString toString() const |
51 | { |
52 | return QString::fromLatin1(ba: "%1,%2,%3" ) |
53 | .arg(args: slotName, args: tag, args: QString::number(checkpointIndex)); |
54 | } |
55 | |
56 | QBenchmarkContext() = default; |
57 | }; |
58 | Q_DECLARE_TYPEINFO(QBenchmarkContext, Q_RELOCATABLE_TYPE); |
59 | |
60 | class QBenchmarkResult |
61 | { |
62 | public: |
63 | QBenchmarkContext context; |
64 | QBenchmarkMeasurerBase::Measurement measurement = { .value: -1, .metric: QTest::FramesPerSecond }; |
65 | int iterations = -1; |
66 | bool setByMacro = true; |
67 | |
68 | QBenchmarkResult() = default; |
69 | |
70 | QBenchmarkResult( |
71 | const QBenchmarkContext &context, QBenchmarkMeasurerBase::Measurement m, |
72 | const int iterations, bool setByMacro) |
73 | : context(context) |
74 | , measurement(m) |
75 | , iterations(iterations) |
76 | , setByMacro(setByMacro) |
77 | { } |
78 | |
79 | bool operator<(const QBenchmarkResult &other) const |
80 | { |
81 | return (measurement.value / iterations) < (other.measurement.value / other.iterations); |
82 | } |
83 | }; |
84 | Q_DECLARE_TYPEINFO(QBenchmarkResult, Q_RELOCATABLE_TYPE); |
85 | |
86 | /* |
87 | The QBenchmarkGlobalData class stores global benchmark-related data. |
88 | QBenchmarkGlobalData:current is created at the beginning of qExec() |
89 | and cleared at the end. |
90 | */ |
91 | class Q_TESTLIB_EXPORT QBenchmarkGlobalData |
92 | { |
93 | public: |
94 | static QBenchmarkGlobalData *current; |
95 | |
96 | QBenchmarkGlobalData(); |
97 | ~QBenchmarkGlobalData(); |
98 | enum Mode { WallTime, CallgrindParentProcess, CallgrindChildProcess, PerfCounter, TickCounter, EventCounter }; |
99 | void setMode(Mode mode); |
100 | Mode mode() const { return mode_; } |
101 | QBenchmarkMeasurerBase *createMeasurer(); |
102 | int adjustMedianIterationCount(); |
103 | |
104 | QBenchmarkMeasurerBase *measurer = nullptr; |
105 | QBenchmarkContext context; |
106 | int walltimeMinimum = -1; |
107 | int iterationCount = -1; |
108 | int medianIterationCount = -1; |
109 | bool createChart = false; |
110 | bool verboseOutput = false; |
111 | QString callgrindOutFileBase; |
112 | int minimumTotal = -1; |
113 | private: |
114 | Mode mode_ = WallTime; |
115 | }; |
116 | |
117 | /* |
118 | The QBenchmarkTestMethodData class stores all benchmark-related data for the |
119 | current test case. QBenchmarkTestMethodData:current is set to a local |
120 | instance at the beginning of TestMethods::invokeTest() and cleared by its |
121 | destructor when that instance drops out of scope. |
122 | */ |
123 | class Q_TESTLIB_EXPORT QBenchmarkTestMethodData |
124 | { |
125 | public: |
126 | static QBenchmarkTestMethodData *current; |
127 | QBenchmarkTestMethodData(); |
128 | ~QBenchmarkTestMethodData(); |
129 | |
130 | // Called once for each data row created by the _data function, |
131 | // before and after calling the test function itself. |
132 | void beginDataRun(); |
133 | void endDataRun(); |
134 | |
135 | bool isBenchmark() const { return valid; } |
136 | bool resultsAccepted() const { return resultAccepted; } |
137 | int adjustIterationCount(int suggestion); |
138 | void setResults(const QList<QBenchmarkMeasurerBase::Measurement> &m, bool setByMacro = true); |
139 | void setResult(QBenchmarkMeasurerBase::Measurement m, bool setByMacro = true) |
140 | { setResults(m: { m }, setByMacro); } |
141 | |
142 | QList<QBenchmarkResult> results; |
143 | bool valid = false; |
144 | bool resultAccepted = false; |
145 | bool runOnce = false; |
146 | int iterationCount = -1; |
147 | }; |
148 | |
149 | // low-level API: |
150 | namespace QTest |
151 | { |
152 | int iterationCount(); |
153 | void setIterationCountHint(int count); |
154 | void setIterationCount(int count); |
155 | |
156 | void beginBenchmarkMeasurement(); |
157 | QList<QBenchmarkMeasurerBase::Measurement> endBenchmarkMeasurement(); |
158 | } |
159 | |
160 | QT_END_NAMESPACE |
161 | |
162 | #endif // QBENCHMARK_H |
163 | |