summaryrefslogtreecommitdiffstats
path: root/src/testlib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2012-04-09 11:37:25 -0300
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-06 21:50:28 +0100
commit9d72259f943a3b31fa4e32aeb1c5a2de3d8ca611 (patch)
treebbe81012555fc1829592d66c186a2422321b60d0 /src/testlib
parent24f059eed0be5b901bbb81ce921a942ca785fe1d (diff)
Add the skeleton Linux perf events counter for QtTest
Currently, it only prints "perf available" if you use the -perf option and perf is available. The implementation comes in the next commits. Change-Id: Ic6cdee70e21df25780799a4bc31ca2c2d923b9f8 Reviewed-by: Jason McDonald <macadder1@gmail.com>
Diffstat (limited to 'src/testlib')
-rw-r--r--src/testlib/qbenchmark.cpp4
-rw-r--r--src/testlib/qbenchmark_p.h11
-rw-r--r--src/testlib/qbenchmarkperfevents.cpp115
-rw-r--r--src/testlib/qbenchmarkperfevents_p.h82
-rw-r--r--src/testlib/qtestcase.cpp11
-rw-r--r--src/testlib/testlib.pro2
6 files changed, 224 insertions, 1 deletions
diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp
index 796d817ae2..91cafc99e3 100644
--- a/src/testlib/qbenchmark.cpp
+++ b/src/testlib/qbenchmark.cpp
@@ -87,6 +87,10 @@ QBenchmarkMeasurerBase * QBenchmarkGlobalData::createMeasurer()
} else if (mode_ == CallgrindChildProcess || mode_ == CallgrindParentProcess) {
measurer = new QBenchmarkCallgrindMeasurer;
#endif
+#ifdef QTESTLIB_USE_PERF_EVENTS
+ } else if (mode_ == PerfCounter) {
+ measurer = new QBenchmarkPerfEventsMeasurer;
+#endif
#ifdef HAVE_TICK_COUNTER
} else if (mode_ == TickCounter) {
measurer = new QBenchmarkTickMeasurer;
diff --git a/src/testlib/qbenchmark_p.h b/src/testlib/qbenchmark_p.h
index 6b5d996966..9859ca973c 100644
--- a/src/testlib/qbenchmark_p.h
+++ b/src/testlib/qbenchmark_p.h
@@ -63,12 +63,21 @@
#undef QTESTLIB_USE_VALGRIND
#endif
+#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
+#define QTESTLIB_USE_PERF_EVENTS
+#else
+#undef QTESTLIB_USE_PERF_EVENTS
+#endif
+
#include <QtTest/private/qbenchmarkmeasurement_p.h>
#include <QtCore/QMap>
#include <QtTest/qtest_global.h>
#ifdef QTESTLIB_USE_VALGRIND
#include <QtTest/private/qbenchmarkvalgrind_p.h>
#endif
+#ifdef QTESTLIB_USE_PERF_EVENTS
+#include <QtTest/private/qbenchmarkperfevents_p.h>
+#endif
#include <QtTest/private/qbenchmarkevent_p.h>
#include <QtTest/private/qbenchmarkmetric_p.h>
@@ -137,7 +146,7 @@ public:
QBenchmarkGlobalData();
~QBenchmarkGlobalData();
- enum Mode { WallTime, CallgrindParentProcess, CallgrindChildProcess, TickCounter, EventCounter };
+ enum Mode { WallTime, CallgrindParentProcess, CallgrindChildProcess, PerfCounter, TickCounter, EventCounter };
void setMode(Mode mode);
Mode mode() const { return mode_; }
QBenchmarkMeasurerBase *createMeasurer();
diff --git a/src/testlib/qbenchmarkperfevents.cpp b/src/testlib/qbenchmarkperfevents.cpp
new file mode 100644
index 0000000000..8c2a4852b4
--- /dev/null
+++ b/src/testlib/qbenchmarkperfevents.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Intel Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbenchmarkperfevents_p.h"
+#include "qbenchmark_p.h"
+
+#ifdef QTESTLIB_USE_PERF_EVENTS
+
+#include <sys/types.h>
+#include <errno.h>
+
+#include <sys/syscall.h>
+
+#include "3rdparty/linux_perf_event_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+static int perf_event_open(perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags)
+{
+ return syscall(SYS_perf_event_open, attr, pid, cpu, group_fd, flags);
+}
+
+bool QBenchmarkPerfEventsMeasurer::isAvailable()
+{
+ // this generates an EFAULT because attr == NULL if perf_event_open is available
+ // if the kernel is too old, it generates ENOSYS
+ return perf_event_open(0, 0, 0, 0, 0) == -1 && errno != ENOSYS;
+}
+
+QBenchmarkPerfEventsMeasurer::QBenchmarkPerfEventsMeasurer()
+{
+}
+
+QBenchmarkPerfEventsMeasurer::~QBenchmarkPerfEventsMeasurer()
+{
+}
+
+void QBenchmarkPerfEventsMeasurer::init()
+{
+}
+
+void QBenchmarkPerfEventsMeasurer::start()
+{
+}
+
+qint64 QBenchmarkPerfEventsMeasurer::checkpoint()
+{
+}
+
+qint64 QBenchmarkPerfEventsMeasurer::stop()
+{
+}
+
+bool QBenchmarkPerfEventsMeasurer::isMeasurementAccepted(qint64)
+{
+ return true;
+}
+
+int QBenchmarkPerfEventsMeasurer::adjustIterationCount(int)
+{
+ return 1;
+}
+
+int QBenchmarkPerfEventsMeasurer::adjustMedianCount(int)
+{
+ return 1;
+}
+
+QTest::QBenchmarkMetric QBenchmarkPerfEventsMeasurer::metricType()
+{
+ return QTest::Events;
+}
+
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/testlib/qbenchmarkperfevents_p.h b/src/testlib/qbenchmarkperfevents_p.h
new file mode 100644
index 0000000000..19e68aebc3
--- /dev/null
+++ b/src/testlib/qbenchmarkperfevents_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Intel Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBENCHMARKPERFEVENTS_P_H
+#define QBENCHMARKPERFEVENTS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtTest/private/qbenchmarkmeasurement_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QBenchmarkPerfEventsMeasurer : public QBenchmarkMeasurerBase
+{
+public:
+ QBenchmarkPerfEventsMeasurer();
+ ~QBenchmarkPerfEventsMeasurer();
+ virtual void init();
+ virtual void start();
+ virtual qint64 checkpoint();
+ virtual qint64 stop();
+ virtual bool isMeasurementAccepted(qint64 measurement);
+ virtual int adjustIterationCount(int suggestion);
+ virtual int adjustMedianCount(int suggestion);
+ virtual bool repeatCount() { return 1; }
+ virtual bool needsWarmupIteration() { return true; }
+ virtual QTest::QBenchmarkMetric metricType();
+
+ static bool isAvailable();
+private:
+};
+
+QT_END_NAMESPACE
+
+#endif // QBENCHMARKPERFEVENTS_P_H
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index ef8ffa570b..20d06f6be2 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -1341,6 +1341,9 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
#ifdef QTESTLIB_USE_VALGRIND
" -callgrind : Use callgrind to time benchmarks\n"
#endif
+#ifdef QTESTLIB_USE_PERF_EVENTS
+ " -perf : Use Linux perf events to time benchmarks\n"
+#endif
#ifdef HAVE_TICK_COUNTER
" -tickcounter : Use CPU tick counters to time benchmarks\n"
#endif
@@ -1481,6 +1484,14 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
QBenchmarkGlobalData::current->callgrindOutFileBase =
QBenchmarkValgrindUtils::outFileBase();
#endif
+#ifdef QTESTLIB_USE_PERF_EVENTS
+ } else if (strcmp(argv[i], "-perf") == 0) {
+ if (QBenchmarkPerfEventsMeasurer::isAvailable()) {
+ printf("perf available\n");
+ } else {
+ fprintf(stderr, "WARNING: Linux perf events not available. Using the walltime measurer.\n");
+ }
+#endif
#ifdef HAVE_TICK_COUNTER
} else if (strcmp(argv[i], "-tickcounter") == 0) {
QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::TickCounter);
diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro
index 8c6972f6a3..97301de151 100644
--- a/src/testlib/testlib.pro
+++ b/src/testlib/testlib.pro
@@ -16,6 +16,7 @@ HEADERS = qbenchmark.h \
qbenchmarkmeasurement_p.h \
qbenchmarkvalgrind_p.h \
qbenchmarkevent_p.h \
+ qbenchmarkperfevents_p.h \
qbenchmarkmetric_p.h \
qsignalspy.h \
qtestaccessible.h \
@@ -48,6 +49,7 @@ SOURCES = qtestcase.cpp \
qbenchmarkmeasurement.cpp \
qbenchmarkvalgrind.cpp \
qbenchmarkevent.cpp \
+ qbenchmarkperfevents.cpp \
qbenchmarkmetric.cpp \
qtestelement.cpp \
qtestelementattribute.cpp \