1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd
4 ** All rights reserved.
5 ** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
6 **
7 ** This file is part of the Qt Enterprise Perf Profiler Add-on.
8 **
9 ** GNU General Public License Usage
10 ** This file may be used under the terms of the GNU General Public License
11 ** version 3 as published by the Free Software Foundation and appearing in
12 ** the file LICENSE.GPLv3 included in the packaging of this file. Please
13 ** review the following information to ensure the GNU General Public License
14 ** requirements will be met: https://www.gnu.org/licenses/gpl.html.
15 **
16 ** If you have questions regarding the use of this file, please use
17 ** contact form at http://www.qt.io/contact-us
18 **
19 ****************************************************************************/
20 
21 #pragma once
22 
23 #include "perfattributes.h"
24 #include "perfheader.h"
25 #include "perftracingdata.h"
26 
27 #include <QHash>
28 #include <QVector>
29 
30 struct PerfEventHeader {
PerfEventHeaderPerfEventHeader31     PerfEventHeader() : type(0), misc(0), size(0) {}
32     quint32 type;
33     quint16 misc;
34     quint16 size;
35 
fixedLengthPerfEventHeader36     static quint16 fixedLength() { return sizeof(type) + sizeof(misc) + sizeof(size); }
37 };
38 
39 QDataStream &operator>>(QDataStream &stream, PerfEventHeader &header);
40 
41 struct PerfBuildId {
PerfBuildIdPerfBuildId42     PerfBuildId() : size(0) {}
43 
44     static const quint16 s_idLength = 20;
45     static const quint16 s_idPadding = 4; // 20 aligned to 8 gives 24 => 4 unused bytes
46     static const quint16 s_pathMax = 4096;
47 
48     struct BuildId {
49         qint32 pid;
50         QByteArray id; // raw id, use .toHex() to get something human-readable
51         QByteArray fileName;
52     };
53 
54     qint64 size;
55     QList<BuildId> buildIds;
56 };
57 
58 QDataStream &operator>>(QDataStream &stream, PerfBuildId &buildId);
59 QDataStream &operator<<(QDataStream &stream, const PerfBuildId::BuildId &buildId);
60 
61 struct PerfStringFeature {
62     QByteArray value;
63 };
64 
65 QDataStream &operator>>(QDataStream &stream, PerfStringFeature &stringFeature);
66 
67 struct PerfNrCpus {
68     quint32 online;
69     quint32 available;
70 };
71 
72 QDataStream &operator>>(QDataStream &stream, PerfNrCpus &numCpus);
73 QDataStream &operator<<(QDataStream &stream, const PerfNrCpus &numCpus);
74 
75 struct PerfTotalMem {
76     quint64 totalMem;
77 };
78 
79 QDataStream &operator>>(QDataStream &stream, PerfTotalMem &totalMem);
80 
81 struct PerfCmdline {
82     QList<QByteArray> cmdline;
83 };
84 
85 QDataStream &operator>>(QDataStream &stream, PerfCmdline &cmdline);
86 
87 struct PerfEventDesc {
88     struct EventDesc {
89         PerfEventAttributes attrs;
90         QByteArray name;
91         QList<quint64> ids;
92     };
93 
94     QList<EventDesc> eventDescs;
95 };
96 
97 QDataStream &operator>>(QDataStream &stream, PerfEventDesc &eventDesc);
98 
99 struct PerfCpuTopology {
100 
101     // Some kind of bitmask. Not so important for now
102     QList<QByteArray> siblingCores;
103     QList<QByteArray> siblingThreads;
104 };
105 
106 QDataStream &operator>>(QDataStream &stream, PerfCpuTopology &cpuTopology);
107 QDataStream &operator<<(QDataStream &stream, const PerfCpuTopology &cpuTopology);
108 
109 struct PerfNumaTopology {
110 
111     struct NumaNode {
112         quint32 nodeId;
113         quint64 memTotal;
114         quint64 memFree;
115         QByteArray topology;
116     };
117 
118     QList<NumaNode> nodes;
119 };
120 
121 QDataStream &operator>>(QDataStream &stream, PerfNumaTopology &numaTopology);
122 QDataStream &operator<<(QDataStream &stream, const PerfNumaTopology::NumaNode &numaNode);
123 
124 struct PerfPmuMappings {
125 
126     struct Pmu {
127         quint32 type;
128         QByteArray name;
129     };
130     QList<Pmu> pmus;
131 };
132 
133 QDataStream &operator>>(QDataStream &stream, PerfPmuMappings &pmuMappings);
134 QDataStream &operator<<(QDataStream &stream, const PerfPmuMappings::Pmu &pmu);
135 
136 struct PerfGroupDesc {
137 
138     struct GroupDesc {
139         QByteArray name;
140         quint32 leaderIndex;
141         quint32 numMembers;
142     };
143 
144     QList<GroupDesc> groupDescs;
145 };
146 
147 QDataStream &operator>>(QDataStream &stream, PerfGroupDesc &groupDesc);
148 QDataStream &operator<<(QDataStream &stream, const PerfGroupDesc::GroupDesc &groupDesc);
149 
150 struct PerfCompressed {
151     quint32 version = 0;
152     quint32 type = 0;
153     quint32 level = 0;
154     quint32 ratio = 0;
155     quint32 mmap_len = 0;
156 
157     enum Type {
158         PERF_COMP_NONE = 0,
159         PERF_COMP_ZSTD,
160         PERF_COMP_MAX
161     };
162     Q_ENUM(Type)
163     Q_GADGET
164 };
165 
166 QDataStream &operator>>(QDataStream &stream, PerfCompressed &compressed);
167 
168 class PerfFeatures
169 {
170 public:
171     PerfFeatures();
172     ~PerfFeatures();
173 
174     bool read(QIODevice *device, const PerfHeader *header);
architecture()175     const QByteArray &architecture() const { return m_arch.value; }
setArchitecture(const QByteArray & arch)176     void setArchitecture(const QByteArray &arch) { m_arch.value = arch; }
177 
tracingData()178     PerfTracingData tracingData() const { return m_tracingData; }
buildIds()179     QList<PerfBuildId::BuildId> buildIds() const { return m_buildId.buildIds; }
hostName()180     QByteArray hostName() const { return m_hostName.value; }
osRelease()181     QByteArray osRelease() const { return m_osRelease.value; }
version()182     QByteArray version() const { return m_version.value; }
nrCpus()183     PerfNrCpus nrCpus() const { return m_nrCpus; }
cpuDesc()184     QByteArray cpuDesc() const { return m_cpuDesc.value; }
cpuId()185     QByteArray cpuId() const { return m_cpuId.value; }
totalMem()186     quint64 totalMem() const { return m_totalMem.totalMem; }
cmdline()187     QList<QByteArray> cmdline() const { return m_cmdline.cmdline; }
eventDesc()188     PerfEventDesc eventDesc() const { return m_eventDesc; }
cpuTopology()189     PerfCpuTopology cpuTopology() const { return m_cpuTopology; }
numaTopology()190     QList<PerfNumaTopology::NumaNode> numaTopology() const { return m_numaToplogy.nodes; }
pmuMappings()191     QList<PerfPmuMappings::Pmu> pmuMappings() const { return m_pmuMappings.pmus; }
groupDescs()192     QList<PerfGroupDesc::GroupDesc> groupDescs() const { return m_groupDesc.groupDescs; }
compressed()193     PerfCompressed compressed() const { return m_compressed; }
194 
195 private:
196     void createFeature(QIODevice *device, QDataStream::ByteOrder byteOrder,
197                        const PerfFileSection &section, PerfHeader::Feature featureId);
198 
199     PerfTracingData m_tracingData;
200     PerfBuildId m_buildId;
201     PerfStringFeature m_hostName;
202     PerfStringFeature m_osRelease;
203     PerfStringFeature m_version;
204     PerfStringFeature m_arch;
205     PerfNrCpus m_nrCpus;
206     PerfStringFeature m_cpuDesc;
207     PerfStringFeature m_cpuId;
208     PerfTotalMem m_totalMem;
209     PerfCmdline m_cmdline;
210     PerfEventDesc m_eventDesc;
211     PerfCpuTopology m_cpuTopology;
212     PerfNumaTopology m_numaToplogy;
213     PerfPmuMappings m_pmuMappings;
214     PerfGroupDesc m_groupDesc;
215     PerfCompressed m_compressed;
216 };
217