diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2015-07-28 13:22:33 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2015-08-04 13:34:22 +0000 |
commit | 4e6de08ba154e541587b2939137a3da1081750be (patch) | |
tree | 7e5f85abcdabdb3b560fe5b4fd4b38c8d20c73d3 /src/qml/debugger/qqmlprofilerservice.cpp | |
parent | e77e9dc2c32edd0f7c437df48fc40c9b6a2a03cc (diff) |
Periodically flush profiling data to client.
This reduces memory usage as the data can be deleted once it is sent.
It also reduces the time it takes to transmit the data when profiling
is stopped. It does incur a runtime cost as the sending now takes place
while the application is running. The decision to periodically flush or
not is left to the client, who can specify a flush interval when
starting profiling.
Usage of the flushing feature also relaxes the guarantees regarding the
sorting of events before they are sent. Events with higher timestamps
are now allowed to arrive before events with lower timestamps. Any
clients implementing the flushing need to take this into account. This
will eventually allow us to do away with the server-side ordering
altogether.
Task-number: QTBUG-39756
Change-Id: Idaf4931dc17f224c2bd492078b99e88b1405234e
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qml/debugger/qqmlprofilerservice.cpp')
-rw-r--r-- | src/qml/debugger/qqmlprofilerservice.cpp | 88 |
1 files changed, 72 insertions, 16 deletions
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp index 6f50b41b1b..2b26cdccf9 100644 --- a/src/qml/debugger/qqmlprofilerservice.cpp +++ b/src/qml/debugger/qqmlprofilerservice.cpp @@ -48,7 +48,8 @@ QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QQmlProfilerService, profilerInstance) QQmlProfilerService::QQmlProfilerService() - : QQmlConfigurableDebugService<QQmlDebugService>(QStringLiteral("CanvasFrameRate"), 1) + : QQmlConfigurableDebugService<QQmlDebugService>(QStringLiteral("CanvasFrameRate"), 1), + m_waitingForStop(false) { m_timer.start(); } @@ -242,6 +243,8 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine, quint64 features) if (!profiler->isRunning()) profiler->startProfiling(features); } + + emit startFlushTimer(); } emit messageToClient(name(), message); @@ -273,6 +276,9 @@ void QQmlProfilerService::stopProfiling(QQmlEngine *engine) } } + if (stopping.isEmpty()) + return; + foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) { if (!profiler->isRunning()) continue; @@ -284,6 +290,9 @@ void QQmlProfilerService::stopProfiling(QQmlEngine *engine) } } + emit stopFlushTimer(); + m_waitingForStop = true; + foreach (QQmlAbstractProfilerAdapter *profiler, reporting) profiler->reportData(); @@ -299,16 +308,19 @@ void QQmlProfilerService::sendMessages() QList<QByteArray> messages; QByteArray data; - QQmlDebugStream traceEnd(&data, QIODevice::WriteOnly); - traceEnd << m_timer.nsecsElapsed() << (int)Event << (int)EndTrace; - QSet<QQmlEngine *> seen; - foreach (QQmlAbstractProfilerAdapter *profiler, m_startTimes) { - for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); - i != m_engineProfilers.end(); ++i) { - if (i.value() == profiler && !seen.contains(i.key())) { - seen << i.key(); - traceEnd << idForObject(i.key()); + if (m_waitingForStop) { + QQmlDebugStream traceEnd(&data, QIODevice::WriteOnly); + traceEnd << m_timer.nsecsElapsed() << (int)Event << (int)EndTrace; + + QSet<QQmlEngine *> seen; + foreach (QQmlAbstractProfilerAdapter *profiler, m_startTimes) { + for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); + i != m_engineProfilers.end(); ++i) { + if (i.value() == profiler && !seen.contains(i.key())) { + seen << i.key(); + traceEnd << idForObject(i.key()); + } } } } @@ -325,15 +337,26 @@ void QQmlProfilerService::sendMessages() } } - //indicate completion - messages << data; - data.clear(); + if (m_waitingForStop) { + //indicate completion + messages << data; + data.clear(); - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << (qint64)-1 << (int)Complete; - messages << data; + QQmlDebugStream ds(&data, QIODevice::WriteOnly); + ds << (qint64)-1 << (int)Complete; + messages << data; + m_waitingForStop = false; + } emit messagesToClient(name(), messages); + + // Restart flushing if any profilers are still running + foreach (const QQmlAbstractProfilerAdapter *profiler, m_engineProfilers) { + if (profiler->isRunning()) { + emit startFlushTimer(); + break; + } + } } void QQmlProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState) @@ -360,11 +383,25 @@ void QQmlProfilerService::messageReceived(const QByteArray &message) int engineId = -1; quint64 features = std::numeric_limits<quint64>::max(); bool enabled; + uint flushInterval = 0; stream >> enabled; if (!stream.atEnd()) stream >> engineId; if (!stream.atEnd()) stream >> features; + if (!stream.atEnd()) { + stream >> flushInterval; + m_flushTimer.setInterval(flushInterval); + if (flushInterval > 0) { + connect(&m_flushTimer, SIGNAL(timeout()), this, SLOT(flush())); + connect(this, SIGNAL(startFlushTimer()), &m_flushTimer, SLOT(start())); + connect(this, SIGNAL(stopFlushTimer()), &m_flushTimer, SLOT(stop())); + } else { + disconnect(&m_flushTimer, SIGNAL(timeout()), this, SLOT(flush())); + disconnect(this, SIGNAL(startFlushTimer()), &m_flushTimer, SLOT(start())); + disconnect(this, SIGNAL(stopFlushTimer()), &m_flushTimer, SLOT(stop())); + } + } // If engineId == -1 objectForId() and then the cast will return 0. if (enabled) @@ -375,4 +412,23 @@ void QQmlProfilerService::messageReceived(const QByteArray &message) stopWaiting(); } +void QQmlProfilerService::flush() +{ + QMutexLocker lock(&m_configMutex); + + foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers) { + if (profiler->isRunning()) { + m_startTimes.insert(-1, profiler); + profiler->reportData(); + } + } + + foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) { + if (profiler->isRunning()) { + m_startTimes.insert(-1, profiler); + profiler->reportData(); + } + } +} + QT_END_NAMESPACE |