File indexing completed on 2024-11-10 04:57:44
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2021 David Edmundson <davidedmundson@kde.org> 0006 SPDX-FileCopyrightText: 2020 Roman Gilg <subdiff@gmail.com> 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #include "ftrace.h" 0012 0013 #include <QDBusConnection> 0014 #include <QDebug> 0015 #include <QDir> 0016 #include <QFile> 0017 #include <QFileInfo> 0018 #include <QScopeGuard> 0019 #include <QTextStream> 0020 0021 namespace KWin 0022 { 0023 KWIN_SINGLETON_FACTORY(KWin::FTraceLogger) 0024 0025 FTraceLogger::FTraceLogger(QObject *parent) 0026 : QObject(parent) 0027 { 0028 if (qEnvironmentVariableIsSet("KWIN_PERF_FTRACE")) { 0029 setEnabled(true); 0030 } else { 0031 QDBusConnection::sessionBus().registerObject(QStringLiteral("/FTrace"), this, QDBusConnection::ExportScriptableContents); 0032 } 0033 } 0034 0035 bool FTraceLogger::isEnabled() const 0036 { 0037 return m_file.isOpen(); 0038 } 0039 0040 void FTraceLogger::setEnabled(bool enabled) 0041 { 0042 QMutexLocker lock(&m_mutex); 0043 if (enabled == isEnabled()) { 0044 return; 0045 } 0046 0047 if (enabled) { 0048 open(); 0049 } else { 0050 m_file.close(); 0051 } 0052 Q_EMIT enabledChanged(); 0053 } 0054 0055 bool FTraceLogger::open() 0056 { 0057 const QString path = filePath(); 0058 if (path.isEmpty()) { 0059 return false; 0060 } 0061 0062 m_file.setFileName(path); 0063 if (!m_file.open(QIODevice::WriteOnly)) { 0064 qWarning() << "No access to trace marker file at:" << path; 0065 } 0066 return true; 0067 } 0068 0069 QString FTraceLogger::filePath() 0070 { 0071 if (qEnvironmentVariableIsSet("KWIN_PERF_FTRACE_FILE")) { 0072 return qgetenv("KWIN_PERF_FTRACE_FILE"); 0073 } 0074 0075 QFile mountsFile("/proc/mounts"); 0076 if (!mountsFile.open(QIODevice::ReadOnly | QIODevice::Text)) { 0077 qWarning() << "No access to mounts file. Can not determine trace marker file location."; 0078 return QString(); 0079 } 0080 0081 auto lineInfo = [](const QString &line) { 0082 const int start = line.indexOf(' ') + 1; 0083 const int end = line.indexOf(' ', start); 0084 const QString dirPath(line.mid(start, end - start)); 0085 if (dirPath.isEmpty() || !QFileInfo::exists(dirPath)) { 0086 return QFileInfo(); 0087 } 0088 return QFileInfo(QDir(dirPath), QStringLiteral("trace_marker")); 0089 }; 0090 QFileInfo markerFileInfo; 0091 QTextStream mountsIn(&mountsFile); 0092 QString mountsLine = mountsIn.readLine(); 0093 0094 while (!mountsLine.isNull()) { 0095 if (mountsLine.startsWith("tracefs")) { 0096 const auto info = lineInfo(mountsLine); 0097 if (info.exists()) { 0098 markerFileInfo = info; 0099 break; 0100 } 0101 } 0102 if (mountsLine.startsWith("debugfs")) { 0103 markerFileInfo = lineInfo(mountsLine); 0104 } 0105 mountsLine = mountsIn.readLine(); 0106 } 0107 mountsFile.close(); 0108 if (!markerFileInfo.exists()) { 0109 qWarning() << "Could not determine trace marker file location from mounts."; 0110 return QString(); 0111 } 0112 0113 return markerFileInfo.absoluteFilePath(); 0114 } 0115 0116 FTraceDuration::~FTraceDuration() 0117 { 0118 FTraceLogger::self()->trace(m_message, " end_ctx=", m_context); 0119 } 0120 0121 } 0122 0123 #include "moc_ftrace.cpp"