VirtualBox

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

Last change on this file since 99582 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

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