~ubuntu-branches/ubuntu/trusty/virtualbox-lts-xenial/trusty-updates

« back to all changes in this revision

Viewing changes to src/libs/kStuff/kStuff/kProfiler2/prfcore.h.h

  • Committer: Package Import Robot
  • Author(s): Gianfranco Costamagna
  • Date: 2016-02-23 14:28:26 UTC
  • Revision ID: package-import@ubuntu.com-20160223142826-bdu69el2z6wa2a44
Tags: upstream-4.3.36-dfsg
ImportĀ upstreamĀ versionĀ 4.3.36-dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: prfcore.h.h 29 2009-07-01 20:30:29Z bird $ */
 
2
/** @file
 
3
 * kProfiler Mark 2 - Core Header Template.
 
4
 */
 
5
 
 
6
/*
 
7
 * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
 
8
 *
 
9
 * Permission is hereby granted, free of charge, to any person
 
10
 * obtaining a copy of this software and associated documentation
 
11
 * files (the "Software"), to deal in the Software without
 
12
 * restriction, including without limitation the rights to use,
 
13
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 
14
 * copies of the Software, and to permit persons to whom the
 
15
 * Software is furnished to do so, subject to the following
 
16
 * conditions:
 
17
 *
 
18
 * The above copyright notice and this permission notice shall be
 
19
 * included in all copies or substantial portions of the Software.
 
20
 *
 
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
22
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 
23
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
24
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 
25
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
26
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
27
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
28
 * OTHER DEALINGS IN THE SOFTWARE.
 
29
 */
 
30
 
 
31
 
 
32
/** @def KPRF_NAME
 
33
 * Mixed case name macro.
 
34
 */
 
35
#ifndef KPRF_NAME
 
36
# define KPRF_NAME(Name)        Name
 
37
#endif
 
38
 
 
39
/** @def KPRF_TYPE
 
40
 * Upper case type name macro.
 
41
 */
 
42
#ifndef KPRF_TYPE
 
43
# define KPRF_TYPE(Prefix,Name) Prefix##Name
 
44
#endif
 
45
 
 
46
/** @type KPRF_DECL_FUNC
 
47
 * The calling convention used.
 
48
 */
 
49
#ifndef KPRF_DECL_FUNC
 
50
# define KPRF_DECL_FUNC(type, name) type name
 
51
#endif
 
52
 
 
53
/** @def KPRF_BITS
 
54
 * The bitsize of the format.
 
55
 */
 
56
#ifndef KPRF_BITS
 
57
# define KPRF_BITS  32
 
58
#endif
 
59
 
 
60
/** @type UPTR
 
61
 * The basic unsigned interger pointer type.
 
62
 */
 
63
/** @type IPTR
 
64
 * The basic signed interger pointer type.
 
65
 */
 
66
#if KPRF_BITS == 16
 
67
typedef KU16    KPRF_TYPE(,UPTR);
 
68
typedef KI16    KPRF_TYPE(,IPTR);
 
69
#elif KPRF_BITS == 32
 
70
typedef KU32    KPRF_TYPE(,UPTR);
 
71
typedef KI32    KPRF_TYPE(,IPTR);
 
72
#elif KPRF_BITS == 64
 
73
typedef KU64    KPRF_TYPE(,UPTR);
 
74
typedef KI64    KPRF_TYPE(,IPTR);
 
75
#else
 
76
# error "KPRF_BITS has an invalid value. Supported values are 16, 32 and 64."
 
77
#endif
 
78
/** @type KPRF_TYPE(P,UPTR)
 
79
 * Pointer to the basic pointer type.
 
80
 */
 
81
typedef KPRF_TYPE(,UPTR) *KPRF_TYPE(P,UPTR);
 
82
 
 
83
 
 
84
/**
 
85
 * Various constants.
 
86
 */
 
87
enum KPRF_TYPE(,CONSTANTS)
 
88
{
 
89
    /** Magic for the profiler header. (Unix Epoc) */
 
90
    KPRF_TYPE(,HDR_MAGIC) = 0x19700101
 
91
};
 
92
 
 
93
 
 
94
/**
 
95
 * The profile data header.
 
96
 */
 
97
typedef struct KPRF_TYPE(,HDR)
 
98
{
 
99
    /** [0] The magic number for file data. (KPRF_TYPE(,HDR_MAGIC)) */
 
100
    KU32                    u32Magic;
 
101
    /** [4] KPRF_BITS. */
 
102
    KU32                    cFormatBits;
 
103
    /** [8] The base address which all pointers should be relative to. */
 
104
    KPRF_TYPE(,UPTR)        uBasePtr;
 
105
#if KPRF_BITS <= 16
 
106
    /** [a] Reserved. */
 
107
    KU16                    u16Reserved;
 
108
#endif
 
109
#if KPRF_BITS <= 32
 
110
    /** [c] Reserved. */
 
111
    KU32                    u32Reserved;
 
112
#endif
 
113
    /** [10] The size of this data set. */
 
114
    KU32                    cb;
 
115
    /** [10] The allocated data set size. */
 
116
    KU32                    cbAllocated;
 
117
 
 
118
    /** [18] The max number of functions the function table can hold. */
 
119
    KU32                    cMaxFunctions;
 
120
    /** [1c] The current number of functions in the function table. */
 
121
    KU32                    cFunctions;
 
122
    /** [20] The offset of the function table (relative to this header). */
 
123
    KU32                    offFunctions;
 
124
    /** [24] The size of a function entry. */
 
125
    KU32                    cbFunction;
 
126
 
 
127
    /** [28] The max number of bytes the module segments can occupy. */
 
128
    KU32                    cbMaxModSegs;
 
129
    /** [2c] The current size of the module segment records. */
 
130
    KU32                    cbModSegs;
 
131
    /** [30] The offset of the module segment records (relative to this header). */
 
132
    KU32                    offModSegs;
 
133
 
 
134
    /** [34] The max number of threads the thread table can contain. */
 
135
    KU32                    cMaxThreads;
 
136
    /** [38] The current number of threads in the thread table. */
 
137
    KU32                    cThreads;
 
138
    /** [3c] The offset of the thread table (relative to this header). */
 
139
    KU32                    offThreads;
 
140
    /** [40] The size of a thread entry. */
 
141
    KU32                    cbThread;
 
142
 
 
143
    /** [44] The max number of stacks the stack table can contain. */
 
144
    KU32                    cMaxStacks;
 
145
    /** [48] The max number of stacks.
 
146
     * Unlike the other members, the stacks can be reused. It follows that
 
147
     * this count doesn't specify the number of used slots from the start. */
 
148
    KU32                    cStacks;
 
149
    /** [4c] The offset of the thread table (relative to this header).
 
150
     * This is usually 0 in a stored data set. */
 
151
    KU32                    offStacks;
 
152
    /** [50] The size of a stack. */
 
153
    KU32                    cbStack;
 
154
    /** [54] The maxium stack depth. */
 
155
    KU32                    cMaxStackFrames;
 
156
 
 
157
    /** [58] The process commandline.
 
158
     * Might not always apply is will be 0 in those cases. This is normally written
 
159
     * where the stacks used to be.
 
160
     */
 
161
    KU32                    offCommandLine;
 
162
    /** [5c] The length of the command line. (excludes the terminator). */
 
163
    KU32                    cchCommandLine;
 
164
 
 
165
    /** [60]  The function lookup table (it contains indexes).
 
166
     * This is sorted by address so that a binary search can be performed.
 
167
     * Access to this table is managed externally, but generally a read/write lock is employed. */
 
168
    KU32                    aiFunctions[1];
 
169
} KPRF_TYPE(,HDR);
 
170
/** Pointer to a profiler data header. */
 
171
typedef KPRF_TYPE(,HDR) *KPRF_TYPE(P,HDR);
 
172
/** Pointer to a const profiler data header. */
 
173
typedef const KPRF_TYPE(,HDR) *KPRF_TYPE(PC,HDR);
 
174
 
 
175
 
 
176
/**
 
177
 * Time statistics.
 
178
 */
 
179
typedef struct KPRF_TYPE(,TIMESTAT)      /** @todo bad names and descriptions! */
 
180
{
 
181
    /** The minimum period */
 
182
    KU64 volatile           MinTicks;
 
183
    /** The maximum period */
 
184
    KU64 volatile           MaxTicks;
 
185
    /** The sum of all periods. */
 
186
    KU64 volatile           SumTicks;
 
187
} KPRF_TYPE(,TIMESTAT);
 
188
/** Pointer to time statistics. */
 
189
typedef KPRF_TYPE(,TIMESTAT) *KPRF_TYPE(P,TIMESTAT);
 
190
/** Pointer to const time statistics. */
 
191
typedef const KPRF_TYPE(,TIMESTAT) *KPRF_TYPE(PC,TIMESTAT);
 
192
 
 
193
 
 
194
/**
 
195
 * A Module Segment.
 
196
 */
 
197
typedef struct KPRF_TYPE(,MODSEG)
 
198
{
 
199
    /** The address of the segment. (relative address) */
 
200
    KPRF_TYPE(,UPTR)        uBasePtr;
 
201
    /** The size of the segment minus one (so the entire address space can be covered). */
 
202
    KPRF_TYPE(,UPTR)        cbSegmentMinusOne;
 
203
    /** The segment number. (0 based) */
 
204
    KU32                    iSegment;
 
205
    /** Flag indicating whether this segment is loaded or not.
 
206
     * (A 16-bit value was choosen out of convenience, all that's stored is 0 or 1 anyway.) */
 
207
    KU16                    fLoaded;
 
208
    /** The length of the path.
 
209
     * This is used to calculate the length of the record: offsetof(MODSEG, szPath) + cchPath + 1 */
 
210
    KU16                    cchPath;
 
211
    /** The module name. */
 
212
    char                    szPath[1];
 
213
} KPRF_TYPE(,MODSEG);
 
214
/** Pointer to a module segment. */
 
215
typedef KPRF_TYPE(,MODSEG) *KPRF_TYPE(P,MODSEG);
 
216
/** Pointer to a const module segment. */
 
217
typedef const KPRF_TYPE(,MODSEG) *KPRF_TYPE(PC,MODSEG);
 
218
 
 
219
 
 
220
/**
 
221
 * The profiler data for a function.
 
222
 */
 
223
typedef struct KPRF_TYPE(,FUNC)
 
224
{
 
225
    /** The entry address of the function. (relative address)
 
226
     * This is the return address of the entry hook (_mcount, _penter, _ProfileHook32, ...). */
 
227
    KPRF_TYPE(,UPTR)        uEntryPtr;
 
228
    /** Offset (relative to the profiler header) of the module segment to which this function belongs. */
 
229
    KU32                    offModSeg;
 
230
 
 
231
    /** The number times on the stack. */
 
232
    KU64 volatile           cOnStack;
 
233
    /** The number of calls made from this function. */
 
234
    KU64 volatile           cCalls;
 
235
 
 
236
    /** Time on stack. */
 
237
    KPRF_TYPE(,TIMESTAT)    OnStack;
 
238
    /** Time on top of the stack, i.e. executing. */
 
239
    KPRF_TYPE(,TIMESTAT)    OnTopOfStack;
 
240
 
 
241
    /** @todo recursion */
 
242
 
 
243
} KPRF_TYPE(,FUNC);
 
244
/** Pointer to the profiler data for a function. */
 
245
typedef KPRF_TYPE(,FUNC)       *KPRF_TYPE(P,FUNC);
 
246
/** Pointer to the const profiler data for a function. */
 
247
typedef const KPRF_TYPE(,FUNC) *KPRF_TYPE(PC,FUNC);
 
248
 
 
249
 
 
250
/**
 
251
 * Stack frame.
 
252
 */
 
253
typedef struct KPRF_TYPE(,FRAME)
 
254
{
 
255
    /** The accumulated overhead.
 
256
     * Over head is accumulated by the parent frame when a child is poped off the stack. */
 
257
    KU64                    OverheadTicks;
 
258
    /** The current (top of stack) overhead. */
 
259
    KU64                    CurOverheadTicks;
 
260
    /** The accumulated sleep ticks.
 
261
     * It's possible to notify the profiler that the thread is being put into a wait/sleep/yield
 
262
     * state. The time spent sleeping is transfered to the parent frame when poping of a child one. */
 
263
    KU64                    SleepTicks;
 
264
    /** The start of the on-stack period. */
 
265
    KU64                    OnStackStart;
 
266
    /** The accumulated time on top (excludes overhead (sleep doesn't apply here obviously)). */
 
267
    KU64                    OnTopOfStackTicks;
 
268
    /** The start of the current on-top-of-stack period.
 
269
     * This is also to mark the start of a sleeping period, the ResumeThread function will always
 
270
     * treat it as the start of the suspend period. */
 
271
    KU64                    OnTopOfStackStart;
 
272
    /** The number of calls made from this stack frame. */
 
273
    KU64                    cCalls;
 
274
    /** Stack address of this frame.
 
275
     * This is used to detect throw and longjmp, and is also used to deal with overflow. (relative address) */
 
276
    KPRF_TYPE(,UPTR)        uFramePtr;
 
277
    /** Offset (relative to the profiler header) to the function record.
 
278
     * This is 0 if we're out of function space. */
 
279
    KU32                    offFunction;
 
280
} KPRF_TYPE(,FRAME);
 
281
/** Pointer to a stack frame. */
 
282
typedef KPRF_TYPE(,FRAME) *KPRF_TYPE(P,FRAME);
 
283
/** Pointer to a const stack frame. */
 
284
typedef const KPRF_TYPE(,FRAME) *KPRF_TYPE(PC,FRAME);
 
285
 
 
286
 
 
287
/**
 
288
 * Stack.
 
289
 */
 
290
typedef struct KPRF_TYPE(,STACK)
 
291
{
 
292
    /** The offset (relative to the profiler header) of the thread owning the stack.
 
293
     * This is zero if not in use, and non-zero if in use. */
 
294
    KU32                        offThread;
 
295
    /** The number of active stack frames. */
 
296
    KU32                        cFrames;
 
297
    /** The stack frames.
 
298
     * The actual size of this array is specified in the header. */
 
299
    KPRF_TYPE(,FRAME)           aFrames[1];
 
300
} KPRF_TYPE(,STACK);
 
301
/** Pointer to a stack. */
 
302
typedef KPRF_TYPE(,STACK) *KPRF_TYPE(P,STACK);
 
303
/** Pointer to a const stack. */
 
304
typedef const KPRF_TYPE(,STACK) *KPRF_TYPE(PC,STACK);
 
305
 
 
306
 
 
307
/**
 
308
 * The thread state.
 
309
 */
 
310
typedef enum KPRF_TYPE(,THREADSTATE)
 
311
{
 
312
    /** The thread hasn't been used yet. */
 
313
    KPRF_TYPE(,THREADSTATE_UNUSED) = 0,
 
314
    /** The thread is activly being profiled.
 
315
     * A thread is added in the suspended state and then activated when
 
316
     * starting to execute the first function.
 
317
     */
 
318
    KPRF_TYPE(,THREADSTATE_ACTIVE),
 
319
    /** The thread is currently suspended from profiling.
 
320
     * Upon entering profiler code the thread is suspended, it's reactivated
 
321
     * upon normal return.
 
322
     */
 
323
    KPRF_TYPE(,THREADSTATE_SUSPENDED),
 
324
    /** The thread is currently suspended due of stack overflow.
 
325
     * When we overflow the stack frame array, the thread enter the overflow state. In this
 
326
     * state nothing is profiled but we keep looking for the exit of the top frame. */
 
327
    KPRF_TYPE(,THREADSTATE_OVERFLOWED),
 
328
    /** The thread is terminated.
 
329
     * When we received a thread termination notification the thread is unwinded, statistics
 
330
     * updated and the state changed to terminated. A terminated thread cannot be revivied. */
 
331
    KPRF_TYPE(,THREADSTATE_TERMINATED),
 
332
 
 
333
    /** Ensure 32-bit size. */
 
334
    KPRF_TYPE(,THREADSTATE_32BIT_HACK) = 0x7fffffff
 
335
} KPRF_TYPE(,THREADSTATE);
 
336
 
 
337
 
 
338
/**
 
339
 * Thread statistics and stack.
 
340
 */
 
341
typedef struct KPRF_TYPE(,THREAD)
 
342
{
 
343
    /** The native thread id. */
 
344
    KU64                        ThreadId;
 
345
    /** The thread name. (optional) */
 
346
    char                        szName[32];
 
347
    /** The thread current thread state. */
 
348
    KPRF_TYPE(,THREADSTATE)     enmState;
 
349
    /** Alignment. */
 
350
    KPRF_TYPE(,THREADSTATE)     Reserved0;
 
351
    /** The base pointer of the thread stack. (relative address) */
 
352
    KPRF_TYPE(,UPTR)            uStackBasePtr;
 
353
    /** The maximum depth of the thread stack (bytes). */
 
354
    KPRF_TYPE(,UPTR)            cbMaxStack;
 
355
    /** The number of calls done by this thread. */
 
356
    KU64                        cCalls;
 
357
    /** The number of times the stack overflowed. */
 
358
    KU64                        cOverflows;
 
359
    /** The number of times stack entries has been rejected because of a stack switch. */
 
360
    KU64                        cStackSwitchRejects;
 
361
    /** The number of times the stack has been unwinded more than one frame. */
 
362
    KU64                        cUnwinds;
 
363
 
 
364
    /** The profiled ticks. (This does not include sleep or overhead ticks.)
 
365
     * This is the accumulated on-stack values for the final stack frames. */
 
366
    KU64                        ProfiledTicks;
 
367
    /** The accumulated overhead of this thread. */
 
368
    KU64                        OverheadTicks;
 
369
    /** The accumulated sleep ticks for this thread.
 
370
     * See KPRF_TYPE(,FRAME)::SleepTicks for details. */
 
371
    KU64                        SleepTicks;
 
372
 
 
373
    /** The offset of the stack. */
 
374
    KU32                        offStack;
 
375
} KPRF_TYPE(,THREAD);
 
376
/** Pointer to a thread. */
 
377
typedef KPRF_TYPE(,THREAD) *KPRF_TYPE(P,THREAD);
 
378
/** Pointer to a const thread. */
 
379
typedef const KPRF_TYPE(,THREAD) *KPRF_TYPE(PC,THREAD);
 
380
 
 
381