summaryrefslogtreecommitdiffstats
path: root/src/core/jobs/qthreadpooler.cpp
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire350@gmail.com>2016-02-26 19:29:38 +0100
committerPaul Lemire <paul.lemire@kdab.com>2016-03-04 19:12:43 +0000
commit27d42a9894cdf31af5bf7c82343da9ea4ef3b64c (patch)
treed90064f8a377574989bf6099a5248f705b788d66 /src/core/jobs/qthreadpooler.cpp
parent52859382c900614a3a88eb3d7aa5af60d2d4a103 (diff)
Qt3D job run stats
Add a way to write to a trace.qt3d file stats about the frame jobs Then use the qt3dprofiler tool to visualize the trace file This is enabled by defining QT3D_JOBS_RUN_STATS at compile time Change-Id: I4d2faaf5189cd91ecc88b7ca0ca3e3e1f2f60498 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/core/jobs/qthreadpooler.cpp')
-rw-r--r--src/core/jobs/qthreadpooler.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/core/jobs/qthreadpooler.cpp b/src/core/jobs/qthreadpooler.cpp
index 79cf6040e..8c71e9296 100644
--- a/src/core/jobs/qthreadpooler.cpp
+++ b/src/core/jobs/qthreadpooler.cpp
@@ -42,10 +42,19 @@
#include <QDebug>
+#ifdef QT3D_JOBS_RUN_STATS
+#include <QFile>
+#include <QThreadStorage>
+#endif
+
QT_BEGIN_NAMESPACE
namespace Qt3DCore {
+#ifdef QT3D_JOBS_RUN_STATS
+QElapsedTimer QThreadPooler::m_jobsStatTimer;
+#endif
+
QThreadPooler::QThreadPooler(QObject *parent)
: QObject(parent),
m_futureInterface(Q_NULLPTR),
@@ -54,6 +63,9 @@ QThreadPooler::QThreadPooler(QObject *parent)
{
// Ensures that threads will never be recycled
m_threadPool.setExpiryTimeout(-1);
+#ifdef QT3D_JOBS_RUN_STATS
+ QThreadPooler::m_jobsStatTimer.start();
+#endif
}
QThreadPooler::~QThreadPooler()
@@ -158,6 +170,73 @@ int QThreadPooler::maxThreadCount() const
return m_threadPool.maxThreadCount();
}
+#ifdef QT3D_JOBS_RUN_STATS
+
+typedef QVector<JobRunStats> JobRunStatsList;
+typedef JobRunStatsList* JobRunStatsListPtr;
+typedef QThreadStorage<JobRunStatsListPtr> JobRunStatStorage;
+
+JobRunStatStorage jobStatsCached;
+
+QVector<JobRunStatsListPtr> localStorages;
+QMutex localStoragesMutex;
+
+// Called by the jobs
+void QThreadPooler::addJobLogStatsEntry(JobRunStats &stats)
+{
+ if (!jobStatsCached.hasLocalData()) {
+ QMutexLocker lock(&localStoragesMutex);
+ auto jobVector = new JobRunStatsList;
+ jobStatsCached.setLocalData(jobVector);
+ localStorages.push_back(jobVector);
+ }
+ jobStatsCached.localData()->push_back(stats);
+}
+
+// Called before jobs are executed (AspectThread)
+void QThreadPooler::starNewFrameJobLogsStats()
+{
+ Q_FOREACH (JobRunStatsListPtr storage, localStorages) {
+ const int oldSize = storage->size();
+ storage->clear();
+ storage->reserve(oldSize);
+ }
+ QThreadPooler::m_jobsStatTimer.restart();
+}
+
+// Called after jobs have been executed
+void QThreadPooler::writeFrameJobLogStats()
+{
+ static QScopedPointer<QFile> traceFile;
+ static quint32 frameId = 0;
+ if (!traceFile) {
+ traceFile.reset(new QFile(QStringLiteral("trace.qt3d")));
+ if (!traceFile->open(QFile::WriteOnly|QFile::Truncate))
+ qCritical("Failed to open trace file");
+ }
+
+ FrameHeader header;
+ header.frameId = frameId;
+ header.jobCount = 0;
+
+ Q_FOREACH (const JobRunStatsListPtr storage, localStorages)
+ header.jobCount += storage->size();
+
+ traceFile->write(reinterpret_cast<char *>(&header), sizeof(FrameHeader));
+
+
+
+ Q_FOREACH (const JobRunStatsListPtr storage, localStorages) {
+ qDebug() << Q_FUNC_INFO << localStorages.size() << storage << storage->size();
+ Q_FOREACH (const JobRunStats &stat, *storage) {
+ traceFile->write(reinterpret_cast<const char *>(&stat), sizeof(JobRunStats));
+ }
+ }
+ traceFile->flush();
+ ++frameId;
+}
+#endif
+
} // namespace Qt3DCore
QT_END_NAMESPACE