VirtualBox

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

Last change on this file since 102077 was 102077, checked in by vboxsync, 15 months ago

VMM/IEM,STAM: Native translation of IEM_MC_REF_EFLAGS, IEM_MC_REF_GREG_U16, IEM_MC_CALL_VOID_AIMPL_X and IEM_MC_CALL_AIMPL_X. Added STAMUNIT_BYTES_PER_TB. bugref:10371

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