VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 8 weeks ago

Copyright year updates by scm.

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