File: eventtype.h

package info (click to toggle)
kcachegrind 4%3A25.04.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,964 kB
  • sloc: cpp: 32,149; xml: 403; perl: 325; python: 235; sh: 8; makefile: 6
file content (211 lines) | stat: -rw-r--r-- 6,305 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
    This file is part of KCachegrind.

    SPDX-FileCopyrightText: 2002-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>

    SPDX-License-Identifier: GPL-2.0-only
*/

#ifndef EVENTTYPE_H
#define EVENTTYPE_H

#include <QString>

#include "subcost.h"
#include "costitem.h"

class EventTypeSet;

/**
 * A cost type, e.g. "L1 Read Miss", short "l1rm".
 *
 * We distinguish "real" cost types, where the values come
 * from the trace file, and "virtual" cost types, which
 * are calculated from the real ones.
 *
 * For a virtual cost type, set a formula to calculate it:
 * e.g. for "Read Misses" : "l1rm + l2rm".
 * To allow for parsing, you must specify a EventTypeSet
 * with according cost types (e.g. "l1rm" and "l2rm" for above formula).
 *
 * The cost type with empty name is the "const" cost type.
 */
class EventType
{
public:

    /**
     * @param name is a short (non-localized) identifier for the cost type,
     *   e.g. "l1rm".
     * @param longName is a long localized string, e.g. "L1 Read Miss"
     * @param formula uses short names to reference other types
     */
    explicit EventType(const QString& name,
                       const QString& longName = QString(),
                       const QString& formula = QString());

    void setName(const QString& n) { _name = n; }
    void setLongName(const QString& n) { _longName = n; }
    void setEventTypeSet(EventTypeSet* m);
    // enforces event to be derived, even with empty formula
    void setFormula(const QString&);
    // default arg is for specifying a real type, but index unknown
    void setRealIndex(int r = ProfileCostArray::MaxRealIndex);

    const QString& name() { return _name; }
    const QString& longName() { return _longName; }
    const QString& formula() { return _formula; }
    EventTypeSet* set() { return _set; }
    int realIndex() { return _realIndex; }
    bool isReal() { return _isReal; }

    /*
     * returns true if all cost type names can be resolved in formula
     */
    bool parseFormula();
    QString parsedFormula();
    QString parsedRealFormula();

    SubCost subCost(ProfileCostArray*);

    /*
     * For virtual costs, returns a histogram for use with
     * partitionPixmap().
     * Returns maximal real index.
     */
    int histCost(ProfileCostArray* c, double total, double* hist);

    // application wide known types, referenced by short name
    // next 2 functions return a new event type instance
    static EventType* cloneKnownRealType(const QString&);
    static EventType* cloneKnownDerivedType(const QString&);
    static bool hasKnownRealType(const QString&);
    static bool hasKnownDerivedType(const QString&);
    static void add(EventType*, bool overwriteExisting = true);
    static bool remove(const QString&);
    static int knownTypeCount();
    static EventType* knownType(int);

private:

    QString _name, _longName, _formula, _parsedFormula;
    EventTypeSet* _set;
    bool _parsed, _inParsing, _isReal;
    // index MaxRealIndex is for constant addition
    int _coefficient[MaxRealIndexValue];
    int _realIndex;

    static QList<EventType*>* _knownTypes;
};


/**
 * A class for managing a set of event types.
 *
 * Each event type has an index:
 * - Real events are in range [0 .. ProfileCostArray:MaxRealIndex[
 * - Derived events are in range [MaxRealIndex, ...]
 */
class EventTypeSet
{
public:
    EventTypeSet();
    ~EventTypeSet();

    /**
     * Defines a mapping from indexes into a list of costs to real event types
     * @param types the types
     */
    EventTypeMapping* createMapping(const QString& types);

    // "knows" about some real types
    int addReal(const QString&);
    int add(EventType*);
    bool remove(EventType*);
    int realCount() { return _realCount; }
    int derivedCount() { return _derivedCount; }
    int minDerivedIndex() { return ProfileCostArray::MaxRealIndex; }
    EventType* type(int);
    EventType* realType(int);
    EventType* derivedType(int);
    EventType* type(const QString&);
    EventType* typeForLong(const QString&);
    int realIndex(const QString&);
    int index(const QString&);

    /**
     * Adds all known derived event types that can be parsed
     */
    int addKnownDerivedTypes();

private:
    // we support only a fixed number of real and derived types
    EventType* _real[MaxRealIndexValue];
    EventType* _derived[MaxRealIndexValue];
    int _realCount, _derivedCount;
};

/**
 * A index list into a EventTypeSet
 *
 * This ordered list maps from indexes into real cost types
 * of a set.
 *
 * You can define a set of event types by requesting submaps by name.
 * Every new event type name will get a new real type index.
 *  EventTypeSet s;
 *  m1 = s.createMapping("Event1 Cost1 Cost2");  // returns mapping [0,1,2]
 *  m2 = s.createMapping("Event2 Cost3 Event1"); // returns mapping [3,4,0]
 * Real types of s will be:
 *  (0:Event1, 1:Cost1, 2:Cost2, 3:Event2, 4:Cost3)
 */
class EventTypeMapping
{
public:
    explicit EventTypeMapping(EventTypeSet*);

    bool append(const QString&, bool create=true);
    bool append(int);
    void clear();

    EventTypeSet* set() { return _set; }

    /**
     * Get number of used indexes
     */
    int count() { return _count; }

    /**
     * Is this mapping the identity( i.e. realIndex(i)=i ) ?
     * This often allows for optimizations.
     */
    bool isIdentity() { return _isIdentity; }
    int realIndex(int i)
    { return (i<0 || i>=_count) ? ProfileCostArray::InvalidIndex : _realIndex[i]; }

    /**
     * Get maximal real index for the first @p count mapping indexes.
     * @param count the count
     */
    int maxRealIndex(int count);

    /**
     * Allows an iteration over the sorted list of all real indexes not used in
     * this mapping, up to topIndex (use ProfileCostArray::MaxRealIndex for all).
     * Usage: for(i = firstUnused(); i < topIndex; i = nextUnused(i)) { LOOP }
     */
    int firstUnused() { return _firstUnused; }
    int nextUnused(int i) {
        if (i<0 || i>=ProfileCostArray::MaxRealIndex) return ProfileCostArray::InvalidIndex;
        return _nextUnused[i]; }

private:
    EventTypeSet* _set;
    int _count, _firstUnused;
    bool _isIdentity;
    int _realIndex[MaxRealIndexValue];
    int _nextUnused[MaxRealIndexValue];
};


#endif // EVENTTYPE_H