File indexing completed on 2024-12-01 11:09:55
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 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #pragma once 0011 0012 #include <kwinglobals.h> 0013 0014 #include <QFile> 0015 #include <QMutex> 0016 #include <QMutexLocker> 0017 #include <QObject> 0018 #include <QTextStream> 0019 0020 namespace KWin 0021 { 0022 /** 0023 * FTraceLogger is a singleton utility for writing log messages using ftrace 0024 * 0025 * Usage: Either: 0026 * Set the KWIN_PERF_FTRACE environment variable before starting the application 0027 * Calling on DBus /FTrace org.kde.kwin.FTrace.setEnabled true 0028 * After having created the ftrace mount 0029 */ 0030 class KWIN_EXPORT FTraceLogger : public QObject 0031 { 0032 Q_OBJECT 0033 Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.FTrace"); 0034 Q_PROPERTY(bool isEnabled READ isEnabled NOTIFY enabledChanged) 0035 0036 public: 0037 /** 0038 * Enabled through DBus and logging has started 0039 */ 0040 bool isEnabled() const; 0041 0042 /** 0043 * Main log function 0044 * Takes any number of arguments that can be written into QTextStream 0045 */ 0046 template<typename... Args> 0047 void trace(Args... args) 0048 { 0049 Q_ASSERT(isEnabled()); 0050 QMutexLocker lock(&m_mutex); 0051 if (!m_file.isOpen()) { 0052 return; 0053 } 0054 QTextStream stream(&m_file); 0055 (stream << ... << args) << Qt::endl; 0056 } 0057 0058 Q_SIGNALS: 0059 void enabledChanged(); 0060 0061 public Q_SLOTS: 0062 Q_SCRIPTABLE void setEnabled(bool enabled); 0063 0064 private: 0065 static QString filePath(); 0066 bool open(); 0067 QFile m_file; 0068 QMutex m_mutex; 0069 KWIN_SINGLETON(FTraceLogger) 0070 }; 0071 0072 class KWIN_EXPORT FTraceDuration 0073 { 0074 public: 0075 template<typename... Args> 0076 FTraceDuration(Args... args) 0077 { 0078 static QAtomicInteger<quint32> s_context = 0; 0079 QTextStream stream(&m_message); 0080 (stream << ... << args); 0081 stream.flush(); 0082 m_context = ++s_context; 0083 FTraceLogger::self()->trace(m_message, " begin_ctx=", m_context); 0084 } 0085 0086 ~FTraceDuration(); 0087 0088 private: 0089 QByteArray m_message; 0090 quint32 m_context; 0091 }; 0092 0093 } // namespace KWin 0094 0095 /** 0096 * Optimised macro, arguments are only copied if tracing is enabled 0097 */ 0098 #define fTrace(...) \ 0099 if (KWin::FTraceLogger::self()->isEnabled()) \ 0100 KWin::FTraceLogger::self()->trace(__VA_ARGS__); 0101 0102 /** 0103 * Will insert two markers into the log. Once when called, and the second at the end of the relevant block 0104 * In GPUVis this will appear as a timed block with begin_ctx and end_ctx markers 0105 */ 0106 #define fTraceDuration(...) \ 0107 std::unique_ptr<KWin::FTraceDuration> _duration(KWin::FTraceLogger::self()->isEnabled() ? new KWin::FTraceDuration(__VA_ARGS__) : nullptr);