OpenCoverage

qbenchmarkvalgrind.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/testlib/qbenchmarkvalgrind.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtTest module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include <QtTest/private/qbenchmark_p.h>-
41-
42#ifdef QTESTLIB_USE_VALGRIND-
43-
44#include <QtTest/private/qbenchmarkvalgrind_p.h>-
45#include <QtCore/qstringlist.h>-
46#include <QtCore/qcoreapplication.h>-
47#include <QtCore/qprocess.h>-
48#include <QtCore/qdir.h>-
49#include <QtCore/qset.h>-
50#include <QtTest/private/callgrind_p.h>-
51-
52QT_BEGIN_NAMESPACE-
53-
54// Returns \c true if valgrind is available.-
55bool QBenchmarkValgrindUtils::haveValgrind()-
56{-
57#ifdef NVALGRIND-
58 return false;-
59#else-
60 QProcess process;-
61 process.start(QLatin1String("valgrind"), QStringList(QLatin1String("--version")));-
62 return process.waitForStarted() && process.waitForFinished(-1);
never executed: return process.waitForStarted() && process.waitForFinished(-1);
0
63#endif-
64}-
65-
66// Reruns this program through callgrind.-
67// Returns \c true upon success, otherwise false.-
68bool QBenchmarkValgrindUtils::rerunThroughCallgrind(const QStringList &origAppArgs, int &exitCode)-
69{-
70 if (!QBenchmarkValgrindUtils::runCallgrindSubProcess(origAppArgs, exitCode)) {
!QBenchmarkVal...rgs, exitCode)Description
TRUEnever evaluated
FALSEnever evaluated
0
71 qWarning("failed to run callgrind subprocess");-
72 return false;
never executed: return false;
0
73 }-
74 return true;
never executed: return true;
0
75}-
76-
77static void dumpOutput(const QByteArray &data, FILE *fh)-
78{-
79 QFile file;-
80 file.open(fh, QIODevice::WriteOnly);-
81 file.write(data);-
82}
never executed: end of block
0
83-
84qint64 QBenchmarkValgrindUtils::extractResult(const QString &fileName)-
85{-
86 QFile file(fileName);-
87 const bool openOk = file.open(QIODevice::ReadOnly | QIODevice::Text);-
88 Q_ASSERT(openOk);-
89 Q_UNUSED(openOk);-
90-
91 qint64 val = -1;-
92 bool valSeen = false;-
93 QRegExp rxValue(QLatin1String("^summary: (\\d+)"));-
94 while (!file.atEnd()) {
!file.atEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
95 const QString line(QLatin1String(file.readLine()));-
96 if (rxValue.indexIn(line) != -1) {
rxValue.indexIn(line) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
97 Q_ASSERT(rxValue.captureCount() == 1);-
98 bool ok;-
99 val = rxValue.cap(1).toLongLong(&ok);-
100 Q_ASSERT(ok);-
101 valSeen = true;-
102 break;
never executed: break;
0
103 }-
104 }
never executed: end of block
0
105 if (Q_UNLIKELY(!valSeen))
__builtin_expe...lSeen), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
106 qFatal("Failed to extract result");
never executed: QMessageLogger(__FILE__, 106, __PRETTY_FUNCTION__).fatal("Failed to extract result");
0
107 return val;
never executed: return val;
0
108}-
109-
110// Gets the newest file name (i.e. the one with the highest integer suffix).-
111QString QBenchmarkValgrindUtils::getNewestFileName()-
112{-
113 QStringList nameFilters;-
114 QString base = QBenchmarkGlobalData::current->callgrindOutFileBase;-
115 Q_ASSERT(!base.isEmpty());-
116-
117 nameFilters << QString::fromLatin1("%1.*").arg(base);-
118 const QFileInfoList fiList = QDir().entryInfoList(nameFilters, QDir::Files | QDir::Readable);-
119 Q_ASSERT(!fiList.empty());-
120 int hiSuffix = -1;-
121 QFileInfo lastFileInfo;-
122 const QString pattern = QString::fromLatin1("%1.(\\d+)").arg(base);-
123 QRegExp rx(pattern);-
124 for (const QFileInfo &fileInfo : fiList) {-
125 const int index = rx.indexIn(fileInfo.fileName());-
126 Q_ASSERT(index == 0);-
127 Q_UNUSED(index);-
128 bool ok;-
129 const int suffix = rx.cap(1).toInt(&ok);-
130 Q_ASSERT(ok);-
131 Q_ASSERT(suffix >= 0);-
132 if (suffix > hiSuffix) {
suffix > hiSuffixDescription
TRUEnever evaluated
FALSEnever evaluated
0
133 lastFileInfo = fileInfo;-
134 hiSuffix = suffix;-
135 }
never executed: end of block
0
136 }
never executed: end of block
0
137-
138 return lastFileInfo.fileName();
never executed: return lastFileInfo.fileName();
0
139}-
140-
141qint64 QBenchmarkValgrindUtils::extractLastResult()-
142{-
143 return extractResult(getNewestFileName());
never executed: return extractResult(getNewestFileName());
0
144}-
145-
146void QBenchmarkValgrindUtils::cleanup()-
147{-
148 QStringList nameFilters;-
149 QString base = QBenchmarkGlobalData::current->callgrindOutFileBase;-
150 Q_ASSERT(!base.isEmpty());-
151 nameFilters-
152 << base // overall summary-
153 << QString::fromLatin1("%1.*").arg(base); // individual dumps-
154 const QFileInfoList fiList = QDir().entryInfoList(nameFilters, QDir::Files | QDir::Readable);-
155 for (const QFileInfo &fileInfo : fiList) {-
156 const bool removeOk = QFile::remove(fileInfo.fileName());-
157 Q_ASSERT(removeOk);-
158 Q_UNUSED(removeOk);-
159 }
never executed: end of block
0
160}
never executed: end of block
0
161-
162QString QBenchmarkValgrindUtils::outFileBase(qint64 pid)-
163{-
164 return QString::fromLatin1("callgrind.out.%1").arg(
never executed: return QString::fromLatin1("callgrind.out.%1").arg( pid != -1 ? pid : QCoreApplication::applicationPid());
0
165 pid != -1 ? pid : QCoreApplication::applicationPid());
never executed: return QString::fromLatin1("callgrind.out.%1").arg( pid != -1 ? pid : QCoreApplication::applicationPid());
0
166}-
167-
168// Reruns this program through callgrind, storing callgrind result files in the-
169// current directory.-
170// Returns \c true upon success, otherwise false.-
171bool QBenchmarkValgrindUtils::runCallgrindSubProcess(const QStringList &origAppArgs, int &exitCode)-
172{-
173 const QString execFile(origAppArgs.at(0));-
174 QStringList args;-
175 args << QLatin1String("--tool=callgrind") << QLatin1String("--instr-atstart=yes")-
176 << QLatin1String("--quiet")-
177 << execFile << QLatin1String("-callgrindchild");-
178-
179 // pass on original arguments that make sense (e.g. avoid wasting time producing output-
180 // that will be ignored anyway) ...-
181 for (int i = 1; i < origAppArgs.size(); ++i) {
i < origAppArgs.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
182 const QString arg(origAppArgs.at(i));-
183 if (arg == QLatin1String("-callgrind"))
arg == QLatin1...("-callgrind")Description
TRUEnever evaluated
FALSEnever evaluated
0
184 continue;
never executed: continue;
0
185 args << arg; // ok to pass on-
186 }
never executed: end of block
0
187-
188 QProcess process;-
189 process.start(QLatin1String("valgrind"), args);-
190 process.waitForStarted(-1);-
191 QBenchmarkGlobalData::current->callgrindOutFileBase =-
192 QBenchmarkValgrindUtils::outFileBase(process.pid());-
193 const bool finishedOk = process.waitForFinished(-1);-
194 exitCode = process.exitCode();-
195-
196 dumpOutput(process.readAllStandardOutput(), stdout);-
197 dumpOutput(process.readAllStandardError(), stderr);-
198-
199 return finishedOk;
never executed: return finishedOk;
0
200}-
201-
202void QBenchmarkCallgrindMeasurer::start()-
203{-
204 CALLGRIND_ZERO_STATS;-
205}
never executed: end of block
0
206-
207qint64 QBenchmarkCallgrindMeasurer::checkpoint()-
208{-
209 CALLGRIND_DUMP_STATS;-
210 const qint64 result = QBenchmarkValgrindUtils::extractLastResult();-
211 return result;
never executed: return result;
0
212}-
213-
214qint64 QBenchmarkCallgrindMeasurer::stop()-
215{-
216 return checkpoint();
never executed: return checkpoint();
0
217}-
218-
219bool QBenchmarkCallgrindMeasurer::isMeasurementAccepted(qint64 measurement)-
220{-
221 Q_UNUSED(measurement);-
222 return true;
never executed: return true;
0
223}-
224-
225int QBenchmarkCallgrindMeasurer::adjustIterationCount(int)-
226{-
227 return 1;
never executed: return 1;
0
228}-
229-
230int QBenchmarkCallgrindMeasurer::adjustMedianCount(int)-
231{-
232 return 1;
never executed: return 1;
0
233}-
234-
235bool QBenchmarkCallgrindMeasurer::needsWarmupIteration()-
236{-
237 return true;
never executed: return true;
0
238}-
239-
240QTest::QBenchmarkMetric QBenchmarkCallgrindMeasurer::metricType()-
241{-
242 return QTest::InstructionReads;
never executed: return QTest::InstructionReads;
0
243}-
244-
245QT_END_NAMESPACE-
246-
247#endif // QTESTLIB_USE_VALGRIND-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9