1
/* $Id: prfcore.h.h 29 2009-07-01 20:30:29Z bird $ */
3
* kProfiler Mark 2 - Core Header Template.
7
* Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
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
18
* The above copyright notice and this permission notice shall be
19
* included in all copies or substantial portions of the Software.
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.
33
* Mixed case name macro.
36
# define KPRF_NAME(Name) Name
40
* Upper case type name macro.
43
# define KPRF_TYPE(Prefix,Name) Prefix##Name
46
/** @type KPRF_DECL_FUNC
47
* The calling convention used.
49
#ifndef KPRF_DECL_FUNC
50
# define KPRF_DECL_FUNC(type, name) type name
54
* The bitsize of the format.
61
* The basic unsigned interger pointer type.
64
* The basic signed interger pointer type.
67
typedef KU16 KPRF_TYPE(,UPTR);
68
typedef KI16 KPRF_TYPE(,IPTR);
70
typedef KU32 KPRF_TYPE(,UPTR);
71
typedef KI32 KPRF_TYPE(,IPTR);
73
typedef KU64 KPRF_TYPE(,UPTR);
74
typedef KI64 KPRF_TYPE(,IPTR);
76
# error "KPRF_BITS has an invalid value. Supported values are 16, 32 and 64."
78
/** @type KPRF_TYPE(P,UPTR)
79
* Pointer to the basic pointer type.
81
typedef KPRF_TYPE(,UPTR) *KPRF_TYPE(P,UPTR);
87
enum KPRF_TYPE(,CONSTANTS)
89
/** Magic for the profiler header. (Unix Epoc) */
90
KPRF_TYPE(,HDR_MAGIC) = 0x19700101
95
* The profile data header.
97
typedef struct KPRF_TYPE(,HDR)
99
/** [0] The magic number for file data. (KPRF_TYPE(,HDR_MAGIC)) */
101
/** [4] KPRF_BITS. */
103
/** [8] The base address which all pointers should be relative to. */
104
KPRF_TYPE(,UPTR) uBasePtr;
113
/** [10] The size of this data set. */
115
/** [10] The allocated data set size. */
118
/** [18] The max number of functions the function table can hold. */
120
/** [1c] The current number of functions in the function table. */
122
/** [20] The offset of the function table (relative to this header). */
124
/** [24] The size of a function entry. */
127
/** [28] The max number of bytes the module segments can occupy. */
129
/** [2c] The current size of the module segment records. */
131
/** [30] The offset of the module segment records (relative to this header). */
134
/** [34] The max number of threads the thread table can contain. */
136
/** [38] The current number of threads in the thread table. */
138
/** [3c] The offset of the thread table (relative to this header). */
140
/** [40] The size of a thread entry. */
143
/** [44] The max number of stacks the stack table can contain. */
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. */
149
/** [4c] The offset of the thread table (relative to this header).
150
* This is usually 0 in a stored data set. */
152
/** [50] The size of a stack. */
154
/** [54] The maxium stack depth. */
155
KU32 cMaxStackFrames;
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.
162
/** [5c] The length of the command line. (excludes the terminator). */
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. */
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);
179
typedef struct KPRF_TYPE(,TIMESTAT) /** @todo bad names and descriptions! */
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);
197
typedef struct KPRF_TYPE(,MODSEG)
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) */
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.) */
208
/** The length of the path.
209
* This is used to calculate the length of the record: offsetof(MODSEG, szPath) + cchPath + 1 */
211
/** The module name. */
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);
221
* The profiler data for a function.
223
typedef struct KPRF_TYPE(,FUNC)
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. */
231
/** The number times on the stack. */
232
KU64 volatile cOnStack;
233
/** The number of calls made from this function. */
234
KU64 volatile cCalls;
236
/** Time on stack. */
237
KPRF_TYPE(,TIMESTAT) OnStack;
238
/** Time on top of the stack, i.e. executing. */
239
KPRF_TYPE(,TIMESTAT) OnTopOfStack;
241
/** @todo recursion */
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);
253
typedef struct KPRF_TYPE(,FRAME)
255
/** The accumulated overhead.
256
* Over head is accumulated by the parent frame when a child is poped off the stack. */
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. */
264
/** The start of the on-stack period. */
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. */
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. */
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);
290
typedef struct KPRF_TYPE(,STACK)
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. */
295
/** The number of active stack frames. */
297
/** The stack frames.
298
* The actual size of this array is specified in the header. */
299
KPRF_TYPE(,FRAME) aFrames[1];
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);
310
typedef enum KPRF_TYPE(,THREADSTATE)
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.
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.
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),
333
/** Ensure 32-bit size. */
334
KPRF_TYPE(,THREADSTATE_32BIT_HACK) = 0x7fffffff
335
} KPRF_TYPE(,THREADSTATE);
339
* Thread statistics and stack.
341
typedef struct KPRF_TYPE(,THREAD)
343
/** The native thread id. */
345
/** The thread name. (optional) */
347
/** The thread current thread state. */
348
KPRF_TYPE(,THREADSTATE) enmState;
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. */
357
/** The number of times the stack overflowed. */
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. */
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. */
367
/** The accumulated overhead of this thread. */
369
/** The accumulated sleep ticks for this thread.
370
* See KPRF_TYPE(,FRAME)::SleepTicks for details. */
373
/** The offset of the stack. */
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);