summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2018-06-11 16:01:01 +0200
committerEike Ziller <eike.ziller@qt.io>2018-06-11 16:01:01 +0200
commitddff6ef6fd31aa9f1707697d1e9601b00a8686b7 (patch)
tree95930b14a6841bacb52daec61d71fb6bf48e0dc7
parentce6d7583461ef7391718c74fb3b30f6347631c82 (diff)
parentb9a998065902d3364c7132bc0cdd48718e6d4ef8 (diff)
Merge remote-tracking branch 'origin/4.7'
-rw-r--r--app/perfunwind.cpp56
-rw-r--r--app/perfunwind.h2
2 files changed, 42 insertions, 16 deletions
diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp
index 0bf5e5a..17b3a16 100644
--- a/app/perfunwind.cpp
+++ b/app/perfunwind.cpp
@@ -169,11 +169,26 @@ void PerfUnwind::setMaxEventBufferSize(uint size)
void PerfUnwind::setTargetEventBufferSize(uint size)
{
+ m_lastEventBufferSize = m_targetEventBufferSize;
m_targetEventBufferSize = size;
if (size > m_maxEventBufferSize)
setMaxEventBufferSize(size);
}
+void PerfUnwind::revertTargetEventBufferSize()
+{
+ setTargetEventBufferSize(m_lastEventBufferSize);
+}
+
+bool PerfUnwind::hasTracePointAttributes() const
+{
+ for (auto &attributes : m_attributes) {
+ if (attributes.type() == PerfEventAttributes::TYPE_TRACEPOINT)
+ return true;
+ }
+ return false;
+}
+
PerfSymbolTable *PerfUnwind::symbolTable(qint32 pid)
{
PerfSymbolTable *&symbolTable = m_symbolTables[pid];
@@ -233,6 +248,12 @@ void PerfUnwind::addAttributes(const PerfEventAttributes &attributes, const QByt
foreach (quint64 id, ids)
m_attributeIds[id] = internalId;
}
+
+ // Switch to dynamic buffering if it's a trace point
+ if (attributes.type() == PerfEventAttributes::TYPE_TRACEPOINT && m_targetEventBufferSize == 0) {
+ qDebug() << "Trace point attributes detected. Switching to dynamic buffering";
+ revertTargetEventBufferSize();
+ }
}
void PerfUnwind::sendAttributes(qint32 id, const PerfEventAttributes &attributes, const QByteArray &name)
@@ -281,8 +302,11 @@ void PerfUnwind::features(const PerfFeatures &features)
const auto perfVersion = QVersionNumber::fromString(QString::fromLatin1(features.version()));
if (perfVersion >= QVersionNumber(3, 17) && m_timeOrderViolations == 0) {
- m_lastEventBufferSize = m_targetEventBufferSize;
- m_targetEventBufferSize = 0;
+ if (!hasTracePointAttributes()) {
+ qDebug() << "Linux version" << features.version()
+ << "detected. Switching to automatic buffering.";
+ setTargetEventBufferSize(0);
+ }
}
QByteArray buffer;
@@ -777,9 +801,9 @@ void PerfUnwind::finishedRound()
// this work-arounds bugs in upstream perf which leads to time order violations
// across FINISHED_ROUND events which should in theory never happen
flushEventBuffer(m_eventBufferSize / 2);
- } else if (m_timeOrderViolations == 0) {
- m_lastEventBufferSize = m_targetEventBufferSize;
- m_targetEventBufferSize = 0;
+ } else if (m_timeOrderViolations == 0 && !hasTracePointAttributes()) {
+ qDebug() << "FINISHED_ROUND detected. Switching to automatic buffering";
+ setTargetEventBufferSize(0);
}
}
@@ -855,7 +879,7 @@ void PerfUnwind::flushEventBuffer(uint desiredBufferSize)
auto sampleIt = m_sampleBuffer.begin();
auto sampleEnd = m_sampleBuffer.end();
- const uint origBufferSize = m_eventBufferSize;
+ uint bufferSize = m_eventBufferSize;
for (; m_eventBufferSize > desiredBufferSize && sampleIt != sampleEnd; ++sampleIt) {
const quint64 timestamp = sampleIt->time();
@@ -911,20 +935,20 @@ void PerfUnwind::flushEventBuffer(uint desiredBufferSize)
// Increase buffer size to reduce future time order violations
++m_timeOrderViolations;
- // First consider the original event buffer size. Obviously that is insufficient.
- m_targetEventBufferSize = origBufferSize;
-
// If we had a larger event buffer before, increase.
- if (m_targetEventBufferSize < m_lastEventBufferSize)
- m_targetEventBufferSize = m_lastEventBufferSize;
+ if (bufferSize < m_lastEventBufferSize)
+ bufferSize = m_lastEventBufferSize;
// Double the size, clamping by UINT_MAX.
- if (m_targetEventBufferSize > std::numeric_limits<uint>::max() / 2)
- m_targetEventBufferSize = std::numeric_limits<uint>::max();
+ if (bufferSize > std::numeric_limits<uint>::max() / 2)
+ bufferSize = std::numeric_limits<uint>::max();
else
- m_targetEventBufferSize *= 2;
+ bufferSize *= 2;
// Clamp by max buffer size.
- if (m_targetEventBufferSize > m_maxEventBufferSize)
- m_targetEventBufferSize = m_maxEventBufferSize;
+ if (bufferSize > m_maxEventBufferSize)
+ bufferSize = m_maxEventBufferSize;
+
+ qDebug() << "Increasing buffer size to" << bufferSize;
+ setTargetEventBufferSize(bufferSize);
}
diff --git a/app/perfunwind.h b/app/perfunwind.h
index 34f80e7..9a36440 100644
--- a/app/perfunwind.h
+++ b/app/perfunwind.h
@@ -311,6 +311,8 @@ private:
void forwardMmapBuffer(QList<PerfRecordMmap>::Iterator &it,
const QList<PerfRecordMmap>::Iterator &mmapEnd,
quint64 timestamp);
+ void revertTargetEventBufferSize();
+ bool hasTracePointAttributes() const;
};
uint qHash(const PerfUnwind::Location &location, uint seed = 0);