VirtualBox

source: kStuff/trunk/kProfiler2/prfcore.h.h@ 121

Last change on this file since 121 was 29, checked in by bird, 15 years ago

Finally got around execute the switch to the MIT license.

  • Property svn:keywords set to Id Revision
File size: 13.5 KB
Line 
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 <[email protected]>
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
67typedef KU16 KPRF_TYPE(,UPTR);
68typedef KI16 KPRF_TYPE(,IPTR);
69#elif KPRF_BITS == 32
70typedef KU32 KPRF_TYPE(,UPTR);
71typedef KI32 KPRF_TYPE(,IPTR);
72#elif KPRF_BITS == 64
73typedef KU64 KPRF_TYPE(,UPTR);
74typedef 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 */
81typedef KPRF_TYPE(,UPTR) *KPRF_TYPE(P,UPTR);
82
83
84/**
85 * Various constants.
86 */
87enum 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 */
97typedef 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. */
171typedef KPRF_TYPE(,HDR) *KPRF_TYPE(P,HDR);
172/** Pointer to a const profiler data header. */
173typedef const KPRF_TYPE(,HDR) *KPRF_TYPE(PC,HDR);
174
175
176/**
177 * Time statistics.
178 */
179typedef 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. */
189typedef KPRF_TYPE(,TIMESTAT) *KPRF_TYPE(P,TIMESTAT);
190/** Pointer to const time statistics. */
191typedef const KPRF_TYPE(,TIMESTAT) *KPRF_TYPE(PC,TIMESTAT);
192
193
194/**
195 * A Module Segment.
196 */
197typedef 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. */
215typedef KPRF_TYPE(,MODSEG) *KPRF_TYPE(P,MODSEG);
216/** Pointer to a const module segment. */
217typedef const KPRF_TYPE(,MODSEG) *KPRF_TYPE(PC,MODSEG);
218
219
220/**
221 * The profiler data for a function.
222 */
223typedef 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. */
245typedef KPRF_TYPE(,FUNC) *KPRF_TYPE(P,FUNC);
246/** Pointer to the const profiler data for a function. */
247typedef const KPRF_TYPE(,FUNC) *KPRF_TYPE(PC,FUNC);
248
249
250/**
251 * Stack frame.
252 */
253typedef 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. */
282typedef KPRF_TYPE(,FRAME) *KPRF_TYPE(P,FRAME);
283/** Pointer to a const stack frame. */
284typedef const KPRF_TYPE(,FRAME) *KPRF_TYPE(PC,FRAME);
285
286
287/**
288 * Stack.
289 */
290typedef 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. */
302typedef KPRF_TYPE(,STACK) *KPRF_TYPE(P,STACK);
303/** Pointer to a const stack. */
304typedef const KPRF_TYPE(,STACK) *KPRF_TYPE(PC,STACK);
305
306
307/**
308 * The thread state.
309 */
310typedef 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 */
341typedef 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. */
377typedef KPRF_TYPE(,THREAD) *KPRF_TYPE(P,THREAD);
378/** Pointer to a const thread. */
379typedef const KPRF_TYPE(,THREAD) *KPRF_TYPE(PC,THREAD);
380
381
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette