VirtualBox

source: vbox/trunk/include/VBox/vmm/stam.h@ 93115

Last change on this file since 93115 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 47.5 KB
Line 
1/** @file
2 * STAM - Statistics Manager.
3 */
4
5/*
6 * Copyright (C) 2006-2022 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef VBOX_INCLUDED_vmm_stam_h
27#define VBOX_INCLUDED_vmm_stam_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <VBox/types.h>
33#include <iprt/stdarg.h>
34#ifdef _MSC_VER
35# if RT_MSC_PREREQ(RT_MSC_VER_VS2005)
36# include <iprt/sanitized/intrin.h>
37# endif
38#endif
39#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
40# include <iprt/asm-arm.h>
41#endif
42
43RT_C_DECLS_BEGIN
44
45/** @defgroup grp_stam The Statistics Manager API
46 * @ingroup grp_vmm
47 * @{
48 */
49
50#if defined(VBOX_WITHOUT_RELEASE_STATISTICS) && defined(VBOX_WITH_STATISTICS)
51# error "Both VBOX_WITHOUT_RELEASE_STATISTICS and VBOX_WITH_STATISTICS are defined! Make up your mind!"
52#endif
53
54
55/** @def STAM_GET_TS
56 * Gets the CPU timestamp counter.
57 *
58 * @param u64 The 64-bit variable which the timestamp shall be saved in.
59 */
60#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
61# define STAM_GET_TS(u64) do { (u64) = ASMReadTSC(); } while (0)
62#elif defined(__GNUC__)
63# if defined(RT_ARCH_X86)
64 /* This produces optimal assembler code for x86 but does not work for AMD64 ('A' means 'either rax or rdx') */
65# define STAM_GET_TS(u64) __asm__ __volatile__ ("rdtsc\n\t" : "=A" (u64))
66# elif defined(RT_ARCH_AMD64)
67# define STAM_GET_TS(u64) \
68 do { uint64_t low; uint64_t high; \
69 __asm__ __volatile__ ("rdtsc\n\t" : "=a"(low), "=d"(high)); \
70 (u64) = ((high << 32) | low); \
71 } while (0)
72# endif
73#else
74# if RT_MSC_PREREQ(RT_MSC_VER_VS2005)
75# pragma intrinsic(__rdtsc)
76# define STAM_GET_TS(u64) \
77 do { (u64) = __rdtsc(); } while (0)
78# else
79# define STAM_GET_TS(u64) \
80 do { \
81 uint64_t u64Tmp; \
82 __asm { \
83 __asm rdtsc \
84 __asm mov dword ptr [u64Tmp], eax \
85 __asm mov dword ptr [u64Tmp + 4], edx \
86 } \
87 (u64) = u64Tmp; \
88 } while (0)
89# endif
90#endif
91
92
93/** @def STAM_REL_STATS
94 * Code for inclusion only when VBOX_WITH_STATISTICS is defined.
95 * @param code A code block enclosed in {}.
96 */
97#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
98# define STAM_REL_STATS(code) do code while(0)
99#else
100# define STAM_REL_STATS(code) do {} while(0)
101#endif
102/** @def STAM_STATS
103 * Code for inclusion only when VBOX_WITH_STATISTICS is defined.
104 * @param code A code block enclosed in {}.
105 */
106#ifdef VBOX_WITH_STATISTICS
107# define STAM_STATS(code) STAM_REL_STATS(code)
108#else
109# define STAM_STATS(code) do {} while(0)
110#endif
111
112
113/**
114 * Sample type.
115 */
116typedef enum STAMTYPE
117{
118 /** Invalid entry. */
119 STAMTYPE_INVALID = 0,
120 /** Generic counter. */
121 STAMTYPE_COUNTER,
122 /** Profiling of an function. */
123 STAMTYPE_PROFILE,
124 /** Profiling of an operation. */
125 STAMTYPE_PROFILE_ADV,
126 /** Ratio of A to B, uint32_t types. Not reset. */
127 STAMTYPE_RATIO_U32,
128 /** Ratio of A to B, uint32_t types. Reset both to 0. */
129 STAMTYPE_RATIO_U32_RESET,
130 /** Callback. */
131 STAMTYPE_CALLBACK,
132 /** Generic unsigned 8-bit value. Not reset. */
133 STAMTYPE_U8,
134 /** Generic unsigned 8-bit value. Reset to 0. */
135 STAMTYPE_U8_RESET,
136 /** Generic hexadecimal unsigned 8-bit value. Not reset. */
137 STAMTYPE_X8,
138 /** Generic hexadecimal unsigned 8-bit value. Reset to 0. */
139 STAMTYPE_X8_RESET,
140 /** Generic unsigned 16-bit value. Not reset. */
141 STAMTYPE_U16,
142 /** Generic unsigned 16-bit value. Reset to 0. */
143 STAMTYPE_U16_RESET,
144 /** Generic hexadecimal unsigned 16-bit value. Not reset. */
145 STAMTYPE_X16,
146 /** Generic hexadecimal unsigned 16-bit value. Reset to 0. */
147 STAMTYPE_X16_RESET,
148 /** Generic unsigned 32-bit value. Not reset. */
149 STAMTYPE_U32,
150 /** Generic unsigned 32-bit value. Reset to 0. */
151 STAMTYPE_U32_RESET,
152 /** Generic hexadecimal unsigned 32-bit value. Not reset. */
153 STAMTYPE_X32,
154 /** Generic hexadecimal unsigned 32-bit value. Reset to 0. */
155 STAMTYPE_X32_RESET,
156 /** Generic unsigned 64-bit value. Not reset. */
157 STAMTYPE_U64,
158 /** Generic unsigned 64-bit value. Reset to 0. */
159 STAMTYPE_U64_RESET,
160 /** Generic hexadecimal unsigned 64-bit value. Not reset. */
161 STAMTYPE_X64,
162 /** Generic hexadecimal unsigned 64-bit value. Reset to 0. */
163 STAMTYPE_X64_RESET,
164 /** Generic boolean value. Not reset. */
165 STAMTYPE_BOOL,
166 /** Generic boolean value. Reset to false. */
167 STAMTYPE_BOOL_RESET,
168 /** The end (exclusive). */
169 STAMTYPE_END
170} STAMTYPE;
171
172/**
173 * Sample visibility type.
174 */
175typedef enum STAMVISIBILITY
176{
177 /** Invalid entry. */
178 STAMVISIBILITY_INVALID = 0,
179 /** Always visible. */
180 STAMVISIBILITY_ALWAYS,
181 /** Only visible when used (/hit). */
182 STAMVISIBILITY_USED,
183 /** Not visible in the GUI. */
184 STAMVISIBILITY_NOT_GUI,
185 /** The end (exclusive). */
186 STAMVISIBILITY_END
187} STAMVISIBILITY;
188
189/**
190 * Sample unit.
191 */
192typedef enum STAMUNIT
193{
194 /** Invalid entry .*/
195 STAMUNIT_INVALID = 0,
196 /** No unit. */
197 STAMUNIT_NONE,
198 /** Number of calls. */
199 STAMUNIT_CALLS,
200 /** Count of whatever. */
201 STAMUNIT_COUNT,
202 /** Count of bytes. */
203 STAMUNIT_BYTES,
204 /** Count of bytes per call. */
205 STAMUNIT_BYTES_PER_CALL,
206 /** Count of bytes. */
207 STAMUNIT_PAGES,
208 /** Error count. */
209 STAMUNIT_ERRORS,
210 /** Number of occurences. */
211 STAMUNIT_OCCURENCES,
212 /** Ticks. */
213 STAMUNIT_TICKS,
214 /** Ticks per call. */
215 STAMUNIT_TICKS_PER_CALL,
216 /** Ticks per occurence. */
217 STAMUNIT_TICKS_PER_OCCURENCE,
218 /** Ratio of good vs. bad. */
219 STAMUNIT_GOOD_BAD,
220 /** Megabytes. */
221 STAMUNIT_MEGABYTES,
222 /** Kilobytes. */
223 STAMUNIT_KILOBYTES,
224 /** Nano seconds. */
225 STAMUNIT_NS,
226 /** Nanoseconds per call. */
227 STAMUNIT_NS_PER_CALL,
228 /** Nanoseconds per call. */
229 STAMUNIT_NS_PER_OCCURENCE,
230 /** Percentage. */
231 STAMUNIT_PCT,
232 /** Hertz. */
233 STAMUNIT_HZ,
234 /** The end (exclusive). */
235 STAMUNIT_END
236} STAMUNIT;
237
238/** @name STAM_REFRESH_GRP_XXX - STAM refresh groups
239 * @{ */
240#define STAM_REFRESH_GRP_NONE UINT8_MAX
241#define STAM_REFRESH_GRP_GVMM 0
242#define STAM_REFRESH_GRP_GMM 1
243#define STAM_REFRESH_GRP_NEM 2
244/** @} */
245
246
247/** @def STAM_REL_U8_INC
248 * Increments a uint8_t sample by one.
249 *
250 * @param pCounter Pointer to the uint8_t variable to operate on.
251 */
252#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
253# define STAM_REL_U8_INC(pCounter) \
254 do { ++*(pCounter); } while (0)
255#else
256# define STAM_REL_U8_INC(pCounter) do { } while (0)
257#endif
258/** @def STAM_U8_INC
259 * Increments a uint8_t sample by one.
260 *
261 * @param pCounter Pointer to the uint8_t variable to operate on.
262 */
263#ifdef VBOX_WITH_STATISTICS
264# define STAM_U8_INC(pCounter) STAM_REL_U8_INC(pCounter)
265#else
266# define STAM_U8_INC(pCounter) do { } while (0)
267#endif
268
269
270/** @def STAM_REL_U8_DEC
271 * Decrements a uint8_t sample by one.
272 *
273 * @param pCounter Pointer to the uint8_t variable to operate on.
274 */
275#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
276# define STAM_REL_U8_DEC(pCounter) \
277 do { --*(pCounter); } while (0)
278#else
279# define STAM_REL_U8_DEC(pCounter) do { } while (0)
280#endif
281/** @def STAM_U8_DEC
282 * Decrements a uint8_t sample by one.
283 *
284 * @param pCounter Pointer to the uint8_t variable to operate on.
285 */
286#ifdef VBOX_WITH_STATISTICS
287# define STAM_U8_DEC(pCounter) STAM_REL_U8_DEC(pCounter)
288#else
289# define STAM_U8_DEC(pCounter) do { } while (0)
290#endif
291
292
293/** @def STAM_REL_U8_ADD
294 * Increments a uint8_t sample by a value.
295 *
296 * @param pCounter Pointer to the uint8_t variable to operate on.
297 * @param Addend The value to add.
298 */
299#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
300# define STAM_REL_U8_ADD(pCounter, Addend) \
301 do { *(pCounter) += (Addend); } while (0)
302#else
303# define STAM_REL_U8_ADD(pCounter, Addend) do { } while (0)
304#endif
305/** @def STAM_U8_ADD
306 * Increments a uint8_t sample by a value.
307 *
308 * @param pCounter Pointer to the uint8_t variable to operate on.
309 * @param Addend The value to add.
310 */
311#ifdef VBOX_WITH_STATISTICS
312# define STAM_U8_ADD(pCounter, Addend) STAM_REL_U8_ADD(pCounter, Addend
313#else
314# define STAM_U8_ADD(pCounter, Addend) do { } while (0)
315#endif
316
317
318/** @def STAM_REL_U16_INC
319 * Increments a uint16_t sample by one.
320 *
321 * @param pCounter Pointer to the uint16_t variable to operate on.
322 */
323#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
324# define STAM_REL_U16_INC(pCounter) \
325 do { ++*(pCounter); } while (0)
326#else
327# define STAM_REL_U16_INC(pCounter) do { } while (0)
328#endif
329/** @def STAM_U16_INC
330 * Increments a uint16_t sample by one.
331 *
332 * @param pCounter Pointer to the uint16_t variable to operate on.
333 */
334#ifdef VBOX_WITH_STATISTICS
335# define STAM_U16_INC(pCounter) STAM_REL_U16_INC(pCounter)
336#else
337# define STAM_U16_INC(pCounter) do { } while (0)
338#endif
339
340
341/** @def STAM_REL_U16_DEC
342 * Decrements a uint16_t sample by one.
343 *
344 * @param pCounter Pointer to the uint16_t variable to operate on.
345 */
346#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
347# define STAM_REL_U16_DEC(pCounter) \
348 do { --*(pCounter); } while (0)
349#else
350# define STAM_REL_U16_DEC(pCounter) do { } while (0)
351#endif
352/** @def STAM_U16_DEC
353 * Decrements a uint16_t sample by one.
354 *
355 * @param pCounter Pointer to the uint16_t variable to operate on.
356 */
357#ifdef VBOX_WITH_STATISTICS
358# define STAM_U16_DEC(pCounter) STAM_REL_U16_DEC(pCounter)
359#else
360# define STAM_U16_DEC(pCounter) do { } while (0)
361#endif
362
363
364/** @def STAM_REL_U16_ADD
365 * Increments a uint16_t sample by a value.
366 *
367 * @param pCounter Pointer to the uint16_t variable to operate on.
368 * @param Addend The value to add.
369 */
370#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
371# define STAM_REL_U16_ADD(pCounter, Addend) \
372 do { *(pCounter) += (Addend); } while (0)
373#else
374# define STAM_REL_U16_ADD(pCounter, Addend) do { } while (0)
375#endif
376/** @def STAM_U16_ADD
377 * Increments a uint16_t sample by a value.
378 *
379 * @param pCounter Pointer to the uint16_t variable to operate on.
380 * @param Addend The value to add.
381 */
382#ifdef VBOX_WITH_STATISTICS
383# define STAM_U16_ADD(pCounter, Addend) STAM_REL_U16_ADD(pCounter, Addend)
384#else
385# define STAM_U16_ADD(pCounter, Addend) do { } while (0)
386#endif
387
388
389/** @def STAM_REL_U32_INC
390 * Increments a uint32_t sample by one.
391 *
392 * @param pCounter Pointer to the uint32_t variable to operate on.
393 */
394#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
395# define STAM_REL_U32_INC(pCounter) \
396 do { ++*(pCounter); } while (0)
397#else
398# define STAM_REL_U32_INC(pCounter) do { } while (0)
399#endif
400/** @def STAM_U32_INC
401 * Increments a uint32_t sample by one.
402 *
403 * @param pCounter Pointer to the uint32_t variable to operate on.
404 */
405#ifdef VBOX_WITH_STATISTICS
406# define STAM_U32_INC(pCounter) STAM_REL_U32_INC(pCounter)
407#else
408# define STAM_U32_INC(pCounter) do { } while (0)
409#endif
410
411
412/** @def STAM_REL_U32_DEC
413 * Decrements a uint32_t sample by one.
414 *
415 * @param pCounter Pointer to the uint32_t variable to operate on.
416 */
417#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
418# define STAM_REL_U32_DEC(pCounter) \
419 do { --*(pCounter); } while (0)
420#else
421# define STAM_REL_U32_DEC(pCounter) do { } while (0)
422#endif
423/** @def STAM_U32_DEC
424 * Decrements a uint32_t sample by one.
425 *
426 * @param pCounter Pointer to the uint32_t variable to operate on.
427 */
428#ifdef VBOX_WITH_STATISTICS
429# define STAM_U32_DEC(pCounter) STAM_REL_U32_DEC(pCounter)
430#else
431# define STAM_U32_DEC(pCounter) do { } while (0)
432#endif
433
434
435/** @def STAM_REL_U32_ADD
436 * Increments a uint32_t sample by value.
437 *
438 * @param pCounter Pointer to the uint32_t variable to operate on.
439 * @param Addend The value to add.
440 */
441#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
442# define STAM_REL_U32_ADD(pCounter, Addend) \
443 do { *(pCounter) += (Addend); } while (0)
444#else
445# define STAM_REL_U32_ADD(pCounter, Addend) do { } while (0)
446#endif
447/** @def STAM_U32_ADD
448 * Increments a uint32_t sample by value.
449 *
450 * @param pCounter Pointer to the uint32_t variable to operate on.
451 * @param Addend The value to add.
452 */
453#ifdef VBOX_WITH_STATISTICS
454# define STAM_U32_ADD(pCounter, Addend) STAM_REL_U32_ADD(pCounter, Addend)
455#else
456# define STAM_U32_ADD(pCounter, Addend) do { } while (0)
457#endif
458
459
460/** @def STAM_REL_U64_INC
461 * Increments a uint64_t sample by one.
462 *
463 * @param pCounter Pointer to the uint64_t variable to operate on.
464 */
465#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
466# define STAM_REL_U64_INC(pCounter) \
467 do { ++*(pCounter); } while (0)
468#else
469# define STAM_REL_U64_INC(pCounter) do { } while (0)
470#endif
471/** @def STAM_U64_INC
472 * Increments a uint64_t sample by one.
473 *
474 * @param pCounter Pointer to the uint64_t variable to operate on.
475 */
476#ifdef VBOX_WITH_STATISTICS
477# define STAM_U64_INC(pCounter) STAM_REL_U64_INC(pCounter)
478#else
479# define STAM_U64_INC(pCounter) do { } while (0)
480#endif
481
482
483/** @def STAM_REL_U64_DEC
484 * Decrements a uint64_t sample by one.
485 *
486 * @param pCounter Pointer to the uint64_t variable to operate on.
487 */
488#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
489# define STAM_REL_U64_DEC(pCounter) \
490 do { --*(pCounter); } while (0)
491#else
492# define STAM_REL_U64_DEC(pCounter) do { } while (0)
493#endif
494/** @def STAM_U64_DEC
495 * Decrements a uint64_t sample by one.
496 *
497 * @param pCounter Pointer to the uint64_t variable to operate on.
498 */
499#ifdef VBOX_WITH_STATISTICS
500# define STAM_U64_DEC(pCounter) STAM_REL_U64_DEC(pCounter)
501#else
502# define STAM_U64_DEC(pCounter) do { } while (0)
503#endif
504
505
506/** @def STAM_REL_U64_ADD
507 * Increments a uint64_t sample by a value.
508 *
509 * @param pCounter Pointer to the uint64_t variable to operate on.
510 * @param Addend The value to add.
511 */
512#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
513# define STAM_REL_U64_ADD(pCounter, Addend) \
514 do { *(pCounter) += (Addend); } while (0)
515#else
516# define STAM_REL_U64_ADD(pCounter, Addend) do { } while (0)
517#endif
518/** @def STAM_U64_ADD
519 * Increments a uint64_t sample by a value.
520 *
521 * @param pCounter Pointer to the uint64_t variable to operate on.
522 * @param Addend The value to add.
523 */
524#ifdef VBOX_WITH_STATISTICS
525# define STAM_U64_ADD(pCounter, Addend) STAM_REL_U64_ADD(pCounter, Addend)
526#else
527# define STAM_U64_ADD(pCounter, Addend) do { } while (0)
528#endif
529
530
531/**
532 * Counter sample - STAMTYPE_COUNTER.
533 */
534typedef struct STAMCOUNTER
535{
536 /** The current count. */
537 volatile uint64_t c;
538} STAMCOUNTER;
539/** Pointer to a counter. */
540typedef STAMCOUNTER *PSTAMCOUNTER;
541/** Pointer to a const counter. */
542typedef const STAMCOUNTER *PCSTAMCOUNTER;
543
544
545/** @def STAM_REL_COUNTER_INC
546 * Increments a counter sample by one.
547 *
548 * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
549 */
550#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
551# define STAM_REL_COUNTER_INC(pCounter) \
552 do { (pCounter)->c++; } while (0)
553#else
554# define STAM_REL_COUNTER_INC(pCounter) do { } while (0)
555#endif
556/** @def STAM_COUNTER_INC
557 * Increments a counter sample by one.
558 *
559 * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
560 */
561#ifdef VBOX_WITH_STATISTICS
562# define STAM_COUNTER_INC(pCounter) STAM_REL_COUNTER_INC(pCounter)
563#else
564# define STAM_COUNTER_INC(pCounter) do { } while (0)
565#endif
566
567
568/** @def STAM_REL_COUNTER_DEC
569 * Decrements a counter sample by one.
570 *
571 * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
572 */
573#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
574# define STAM_REL_COUNTER_DEC(pCounter) \
575 do { (pCounter)->c--; } while (0)
576#else
577# define STAM_REL_COUNTER_DEC(pCounter) do { } while (0)
578#endif
579/** @def STAM_COUNTER_DEC
580 * Decrements a counter sample by one.
581 *
582 * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
583 */
584#ifdef VBOX_WITH_STATISTICS
585# define STAM_COUNTER_DEC(pCounter) STAM_REL_COUNTER_DEC(pCounter)
586#else
587# define STAM_COUNTER_DEC(pCounter) do { } while (0)
588#endif
589
590
591/** @def STAM_REL_COUNTER_ADD
592 * Increments a counter sample by a value.
593 *
594 * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
595 * @param Addend The value to add to the counter.
596 */
597#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
598# define STAM_REL_COUNTER_ADD(pCounter, Addend) \
599 do { (pCounter)->c += (Addend); } while (0)
600#else
601# define STAM_REL_COUNTER_ADD(pCounter, Addend) do { } while (0)
602#endif
603/** @def STAM_COUNTER_ADD
604 * Increments a counter sample by a value.
605 *
606 * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
607 * @param Addend The value to add to the counter.
608 */
609#ifdef VBOX_WITH_STATISTICS
610# define STAM_COUNTER_ADD(pCounter, Addend) STAM_REL_COUNTER_ADD(pCounter, Addend)
611#else
612# define STAM_COUNTER_ADD(pCounter, Addend) do { } while (0)
613#endif
614
615
616/** @def STAM_REL_COUNTER_RESET
617 * Resets the statistics sample.
618 */
619#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
620# define STAM_REL_COUNTER_RESET(pCounter) do { (pCounter)->c = 0; } while (0)
621#else
622# define STAM_REL_COUNTER_RESET(pCounter) do { } while (0)
623#endif
624/** @def STAM_COUNTER_RESET
625 * Resets the statistics sample.
626 */
627#ifdef VBOX_WITH_STATISTICS
628# define STAM_COUNTER_RESET(pCounter) STAM_REL_COUNTER_RESET(pCounter)
629#else
630# define STAM_COUNTER_RESET(pCounter) do { } while (0)
631#endif
632
633
634
635/**
636 * Profiling sample - STAMTYPE_PROFILE.
637 */
638typedef struct STAMPROFILE
639{
640 /** Number of periods. */
641 volatile uint64_t cPeriods;
642 /** Total count of ticks. */
643 volatile uint64_t cTicks;
644 /** Maximum tick count during a sampling. */
645 volatile uint64_t cTicksMax;
646 /** Minimum tick count during a sampling. */
647 volatile uint64_t cTicksMin;
648} STAMPROFILE;
649/** Pointer to a profile sample. */
650typedef STAMPROFILE *PSTAMPROFILE;
651/** Pointer to a const profile sample. */
652typedef const STAMPROFILE *PCSTAMPROFILE;
653
654
655/** @def STAM_REL_PROFILE_ADD_PERIOD
656 * Adds a period.
657 *
658 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
659 * @param cTicksInPeriod The number of tick (or whatever) of the preiod
660 * being added. This is only referenced once.
661 */
662#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
663# define STAM_REL_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) \
664 do { \
665 uint64_t const StamPrefix_cTicks = (cTicksInPeriod); \
666 (pProfile)->cTicks += StamPrefix_cTicks; \
667 (pProfile)->cPeriods++; \
668 if ((pProfile)->cTicksMax < StamPrefix_cTicks) \
669 (pProfile)->cTicksMax = StamPrefix_cTicks; \
670 if ((pProfile)->cTicksMin > StamPrefix_cTicks) \
671 (pProfile)->cTicksMin = StamPrefix_cTicks; \
672 } while (0)
673#else
674# define STAM_REL_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) do { } while (0)
675#endif
676/** @def STAM_PROFILE_ADD_PERIOD
677 * Adds a period.
678 *
679 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
680 * @param cTicksInPeriod The number of tick (or whatever) of the preiod
681 * being added. This is only referenced once.
682 */
683#ifdef VBOX_WITH_STATISTICS
684# define STAM_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) STAM_REL_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod)
685#else
686# define STAM_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) do { } while (0)
687#endif
688
689
690/** @def STAM_REL_PROFILE_START
691 * Samples the start time of a profiling period.
692 *
693 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
694 * @param Prefix Identifier prefix used to internal variables.
695 *
696 * @remarks Declears a stack variable that will be used by related macros.
697 */
698#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
699# define STAM_REL_PROFILE_START(pProfile, Prefix) \
700 uint64_t Prefix##_tsStart; \
701 STAM_GET_TS(Prefix##_tsStart)
702#else
703# define STAM_REL_PROFILE_START(pProfile, Prefix) do { } while (0)
704#endif
705/** @def STAM_PROFILE_START
706 * Samples the start time of a profiling period.
707 *
708 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
709 * @param Prefix Identifier prefix used to internal variables.
710 *
711 * @remarks Declears a stack variable that will be used by related macros.
712 */
713#ifdef VBOX_WITH_STATISTICS
714# define STAM_PROFILE_START(pProfile, Prefix) STAM_REL_PROFILE_START(pProfile, Prefix)
715#else
716# define STAM_PROFILE_START(pProfile, Prefix) do { } while (0)
717#endif
718
719/** @def STAM_REL_PROFILE_STOP
720 * Samples the stop time of a profiling period and updates the sample.
721 *
722 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
723 * @param Prefix Identifier prefix used to internal variables.
724 */
725#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
726# define STAM_REL_PROFILE_STOP(pProfile, Prefix) \
727 do { \
728 uint64_t Prefix##_cTicks; \
729 STAM_GET_TS(Prefix##_cTicks); \
730 Prefix##_cTicks -= Prefix##_tsStart; \
731 (pProfile)->cTicks += Prefix##_cTicks; \
732 (pProfile)->cPeriods++; \
733 if ((pProfile)->cTicksMax < Prefix##_cTicks) \
734 (pProfile)->cTicksMax = Prefix##_cTicks; \
735 if ((pProfile)->cTicksMin > Prefix##_cTicks) \
736 (pProfile)->cTicksMin = Prefix##_cTicks; \
737 } while (0)
738#else
739# define STAM_REL_PROFILE_STOP(pProfile, Prefix) do { } while (0)
740#endif
741/** @def STAM_PROFILE_STOP
742 * Samples the stop time of a profiling period and updates the sample.
743 *
744 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
745 * @param Prefix Identifier prefix used to internal variables.
746 */
747#ifdef VBOX_WITH_STATISTICS
748# define STAM_PROFILE_STOP(pProfile, Prefix) STAM_REL_PROFILE_STOP(pProfile, Prefix)
749#else
750# define STAM_PROFILE_STOP(pProfile, Prefix) do { } while (0)
751#endif
752
753
754/** @def STAM_REL_PROFILE_STOP_EX
755 * Samples the stop time of a profiling period and updates both the sample
756 * and an attribution sample.
757 *
758 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
759 * @param pProfile2 Pointer to the STAMPROFILE structure which this
760 * interval should be attributed to as well. This may be NULL.
761 * @param Prefix Identifier prefix used to internal variables.
762 */
763#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
764# define STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) \
765 do { \
766 uint64_t Prefix##_cTicks; \
767 STAM_GET_TS(Prefix##_cTicks); \
768 Prefix##_cTicks -= Prefix##_tsStart; \
769 (pProfile)->cTicks += Prefix##_cTicks; \
770 (pProfile)->cPeriods++; \
771 if ((pProfile)->cTicksMax < Prefix##_cTicks) \
772 (pProfile)->cTicksMax = Prefix##_cTicks; \
773 if ((pProfile)->cTicksMin > Prefix##_cTicks) \
774 (pProfile)->cTicksMin = Prefix##_cTicks; \
775 \
776 if ((pProfile2)) \
777 { \
778 (pProfile2)->cTicks += Prefix##_cTicks; \
779 (pProfile2)->cPeriods++; \
780 if ((pProfile2)->cTicksMax < Prefix##_cTicks) \
781 (pProfile2)->cTicksMax = Prefix##_cTicks; \
782 if ((pProfile2)->cTicksMin > Prefix##_cTicks) \
783 (pProfile2)->cTicksMin = Prefix##_cTicks; \
784 } \
785 } while (0)
786#else
787# define STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) do { } while (0)
788#endif
789/** @def STAM_PROFILE_STOP_EX
790 * Samples the stop time of a profiling period and updates both the sample
791 * and an attribution sample.
792 *
793 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
794 * @param pProfile2 Pointer to the STAMPROFILE structure which this
795 * interval should be attributed to as well. This may be NULL.
796 * @param Prefix Identifier prefix used to internal variables.
797 */
798#ifdef VBOX_WITH_STATISTICS
799# define STAM_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix)
800#else
801# define STAM_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) do { } while (0)
802#endif
803
804
805/** @def STAM_REL_PROFILE_STOP_START
806 * Stops one profile counter (if running) and starts another one.
807 *
808 * @param pProfile1 Pointer to the STAMPROFILE structure to stop.
809 * @param pProfile2 Pointer to the STAMPROFILE structure to start.
810 * @param Prefix Identifier prefix used to internal variables.
811 */
812#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
813# define STAM_REL_PROFILE_STOP_START(pProfile1, pProfile2, Prefix) \
814 do { \
815 uint64_t Prefix##_tsStop; \
816 STAM_GET_TS(Prefix##_tsStop); \
817 STAM_REL_PROFILE_ADD_PERIOD(pProfile1, Prefix##_tsStop - Prefix##_tsStart); \
818 Prefix##_tsStart = Prefix##_tsStop; \
819 } while (0)
820#else
821# define STAM_REL_PROFILE_STOP_START(pProfile1, pProfile2, Prefix) \
822 do { } while (0)
823#endif
824/** @def STAM_PROFILE_STOP_START
825 * Samples the stop time of a profiling period (if running) and updates the
826 * sample.
827 *
828 * @param pProfile1 Pointer to the STAMPROFILE structure to stop.
829 * @param pProfile2 Pointer to the STAMPROFILE structure to start.
830 * @param Prefix Identifier prefix used to internal variables.
831 */
832#ifdef VBOX_WITH_STATISTICS
833# define STAM_PROFILE_STOP_START(pProfile1, pProfile2, Prefix) \
834 STAM_REL_PROFILE_STOP_START(pProfile1, pProfile2, Prefix)
835#else
836# define STAM_PROFILE_STOP_START(pProfile1, pProfile2, Prefix) \
837 do { } while (0)
838#endif
839
840
841/** @def STAM_REL_PROFILE_START_NS
842 * Samples the start time of a profiling period, using RTTimeNanoTS().
843 *
844 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
845 * @param Prefix Identifier prefix used to internal variables.
846 *
847 * @remarks Declears a stack variable that will be used by related macros.
848 */
849#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
850# define STAM_REL_PROFILE_START_NS(pProfile, Prefix) \
851 uint64_t const Prefix##_tsStart = RTTimeNanoTS()
852#else
853# define STAM_REL_PROFILE_START_NS(pProfile, Prefix) do { } while (0)
854#endif
855/** @def STAM_PROFILE_START_NS
856 * Samples the start time of a profiling period, using RTTimeNanoTS().
857 *
858 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
859 * @param Prefix Identifier prefix used to internal variables.
860 *
861 * @remarks Declears a stack variable that will be used by related macros.
862 */
863#ifdef VBOX_WITH_STATISTICS
864# define STAM_PROFILE_START_NS(pProfile, Prefix) STAM_REL_PROFILE_START_NS(pProfile, Prefix)
865#else
866# define STAM_PROFILE_START_NS(pProfile, Prefix) do { } while (0)
867#endif
868
869/** @def STAM_REL_PROFILE_STOP_NS
870 * Samples the stop time of a profiling period and updates the sample, using
871 * RTTimeNanoTS().
872 *
873 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
874 * @param Prefix Identifier prefix used to internal variables.
875 */
876#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
877# define STAM_REL_PROFILE_STOP_NS(pProfile, Prefix) \
878 STAM_REL_PROFILE_ADD_PERIOD(pProfile, RTTimeNanoTS() - Prefix##_tsStart)
879#else
880# define STAM_REL_PROFILE_STOP_NS(pProfile, Prefix) do { } while (0)
881#endif
882/** @def STAM_PROFILE_STOP_NS
883 * Samples the stop time of a profiling period and updates the sample, using
884 * RTTimeNanoTS().
885 *
886 * @param pProfile Pointer to the STAMPROFILE structure to operate on.
887 * @param Prefix Identifier prefix used to internal variables.
888 */
889#ifdef VBOX_WITH_STATISTICS
890# define STAM_PROFILE_STOP_NS(pProfile, Prefix) STAM_REL_PROFILE_STOP_NS(pProfile, Prefix)
891#else
892# define STAM_PROFILE_STOP_NS(pProfile, Prefix) do { } while (0)
893#endif
894
895
896/**
897 * Advanced profiling sample - STAMTYPE_PROFILE_ADV.
898 *
899 * Identical to a STAMPROFILE sample, but the start timestamp
900 * is stored after the STAMPROFILE structure so the sampling
901 * can start and stop in different functions.
902 */
903typedef struct STAMPROFILEADV
904{
905 /** The STAMPROFILE core. */
906 STAMPROFILE Core;
907 /** The start timestamp. */
908 volatile uint64_t tsStart;
909} STAMPROFILEADV;
910/** Pointer to a advanced profile sample. */
911typedef STAMPROFILEADV *PSTAMPROFILEADV;
912/** Pointer to a const advanced profile sample. */
913typedef const STAMPROFILEADV *PCSTAMPROFILEADV;
914
915
916/** @def STAM_REL_PROFILE_ADV_START
917 * Samples the start time of a profiling period.
918 *
919 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
920 * @param Prefix Identifier prefix used to internal variables.
921 */
922#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
923# define STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix) \
924 STAM_GET_TS((pProfileAdv)->tsStart)
925#else
926# define STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix) do { } while (0)
927#endif
928/** @def STAM_PROFILE_ADV_START
929 * Samples the start time of a profiling period.
930 *
931 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
932 * @param Prefix Identifier prefix used to internal variables.
933 */
934#ifdef VBOX_WITH_STATISTICS
935# define STAM_PROFILE_ADV_START(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix)
936#else
937# define STAM_PROFILE_ADV_START(pProfileAdv, Prefix) do { } while (0)
938#endif
939
940
941/** @def STAM_REL_PROFILE_ADV_STOP
942 * Samples the stop time of a profiling period (if running) and updates the
943 * sample.
944 *
945 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
946 * @param Prefix Identifier prefix used to internal variables.
947 */
948#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
949# define STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix) \
950 do { \
951 if ((pProfileAdv)->tsStart) \
952 { \
953 uint64_t Prefix##_cTicks; \
954 STAM_GET_TS(Prefix##_cTicks); \
955 Prefix##_cTicks -= (pProfileAdv)->tsStart; \
956 (pProfileAdv)->tsStart = 0; \
957 (pProfileAdv)->Core.cTicks += Prefix##_cTicks; \
958 (pProfileAdv)->Core.cPeriods++; \
959 if ((pProfileAdv)->Core.cTicksMax < Prefix##_cTicks) \
960 (pProfileAdv)->Core.cTicksMax = Prefix##_cTicks; \
961 if ((pProfileAdv)->Core.cTicksMin > Prefix##_cTicks) \
962 (pProfileAdv)->Core.cTicksMin = Prefix##_cTicks; \
963 } \
964 } while (0)
965#else
966# define STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix) do { } while (0)
967#endif
968/** @def STAM_PROFILE_ADV_STOP
969 * Samples the stop time of a profiling period (if running) and updates the
970 * sample.
971 *
972 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
973 * @param Prefix Identifier prefix used to internal variables.
974 */
975#ifdef VBOX_WITH_STATISTICS
976# define STAM_PROFILE_ADV_STOP(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix)
977#else
978# define STAM_PROFILE_ADV_STOP(pProfileAdv, Prefix) do { } while (0)
979#endif
980
981
982/** @def STAM_REL_PROFILE_ADV_STOP_START
983 * Stops one profile counter (if running) and starts another one.
984 *
985 * @param pProfileAdv1 Pointer to the STAMPROFILEADV structure to stop.
986 * @param pProfileAdv2 Pointer to the STAMPROFILEADV structure to start.
987 * @param Prefix Identifier prefix used to internal variables.
988 */
989#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
990# define STAM_REL_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \
991 do { \
992 uint64_t Prefix##_cTicks; \
993 STAM_GET_TS(Prefix##_cTicks); \
994 (pProfileAdv2)->tsStart = Prefix##_cTicks; \
995 if ((pProfileAdv1)->tsStart) \
996 { \
997 Prefix##_cTicks -= (pProfileAdv1)->tsStart; \
998 (pProfileAdv1)->tsStart = 0; \
999 (pProfileAdv1)->Core.cTicks += Prefix##_cTicks; \
1000 (pProfileAdv1)->Core.cPeriods++; \
1001 if ((pProfileAdv1)->Core.cTicksMax < Prefix##_cTicks) \
1002 (pProfileAdv1)->Core.cTicksMax = Prefix##_cTicks; \
1003 if ((pProfileAdv1)->Core.cTicksMin > Prefix##_cTicks) \
1004 (pProfileAdv1)->Core.cTicksMin = Prefix##_cTicks; \
1005 } \
1006 } while (0)
1007#else
1008# define STAM_REL_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \
1009 do { } while (0)
1010#endif
1011/** @def STAM_PROFILE_ADV_STOP_START
1012 * Samples the stop time of a profiling period (if running) and updates the
1013 * sample.
1014 *
1015 * @param pProfileAdv1 Pointer to the STAMPROFILEADV structure to stop.
1016 * @param pProfileAdv2 Pointer to the STAMPROFILEADV structure to start.
1017 * @param Prefix Identifier prefix used to internal variables.
1018 */
1019#ifdef VBOX_WITH_STATISTICS
1020# define STAM_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \
1021 STAM_REL_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix)
1022#else
1023# define STAM_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \
1024 do { } while (0)
1025#endif
1026
1027
1028/** @def STAM_REL_PROFILE_ADV_SUSPEND
1029 * Suspends the sampling for a while. This can be useful to exclude parts
1030 * covered by other samples without screwing up the count, and average+min times.
1031 *
1032 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1033 * @param Prefix Identifier prefix used to internal variables. The prefix
1034 * must match that of the resume one since it stores the
1035 * suspend time in a stack variable.
1036 */
1037#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
1038# define STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) \
1039 uint64_t Prefix##_tsSuspend; \
1040 STAM_GET_TS(Prefix##_tsSuspend)
1041#else
1042# define STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) do { } while (0)
1043#endif
1044/** @def STAM_PROFILE_ADV_SUSPEND
1045 * Suspends the sampling for a while. This can be useful to exclude parts
1046 * covered by other samples without screwing up the count, and average+min times.
1047 *
1048 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1049 * @param Prefix Identifier prefix used to internal variables. The prefix
1050 * must match that of the resume one since it stores the
1051 * suspend time in a stack variable.
1052 */
1053#ifdef VBOX_WITH_STATISTICS
1054# define STAM_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix)
1055#else
1056# define STAM_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) do { } while (0)
1057#endif
1058
1059
1060/** @def STAM_REL_PROFILE_ADV_RESUME
1061 * Counter to STAM_REL_PROFILE_ADV_SUSPEND.
1062 *
1063 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1064 * @param Prefix Identifier prefix used to internal variables. This must
1065 * match the one used with the SUSPEND!
1066 */
1067#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
1068# define STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix) \
1069 do { \
1070 uint64_t Prefix##_tsNow; \
1071 STAM_GET_TS(Prefix##_tsNow); \
1072 (pProfileAdv)->tsStart += Prefix##_tsNow - Prefix##_tsSuspend; \
1073 } while (0)
1074#else
1075# define STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix) do { } while (0)
1076#endif
1077/** @def STAM_PROFILE_ADV_RESUME
1078 * Counter to STAM_PROFILE_ADV_SUSPEND.
1079 *
1080 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1081 * @param Prefix Identifier prefix used to internal variables. This must
1082 * match the one used with the SUSPEND!
1083 */
1084#ifdef VBOX_WITH_STATISTICS
1085# define STAM_PROFILE_ADV_RESUME(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix)
1086#else
1087# define STAM_PROFILE_ADV_RESUME(pProfileAdv, Prefix) do { } while (0)
1088#endif
1089
1090
1091/** @def STAM_REL_PROFILE_ADV_STOP_EX
1092 * Samples the stop time of a profiling period (if running) and updates both
1093 * the sample and an attribution sample.
1094 *
1095 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1096 * @param pProfile2 Pointer to the STAMPROFILE structure which this
1097 * interval should be attributed to as well. This may be NULL.
1098 * @param Prefix Identifier prefix used to internal variables.
1099 */
1100#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
1101# define STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) \
1102 do { \
1103 if ((pProfileAdv)->tsStart) \
1104 { \
1105 uint64_t Prefix##_cTicks; \
1106 STAM_GET_TS(Prefix##_cTicks); \
1107 Prefix##_cTicks -= (pProfileAdv)->tsStart; \
1108 (pProfileAdv)->tsStart = 0; \
1109 (pProfileAdv)->Core.cTicks += Prefix##_cTicks; \
1110 (pProfileAdv)->Core.cPeriods++; \
1111 if ((pProfileAdv)->Core.cTicksMax < Prefix##_cTicks) \
1112 (pProfileAdv)->Core.cTicksMax = Prefix##_cTicks; \
1113 if ((pProfileAdv)->Core.cTicksMin > Prefix##_cTicks) \
1114 (pProfileAdv)->Core.cTicksMin = Prefix##_cTicks; \
1115 if ((pProfile2)) \
1116 { \
1117 (pProfile2)->cTicks += Prefix##_cTicks; \
1118 (pProfile2)->cPeriods++; \
1119 if ((pProfile2)->cTicksMax < Prefix##_cTicks) \
1120 (pProfile2)->cTicksMax = Prefix##_cTicks; \
1121 if ((pProfile2)->cTicksMin > Prefix##_cTicks) \
1122 (pProfile2)->cTicksMin = Prefix##_cTicks; \
1123 } \
1124 } \
1125 } while (0)
1126#else
1127# define STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) do { } while (0)
1128#endif
1129/** @def STAM_PROFILE_ADV_STOP_EX
1130 * Samples the stop time of a profiling period (if running) and updates both
1131 * the sample and an attribution sample.
1132 *
1133 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1134 * @param pProfile2 Pointer to the STAMPROFILE structure which this
1135 * interval should be attributed to as well. This may be NULL.
1136 * @param Prefix Identifier prefix used to internal variables.
1137 */
1138#ifdef VBOX_WITH_STATISTICS
1139# define STAM_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix)
1140#else
1141# define STAM_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) do { } while (0)
1142#endif
1143
1144/** @def STAM_REL_PROFILE_ADV_IS_RUNNING
1145 * Checks if it is running.
1146 *
1147 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1148 */
1149#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
1150# define STAM_REL_PROFILE_ADV_IS_RUNNING(pProfileAdv) (pProfileAdv)->tsStart
1151#else
1152# define STAM_REL_PROFILE_ADV_IS_RUNNING(pProfileAdv) (false)
1153#endif
1154/** @def STAM_PROFILE_ADV_IS_RUNNING
1155 * Checks if it is running.
1156 *
1157 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1158 */
1159#ifdef VBOX_WITH_STATISTICS
1160# define STAM_PROFILE_ADV_IS_RUNNING(pProfileAdv) STAM_REL_PROFILE_ADV_IS_RUNNING(pProfileAdv)
1161#else
1162# define STAM_PROFILE_ADV_IS_RUNNING(pProfileAdv) (false)
1163#endif
1164
1165/** @def STAM_REL_PROFILE_ADV_SET_STOPPED
1166 * Marks the profile counter as stopped.
1167 *
1168 * This is for avoiding screwups in twisty code.
1169 *
1170 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1171 */
1172#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
1173# define STAM_REL_PROFILE_ADV_SET_STOPPED(pProfileAdv) do { (pProfileAdv)->tsStart = 0; } while (0)
1174#else
1175# define STAM_REL_PROFILE_ADV_SET_STOPPED(pProfileAdv) do { } while (0)
1176#endif
1177/** @def STAM_PROFILE_ADV_SET_STOPPED
1178 * Marks the profile counter as stopped.
1179 *
1180 * This is for avoiding screwups in twisty code.
1181 *
1182 * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
1183 */
1184#ifdef VBOX_WITH_STATISTICS
1185# define STAM_PROFILE_ADV_SET_STOPPED(pProfileAdv) STAM_REL_PROFILE_ADV_SET_STOPPED(pProfileAdv)
1186#else
1187# define STAM_PROFILE_ADV_SET_STOPPED(pProfileAdv) do { } while (0)
1188#endif
1189
1190
1191/**
1192 * Ratio of A to B, uint32_t types.
1193 * @remark Use STAM_STATS or STAM_REL_STATS for modifying A & B values.
1194 */
1195typedef struct STAMRATIOU32
1196{
1197 /** Sample A. */
1198 uint32_t volatile u32A;
1199 /** Sample B. */
1200 uint32_t volatile u32B;
1201} STAMRATIOU32;
1202/** Pointer to a uint32_t ratio. */
1203typedef STAMRATIOU32 *PSTAMRATIOU32;
1204/** Pointer to const a uint32_t ratio. */
1205typedef const STAMRATIOU32 *PCSTAMRATIOU32;
1206
1207
1208
1209
1210/** @defgroup grp_stam_r3 The STAM Host Context Ring 3 API
1211 * @{
1212 */
1213
1214VMMR3DECL(int) STAMR3InitUVM(PUVM pUVM);
1215VMMR3DECL(void) STAMR3TermUVM(PUVM pUVM);
1216VMMR3DECL(int) STAMR3RegisterU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
1217 const char *pszName, STAMUNIT enmUnit, const char *pszDesc);
1218VMMR3DECL(int) STAMR3Register(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
1219 const char *pszName, STAMUNIT enmUnit, const char *pszDesc);
1220
1221/** @def STAM_REL_REG
1222 * Registers a statistics sample.
1223 *
1224 * @param pVM The cross context VM structure.
1225 * @param pvSample Pointer to the sample.
1226 * @param enmType Sample type. This indicates what pvSample is pointing at.
1227 * @param pszName Sample name. The name is on this form "/<component>/<sample>".
1228 * Further nesting is possible.
1229 * @param enmUnit Sample unit.
1230 * @param pszDesc Sample description.
1231 */
1232#define STAM_REL_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
1233 STAM_REL_STATS({ int rcStam = STAMR3Register(pVM, pvSample, enmType, STAMVISIBILITY_ALWAYS, pszName, enmUnit, pszDesc); \
1234 AssertRC(rcStam); })
1235/** @def STAM_REG
1236 * Registers a statistics sample if statistics are enabled.
1237 *
1238 * @param pVM The cross context VM structure.
1239 * @param pvSample Pointer to the sample.
1240 * @param enmType Sample type. This indicates what pvSample is pointing at.
1241 * @param pszName Sample name. The name is on this form "/<component>/<sample>".
1242 * Further nesting is possible.
1243 * @param enmUnit Sample unit.
1244 * @param pszDesc Sample description.
1245 */
1246#define STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
1247 STAM_STATS({STAM_REL_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc);})
1248
1249/** @def STAM_REL_REG_USED
1250 * Registers a statistics sample which only shows when used.
1251 *
1252 * @param pVM The cross context VM structure.
1253 * @param pvSample Pointer to the sample.
1254 * @param enmType Sample type. This indicates what pvSample is pointing at.
1255 * @param pszName Sample name. The name is on this form "/<component>/<sample>".
1256 * Further nesting is possible.
1257 * @param enmUnit Sample unit.
1258 * @param pszDesc Sample description.
1259 */
1260#define STAM_REL_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
1261 STAM_REL_STATS({ int rcStam = STAMR3Register(pVM, pvSample, enmType, STAMVISIBILITY_USED, pszName, enmUnit, pszDesc); \
1262 AssertRC(rcStam);})
1263/** @def STAM_REG_USED
1264 * Registers a statistics sample which only shows when used, if statistics are enabled.
1265 *
1266 * @param pVM The cross context VM structure.
1267 * @param pvSample Pointer to the sample.
1268 * @param enmType Sample type. This indicates what pvSample is pointing at.
1269 * @param pszName Sample name. The name is on this form "/<component>/<sample>".
1270 * Further nesting is possible.
1271 * @param enmUnit Sample unit.
1272 * @param pszDesc Sample description.
1273 */
1274#define STAM_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
1275 STAM_STATS({ STAM_REL_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc); })
1276
1277VMMR3DECL(int) STAMR3RegisterFU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1278 const char *pszDesc, const char *pszName, ...) RT_IPRT_FORMAT_ATTR(7, 8);
1279VMMR3DECL(int) STAMR3RegisterF(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1280 const char *pszDesc, const char *pszName, ...) RT_IPRT_FORMAT_ATTR(7, 8);
1281VMMR3DECL(int) STAMR3RegisterVU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1282 const char *pszDesc, const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(7, 0);
1283VMMR3DECL(int) STAMR3RegisterV(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1284 const char *pszDesc, const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(7, 0);
1285
1286/**
1287 * Resets the sample.
1288 * @param pVM The cross context VM structure.
1289 * @param pvSample The sample registered using STAMR3RegisterCallback.
1290 */
1291typedef DECLCALLBACKTYPE(void, FNSTAMR3CALLBACKRESET,(PVM pVM, void *pvSample));
1292/** Pointer to a STAM sample reset callback. */
1293typedef FNSTAMR3CALLBACKRESET *PFNSTAMR3CALLBACKRESET;
1294
1295/**
1296 * Prints the sample into the buffer.
1297 *
1298 * @param pVM The cross context VM structure.
1299 * @param pvSample The sample registered using STAMR3RegisterCallback.
1300 * @param pszBuf The buffer to print into.
1301 * @param cchBuf The size of the buffer.
1302 */
1303typedef DECLCALLBACKTYPE(void, FNSTAMR3CALLBACKPRINT,(PVM pVM, void *pvSample, char *pszBuf, size_t cchBuf));
1304/** Pointer to a STAM sample print callback. */
1305typedef FNSTAMR3CALLBACKPRINT *PFNSTAMR3CALLBACKPRINT;
1306
1307VMMR3DECL(int) STAMR3RegisterCallback(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1308 PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
1309 const char *pszDesc, const char *pszName, ...) RT_IPRT_FORMAT_ATTR(8, 9);
1310VMMR3DECL(int) STAMR3RegisterCallbackV(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1311 PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
1312 const char *pszDesc, const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(8, 0);
1313
1314VMMR3DECL(int) STAMR3RegisterRefresh(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
1315 STAMUNIT enmUnit, uint8_t iRefreshGrp, const char *pszDesc,
1316 const char *pszName, ...) RT_IPRT_FORMAT_ATTR(8, 9);
1317VMMR3DECL(int) STAMR3RegisterRefreshV(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
1318 STAMUNIT enmUnit, uint8_t iRefreshGrp, const char *pszDesc,
1319 const char *pszName, va_list va) RT_IPRT_FORMAT_ATTR(8, 0);
1320
1321VMMR3DECL(int) STAMR3Deregister(PUVM pUVM, const char *pszPat);
1322VMMR3DECL(int) STAMR3DeregisterF(PUVM pUVM, const char *pszPatFmt, ...) RT_IPRT_FORMAT_ATTR(2, 3);
1323VMMR3DECL(int) STAMR3DeregisterV(PUVM pUVM, const char *pszPatFmt, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
1324VMMR3DECL(int) STAMR3DeregisterByPrefix(PUVM pUVM, const char *pszPrefix);
1325VMMR3DECL(int) STAMR3DeregisterByAddr(PUVM pUVM, void *pvSample);
1326
1327VMMR3DECL(int) STAMR3Reset(PUVM pUVM, const char *pszPat);
1328VMMR3DECL(int) STAMR3Snapshot(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc);
1329VMMR3DECL(int) STAMR3SnapshotFree(PUVM pUVM, char *pszSnapshot);
1330VMMR3DECL(int) STAMR3Dump(PUVM pUVM, const char *pszPat);
1331VMMR3DECL(int) STAMR3DumpToReleaseLog(PUVM pUVM, const char *pszPat);
1332VMMR3DECL(int) STAMR3Print(PUVM pUVM, const char *pszPat);
1333
1334/**
1335 * Callback function for STAMR3Enum().
1336 *
1337 * @returns non-zero to halt the enumeration.
1338 *
1339 * @param pszName The name of the sample.
1340 * @param enmType The type.
1341 * @param pvSample Pointer to the data. enmType indicates the format of this data.
1342 * @param enmUnit The unit.
1343 * @param enmVisibility The visibility.
1344 * @param pszDesc The description.
1345 * @param pvUser The pvUser argument given to STAMR3Enum().
1346 */
1347typedef DECLCALLBACKTYPE(int, FNSTAMR3ENUM,(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
1348 STAMVISIBILITY enmVisibility, const char *pszDesc, void *pvUser));
1349/** Pointer to a FNSTAMR3ENUM(). */
1350typedef FNSTAMR3ENUM *PFNSTAMR3ENUM;
1351
1352VMMR3DECL(int) STAMR3Enum(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser);
1353VMMR3DECL(const char *) STAMR3GetUnit(STAMUNIT enmUnit);
1354VMMR3DECL(const char *) STAMR3GetUnit1(STAMUNIT enmUnit);
1355VMMR3DECL(const char *) STAMR3GetUnit2(STAMUNIT enmUnit);
1356
1357/** @} */
1358
1359/** @} */
1360
1361RT_C_DECLS_END
1362
1363#endif /* !VBOX_INCLUDED_vmm_stam_h */
1364
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