2
* STAM - Statistics Manager. (VMM)
6
* Copyright (C) 2006-2007 Oracle Corporation
8
* This file is part of VirtualBox Open Source Edition (OSE), as
9
* available from http://www.virtualbox.org. This file is free software;
10
* you can redistribute it and/or modify it under the terms of the GNU
11
* General Public License (GPL) as published by the Free Software
12
* Foundation, in version 2 as it comes in the "COPYING" file of the
13
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16
* The contents of this file may alternatively be used under the terms
17
* of the Common Development and Distribution License Version 1.0
18
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19
* VirtualBox OSE distribution, in which case the provisions of the
20
* CDDL are applicable instead of those of the GPL.
22
* You may elect to license modified versions of this file under the
23
* terms and conditions of either the GPL or the CDDL or both.
26
#ifndef ___VBox_stam_h
27
#define ___VBox_stam_h
29
#include <VBox/cdefs.h>
30
#include <VBox/types.h>
31
#include <iprt/stdarg.h>
40
/** @defgroup grp_stam The Statistics Manager API
44
#if defined(VBOX_WITHOUT_RELEASE_STATISTICS) && defined(VBOX_WITH_STATISTICS)
45
# error "Both VBOX_WITHOUT_RELEASE_STATISTICS and VBOX_WITH_STATISTICS are defined! Make up your mind!"
50
* Gets the CPU timestamp counter.
52
* @param u64 The 64-bit variable which the timestamp shall be saved in.
55
# if defined(RT_ARCH_X86)
56
/* This produces optimal assembler code for x86 but does not work for AMD64 ('A' means 'either rax or rdx') */
57
# define STAM_GET_TS(u64) __asm__ __volatile__ ("rdtsc\n\t" : "=A" (u64))
58
# elif defined(RT_ARCH_AMD64)
59
# define STAM_GET_TS(u64) \
60
do { uint64_t low; uint64_t high; \
61
__asm__ __volatile__ ("rdtsc\n\t" : "=a"(low), "=d"(high)); \
62
(u64) = ((high << 32) | low); \
67
# pragma intrinsic(__rdtsc)
68
# define STAM_GET_TS(u64) \
69
do { (u64) = __rdtsc(); } while (0)
71
# define STAM_GET_TS(u64) \
76
__asm mov dword ptr [u64Tmp], eax \
77
__asm mov dword ptr [u64Tmp + 4], edx \
85
/** @def STAM_REL_STATS
86
* Code for inclusion only when VBOX_WITH_STATISTICS is defined.
87
* @param code A code block enclosed in {}.
89
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
90
# define STAM_REL_STATS(code) do code while(0)
92
# define STAM_REL_STATS(code) do {} while(0)
95
* Code for inclusion only when VBOX_WITH_STATISTICS is defined.
96
* @param code A code block enclosed in {}.
98
#ifdef VBOX_WITH_STATISTICS
99
# define STAM_STATS(code) STAM_REL_STATS(code)
101
# define STAM_STATS(code) do {} while(0)
108
typedef enum STAMTYPE
110
/** Invalid entry. */
111
STAMTYPE_INVALID = 0,
112
/** Generic counter. */
114
/** Profiling of an function. */
116
/** Profiling of an operation. */
117
STAMTYPE_PROFILE_ADV,
118
/** Ratio of A to B, uint32_t types. Not reset. */
120
/** Ratio of A to B, uint32_t types. Reset both to 0. */
121
STAMTYPE_RATIO_U32_RESET,
124
/** Generic unsigned 8-bit value. Not reset. */
126
/** Generic unsigned 8-bit value. Reset to 0. */
128
/** Generic hexadecimal unsigned 8-bit value. Not reset. */
130
/** Generic hexadecimal unsigned 8-bit value. Reset to 0. */
132
/** Generic unsigned 16-bit value. Not reset. */
134
/** Generic unsigned 16-bit value. Reset to 0. */
136
/** Generic hexadecimal unsigned 16-bit value. Not reset. */
138
/** Generic hexadecimal unsigned 16-bit value. Reset to 0. */
140
/** Generic unsigned 32-bit value. Not reset. */
142
/** Generic unsigned 32-bit value. Reset to 0. */
144
/** Generic hexadecimal unsigned 32-bit value. Not reset. */
146
/** Generic hexadecimal unsigned 32-bit value. Reset to 0. */
148
/** Generic unsigned 64-bit value. Not reset. */
150
/** Generic unsigned 64-bit value. Reset to 0. */
152
/** Generic hexadecimal unsigned 64-bit value. Not reset. */
154
/** Generic hexadecimal unsigned 64-bit value. Reset to 0. */
156
/** The end (exclusive). */
161
* Sample visibility type.
163
typedef enum STAMVISIBILITY
165
/** Invalid entry. */
166
STAMVISIBILITY_INVALID = 0,
167
/** Always visible. */
168
STAMVISIBILITY_ALWAYS,
169
/** Only visible when used (/hit). */
171
/** Not visible in the GUI. */
172
STAMVISIBILITY_NOT_GUI,
173
/** The end (exclusive). */
180
typedef enum STAMUNIT
182
/** Invalid entry .*/
183
STAMUNIT_INVALID = 0,
186
/** Number of calls. */
188
/** Count of whatever. */
190
/** Count of bytes. */
192
/** Count of bytes. */
196
/** Number of occurences. */
200
/** Ticks per call. */
201
STAMUNIT_TICKS_PER_CALL,
202
/** Ticks per occurence. */
203
STAMUNIT_TICKS_PER_OCCURENCE,
204
/** Ratio of good vs. bad. */
212
/** Nanoseconds per call. */
213
STAMUNIT_NS_PER_CALL,
214
/** Nanoseconds per call. */
215
STAMUNIT_NS_PER_OCCURENCE,
218
/** The end (exclusive). */
223
/** @def STAM_REL_U8_INC
224
* Increments a uint8_t sample by one.
226
* @param pCounter Pointer to the uint8_t variable to operate on.
228
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
229
# define STAM_REL_U8_INC(pCounter) \
230
do { ++*(pCounter); } while (0)
232
# define STAM_REL_U8_INC(pCounter) do { } while (0)
235
* Increments a uint8_t sample by one.
237
* @param pCounter Pointer to the uint8_t variable to operate on.
239
#ifdef VBOX_WITH_STATISTICS
240
# define STAM_U8_INC(pCounter) STAM_REL_U8_INC(pCounter)
242
# define STAM_U8_INC(pCounter) do { } while (0)
246
/** @def STAM_REL_U8_DEC
247
* Decrements a uint8_t sample by one.
249
* @param pCounter Pointer to the uint8_t variable to operate on.
251
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
252
# define STAM_REL_U8_DEC(pCounter) \
253
do { --*(pCounter); } while (0)
255
# define STAM_REL_U8_DEC(pCounter) do { } while (0)
258
* Decrements a uint8_t sample by one.
260
* @param pCounter Pointer to the uint8_t variable to operate on.
262
#ifdef VBOX_WITH_STATISTICS
263
# define STAM_U8_DEC(pCounter) STAM_REL_U8_DEC(pCounter)
265
# define STAM_U8_DEC(pCounter) do { } while (0)
269
/** @def STAM_REL_U8_ADD
270
* Increments a uint8_t sample by a value.
272
* @param pCounter Pointer to the uint8_t variable to operate on.
273
* @param Addend The value to add.
275
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
276
# define STAM_REL_U8_ADD(pCounter, Addend) \
277
do { *(pCounter) += (Addend); } while (0)
279
# define STAM_REL_U8_ADD(pCounter, Addend) do { } while (0)
282
* Increments a uint8_t sample by a value.
284
* @param pCounter Pointer to the uint8_t variable to operate on.
285
* @param Addend The value to add.
287
#ifdef VBOX_WITH_STATISTICS
288
# define STAM_U8_ADD(pCounter, Addend) STAM_REL_U8_ADD(pCounter, Addend
290
# define STAM_U8_ADD(pCounter, Addend) do { } while (0)
294
/** @def STAM_REL_U16_INC
295
* Increments a uint16_t sample by one.
297
* @param pCounter Pointer to the uint16_t variable to operate on.
299
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
300
# define STAM_REL_U16_INC(pCounter) \
301
do { ++*(pCounter); } while (0)
303
# define STAM_REL_U16_INC(pCounter) do { } while (0)
305
/** @def STAM_U16_INC
306
* Increments a uint16_t sample by one.
308
* @param pCounter Pointer to the uint16_t variable to operate on.
310
#ifdef VBOX_WITH_STATISTICS
311
# define STAM_U16_INC(pCounter) STAM_REL_U16_INC(pCounter)
313
# define STAM_U16_INC(pCounter) do { } while (0)
317
/** @def STAM_REL_U16_DEC
318
* Decrements a uint16_t sample by one.
320
* @param pCounter Pointer to the uint16_t variable to operate on.
322
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
323
# define STAM_REL_U16_DEC(pCounter) \
324
do { --*(pCounter); } while (0)
326
# define STAM_REL_U16_DEC(pCounter) do { } while (0)
328
/** @def STAM_U16_DEC
329
* Decrements a uint16_t sample by one.
331
* @param pCounter Pointer to the uint16_t variable to operate on.
333
#ifdef VBOX_WITH_STATISTICS
334
# define STAM_U16_DEC(pCounter) STAM_REL_U16_DEC(pCounter)
336
# define STAM_U16_DEC(pCounter) do { } while (0)
340
/** @def STAM_REL_U16_INC
341
* Increments a uint16_t sample by a value.
343
* @param pCounter Pointer to the uint16_t variable to operate on.
344
* @param Addend The value to add.
346
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
347
# define STAM_REL_U16_ADD(pCounter, Addend) \
348
do { *(pCounter) += (Addend); } while (0)
350
# define STAM_REL_U16_ADD(pCounter, Addend) do { } while (0)
352
/** @def STAM_U16_INC
353
* Increments a uint16_t sample by a value.
355
* @param pCounter Pointer to the uint16_t variable to operate on.
356
* @param Addend The value to add.
358
#ifdef VBOX_WITH_STATISTICS
359
# define STAM_U16_ADD(pCounter, Addend) STAM_REL_U16_ADD(pCounter, Addend)
361
# define STAM_U16_ADD(pCounter, Addend) do { } while (0)
365
/** @def STAM_REL_U32_INC
366
* Increments a uint32_t sample by one.
368
* @param pCounter Pointer to the uint32_t variable to operate on.
370
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
371
# define STAM_REL_U32_INC(pCounter) \
372
do { ++*(pCounter); } while (0)
374
# define STAM_REL_U32_INC(pCounter) do { } while (0)
376
/** @def STAM_U32_INC
377
* Increments a uint32_t sample by one.
379
* @param pCounter Pointer to the uint32_t variable to operate on.
381
#ifdef VBOX_WITH_STATISTICS
382
# define STAM_U32_INC(pCounter) STAM_REL_U32_INC(pCounter)
384
# define STAM_U32_INC(pCounter) do { } while (0)
388
/** @def STAM_REL_U32_DEC
389
* Decrements a uint32_t sample by one.
391
* @param pCounter Pointer to the uint32_t variable to operate on.
393
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
394
# define STAM_REL_U32_DEC(pCounter) \
395
do { --*(pCounter); } while (0)
397
# define STAM_REL_U32_DEC(pCounter) do { } while (0)
399
/** @def STAM_U32_DEC
400
* Decrements a uint32_t sample by one.
402
* @param pCounter Pointer to the uint32_t variable to operate on.
404
#ifdef VBOX_WITH_STATISTICS
405
# define STAM_U32_DEC(pCounter) STAM_REL_U32_DEC(pCounter)
407
# define STAM_U32_DEC(pCounter) do { } while (0)
411
/** @def STAM_REL_U32_ADD
412
* Increments a uint32_t sample by value.
414
* @param pCounter Pointer to the uint32_t variable to operate on.
415
* @param Addend The value to add.
417
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
418
# define STAM_REL_U32_ADD(pCounter, Addend) \
419
do { *(pCounter) += (Addend); } while (0)
421
# define STAM_REL_U32_ADD(pCounter, Addend) do { } while (0)
423
/** @def STAM_U32_ADD
424
* Increments a uint32_t sample by value.
426
* @param pCounter Pointer to the uint32_t variable to operate on.
427
* @param Addend The value to add.
429
#ifdef VBOX_WITH_STATISTICS
430
# define STAM_U32_ADD(pCounter, Addend) STAM_REL_U32_ADD(pCounter, Addend)
432
# define STAM_U32_ADD(pCounter, Addend) do { } while (0)
436
/** @def STAM_REL_U64_INC
437
* Increments a uint64_t sample by one.
439
* @param pCounter Pointer to the uint64_t variable to operate on.
441
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
442
# define STAM_REL_U64_INC(pCounter) \
443
do { ++*(pCounter); } while (0)
445
# define STAM_REL_U64_INC(pCounter) do { } while (0)
447
/** @def STAM_U64_INC
448
* Increments a uint64_t sample by one.
450
* @param pCounter Pointer to the uint64_t variable to operate on.
452
#ifdef VBOX_WITH_STATISTICS
453
# define STAM_U64_INC(pCounter) STAM_REL_U64_INC(pCounter)
455
# define STAM_U64_INC(pCounter) do { } while (0)
459
/** @def STAM_REL_U64_DEC
460
* Decrements a uint64_t sample by one.
462
* @param pCounter Pointer to the uint64_t variable to operate on.
464
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
465
# define STAM_REL_U64_DEC(pCounter) \
466
do { --*(pCounter); } while (0)
468
# define STAM_REL_U64_DEC(pCounter) do { } while (0)
470
/** @def STAM_U64_DEC
471
* Decrements a uint64_t sample by one.
473
* @param pCounter Pointer to the uint64_t variable to operate on.
475
#ifdef VBOX_WITH_STATISTICS
476
# define STAM_U64_DEC(pCounter) STAM_REL_U64_DEC(pCounter)
478
# define STAM_U64_DEC(pCounter) do { } while (0)
482
/** @def STAM_REL_U64_ADD
483
* Increments a uint64_t sample by a value.
485
* @param pCounter Pointer to the uint64_t variable to operate on.
486
* @param Addend The value to add.
488
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
489
# define STAM_REL_U64_ADD(pCounter, Addend) \
490
do { *(pCounter) += (Addend); } while (0)
492
# define STAM_REL_U64_ADD(pCounter, Addend) do { } while (0)
494
/** @def STAM_U64_ADD
495
* Increments a uint64_t sample by a value.
497
* @param pCounter Pointer to the uint64_t variable to operate on.
498
* @param Addend The value to add.
500
#ifdef VBOX_WITH_STATISTICS
501
# define STAM_U64_ADD(pCounter, Addend) STAM_REL_U64_ADD(pCounter, Addend)
503
# define STAM_U64_ADD(pCounter, Addend) do { } while (0)
508
* Counter sample - STAMTYPE_COUNTER.
510
typedef struct STAMCOUNTER
512
/** The current count. */
515
/** Pointer to a counter. */
516
typedef STAMCOUNTER *PSTAMCOUNTER;
517
/** Pointer to a const counter. */
518
typedef const STAMCOUNTER *PCSTAMCOUNTER;
521
/** @def STAM_REL_COUNTER_INC
522
* Increments a counter sample by one.
524
* @param pCounter Pointer to the STAMCOUNTER structure to operate on.
526
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
527
# define STAM_REL_COUNTER_INC(pCounter) \
528
do { (pCounter)->c++; } while (0)
530
# define STAM_REL_COUNTER_INC(pCounter) do { } while (0)
532
/** @def STAM_COUNTER_INC
533
* Increments a counter sample by one.
535
* @param pCounter Pointer to the STAMCOUNTER structure to operate on.
537
#ifdef VBOX_WITH_STATISTICS
538
# define STAM_COUNTER_INC(pCounter) STAM_REL_COUNTER_INC(pCounter)
540
# define STAM_COUNTER_INC(pCounter) do { } while (0)
544
/** @def STAM_REL_COUNTER_DEC
545
* Decrements a counter sample by one.
547
* @param pCounter Pointer to the STAMCOUNTER structure to operate on.
549
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
550
# define STAM_REL_COUNTER_DEC(pCounter) \
551
do { (pCounter)->c--; } while (0)
553
# define STAM_REL_COUNTER_DEC(pCounter) do { } while (0)
555
/** @def STAM_COUNTER_DEC
556
* Decrements a counter sample by one.
558
* @param pCounter Pointer to the STAMCOUNTER structure to operate on.
560
#ifdef VBOX_WITH_STATISTICS
561
# define STAM_COUNTER_DEC(pCounter) STAM_REL_COUNTER_DEC(pCounter)
563
# define STAM_COUNTER_DEC(pCounter) do { } while (0)
567
/** @def STAM_REL_COUNTER_ADD
568
* Increments a counter sample by a value.
570
* @param pCounter Pointer to the STAMCOUNTER structure to operate on.
571
* @param Addend The value to add to the counter.
573
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
574
# define STAM_REL_COUNTER_ADD(pCounter, Addend) \
575
do { (pCounter)->c += (Addend); } while (0)
577
# define STAM_REL_COUNTER_ADD(pCounter, Addend) do { } while (0)
579
/** @def STAM_COUNTER_ADD
580
* Increments a counter sample by a value.
582
* @param pCounter Pointer to the STAMCOUNTER structure to operate on.
583
* @param Addend The value to add to the counter.
585
#ifdef VBOX_WITH_STATISTICS
586
# define STAM_COUNTER_ADD(pCounter, Addend) STAM_REL_COUNTER_ADD(pCounter, Addend)
588
# define STAM_COUNTER_ADD(pCounter, Addend) do { } while (0)
592
/** @def STAM_REL_COUNTER_RESET
593
* Resets the statistics sample.
595
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
596
# define STAM_REL_COUNTER_RESET(pCounter) do { (pCounter)->c = 0; } while (0)
598
# define STAM_REL_COUNTER_RESET(pCounter) do { } while (0)
600
/** @def STAM_COUNTER_RESET
601
* Resets the statistics sample.
603
#ifdef VBOX_WITH_STATISTICS
604
# define STAM_COUNTER_RESET(pCounter) STAM_REL_COUNTER_RESET(pCounter)
606
# define STAM_COUNTER_RESET(pCounter) do { } while (0)
612
* Profiling sample - STAMTYPE_PROFILE.
614
typedef struct STAMPROFILE
616
/** Number of periods. */
617
volatile uint64_t cPeriods;
618
/** Total count of ticks. */
619
volatile uint64_t cTicks;
620
/** Maximum tick count during a sampling. */
621
volatile uint64_t cTicksMax;
622
/** Minimum tick count during a sampling. */
623
volatile uint64_t cTicksMin;
625
/** Pointer to a profile sample. */
626
typedef STAMPROFILE *PSTAMPROFILE;
627
/** Pointer to a const profile sample. */
628
typedef const STAMPROFILE *PCSTAMPROFILE;
631
/** @def STAM_REL_PROFILE_START
632
* Samples the start time of a profiling period.
634
* @param pProfile Pointer to the STAMPROFILE structure to operate on.
635
* @param Prefix Identifier prefix used to internal variables.
637
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
638
# define STAM_REL_PROFILE_START(pProfile, Prefix) \
639
uint64_t Prefix##_tsStart; \
640
STAM_GET_TS(Prefix##_tsStart)
642
# define STAM_REL_PROFILE_START(pProfile, Prefix) do { } while (0)
644
/** @def STAM_PROFILE_START
645
* Samples the start time of a profiling period.
647
* @param pProfile Pointer to the STAMPROFILE structure to operate on.
648
* @param Prefix Identifier prefix used to internal variables.
650
#ifdef VBOX_WITH_STATISTICS
651
# define STAM_PROFILE_START(pProfile, Prefix) STAM_REL_PROFILE_START(pProfile, Prefix)
653
# define STAM_PROFILE_START(pProfile, Prefix) do { } while (0)
656
/** @def STAM_REL_PROFILE_STOP
657
* Samples the stop time of a profiling period and updates the sample.
659
* @param pProfile Pointer to the STAMPROFILE structure to operate on.
660
* @param Prefix Identifier prefix used to internal variables.
662
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
663
# define STAM_REL_PROFILE_STOP(pProfile, Prefix) \
665
uint64_t Prefix##_cTicks; \
666
uint64_t Prefix##_tsStop; \
667
STAM_GET_TS(Prefix##_tsStop); \
668
Prefix##_cTicks = Prefix##_tsStop - Prefix##_tsStart; \
669
(pProfile)->cTicks += Prefix##_cTicks; \
670
(pProfile)->cPeriods++; \
671
if ((pProfile)->cTicksMax < Prefix##_cTicks) \
672
(pProfile)->cTicksMax = Prefix##_cTicks; \
673
if ((pProfile)->cTicksMin > Prefix##_cTicks) \
674
(pProfile)->cTicksMin = Prefix##_cTicks; \
677
# define STAM_REL_PROFILE_STOP(pProfile, Prefix) do { } while (0)
679
/** @def STAM_PROFILE_STOP
680
* Samples the stop time of a profiling period and updates the sample.
682
* @param pProfile Pointer to the STAMPROFILE structure to operate on.
683
* @param Prefix Identifier prefix used to internal variables.
685
#ifdef VBOX_WITH_STATISTICS
686
# define STAM_PROFILE_STOP(pProfile, Prefix) STAM_REL_PROFILE_STOP(pProfile, Prefix)
688
# define STAM_PROFILE_STOP(pProfile, Prefix) do { } while (0)
692
/** @def STAM_REL_PROFILE_STOP_EX
693
* Samples the stop time of a profiling period and updates both the sample
694
* and an attribution sample.
696
* @param pProfile Pointer to the STAMPROFILE structure to operate on.
697
* @param pProfile2 Pointer to the STAMPROFILE structure which this
698
* interval should be attributed to as well. This may be NULL.
699
* @param Prefix Identifier prefix used to internal variables.
701
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
702
# define STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) \
704
uint64_t Prefix##_cTicks; \
705
uint64_t Prefix##_tsStop; \
706
STAM_GET_TS(Prefix##_tsStop); \
707
Prefix##_cTicks = Prefix##_tsStop - Prefix##_tsStart; \
708
(pProfile)->cTicks += Prefix##_cTicks; \
709
(pProfile)->cPeriods++; \
710
if ((pProfile)->cTicksMax < Prefix##_cTicks) \
711
(pProfile)->cTicksMax = Prefix##_cTicks; \
712
if ((pProfile)->cTicksMin > Prefix##_cTicks) \
713
(pProfile)->cTicksMin = Prefix##_cTicks; \
717
(pProfile2)->cTicks += Prefix##_cTicks; \
718
(pProfile2)->cPeriods++; \
719
if ((pProfile2)->cTicksMax < Prefix##_cTicks) \
720
(pProfile2)->cTicksMax = Prefix##_cTicks; \
721
if ((pProfile2)->cTicksMin > Prefix##_cTicks) \
722
(pProfile2)->cTicksMin = Prefix##_cTicks; \
726
# define STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) do { } while (0)
728
/** @def STAM_PROFILE_STOP_EX
729
* Samples the stop time of a profiling period and updates both the sample
730
* and an attribution sample.
732
* @param pProfile Pointer to the STAMPROFILE structure to operate on.
733
* @param pProfile2 Pointer to the STAMPROFILE structure which this
734
* interval should be attributed to as well. This may be NULL.
735
* @param Prefix Identifier prefix used to internal variables.
737
#ifdef VBOX_WITH_STATISTICS
738
# define STAM_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix)
740
# define STAM_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) do { } while (0)
745
* Advanced profiling sample - STAMTYPE_PROFILE_ADV.
747
* Identical to a STAMPROFILE sample, but the start timestamp
748
* is stored after the STAMPROFILE structure so the sampling
749
* can start and stop in different functions.
751
typedef struct STAMPROFILEADV
753
/** The STAMPROFILE core. */
755
/** The start timestamp. */
756
volatile uint64_t tsStart;
758
/** Pointer to a advanced profile sample. */
759
typedef STAMPROFILEADV *PSTAMPROFILEADV;
760
/** Pointer to a const advanced profile sample. */
761
typedef const STAMPROFILEADV *PCSTAMPROFILEADV;
764
/** @def STAM_REL_PROFILE_ADV_START
765
* Samples the start time of a profiling period.
767
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
768
* @param Prefix Identifier prefix used to internal variables.
770
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
771
# define STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix) \
772
STAM_GET_TS((pProfileAdv)->tsStart)
774
# define STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix) do { } while (0)
776
/** @def STAM_PROFILE_ADV_START
777
* Samples the start time of a profiling period.
779
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
780
* @param Prefix Identifier prefix used to internal variables.
782
#ifdef VBOX_WITH_STATISTICS
783
# define STAM_PROFILE_ADV_START(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix)
785
# define STAM_PROFILE_ADV_START(pProfileAdv, Prefix) do { } while (0)
789
/** @def STAM_REL_PROFILE_ADV_STOP
790
* Samples the stop time of a profiling period and updates the sample.
792
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
793
* @param Prefix Identifier prefix used to internal variables.
795
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
796
# define STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix) \
798
uint64_t Prefix##_tsStop; \
799
STAM_GET_TS(Prefix##_tsStop); \
800
if ((pProfileAdv)->tsStart) \
802
uint64_t Prefix##_cTicks = Prefix##_tsStop - (pProfileAdv)->tsStart; \
803
(pProfileAdv)->tsStart = 0; \
804
(pProfileAdv)->Core.cTicks += Prefix##_cTicks; \
805
(pProfileAdv)->Core.cPeriods++; \
806
if ((pProfileAdv)->Core.cTicksMax < Prefix##_cTicks) \
807
(pProfileAdv)->Core.cTicksMax = Prefix##_cTicks; \
808
if ((pProfileAdv)->Core.cTicksMin > Prefix##_cTicks) \
809
(pProfileAdv)->Core.cTicksMin = Prefix##_cTicks; \
813
# define STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix) do { } while (0)
815
/** @def STAM_PROFILE_ADV_STOP
816
* Samples the stop time of a profiling period and updates the sample.
818
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
819
* @param Prefix Identifier prefix used to internal variables.
821
#ifdef VBOX_WITH_STATISTICS
822
# define STAM_PROFILE_ADV_STOP(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix)
824
# define STAM_PROFILE_ADV_STOP(pProfileAdv, Prefix) do { } while (0)
828
/** @def STAM_REL_PROFILE_ADV_SUSPEND
829
* Suspends the sampling for a while. This can be useful to exclude parts
830
* covered by other samples without screwing up the count, and average+min times.
832
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
833
* @param Prefix Identifier prefix used to internal variables. The prefix
834
* must match that of the resume one since it stores the
835
* suspend time in a stack variable.
837
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
838
# define STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) \
839
uint64_t Prefix##_tsSuspend; \
840
STAM_GET_TS(Prefix##_tsSuspend)
842
# define STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) do { } while (0)
844
/** @def STAM_PROFILE_ADV_SUSPEND
845
* Suspends the sampling for a while. This can be useful to exclude parts
846
* covered by other samples without screwing up the count, and average+min times.
848
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
849
* @param Prefix Identifier prefix used to internal variables. The prefix
850
* must match that of the resume one since it stores the
851
* suspend time in a stack variable.
853
#ifdef VBOX_WITH_STATISTICS
854
# define STAM_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix)
856
# define STAM_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) do { } while (0)
860
/** @def STAM_REL_PROFILE_ADV_RESUME
861
* Counter to STAM_REL_PROFILE_ADV_SUSPEND.
863
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
864
* @param Prefix Identifier prefix used to internal variables. This must
865
* match the one used with the SUSPEND!
867
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
868
# define STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix) \
870
uint64_t Prefix##_tsNow; \
871
STAM_GET_TS(Prefix##_tsNow); \
872
(pProfileAdv)->tsStart += Prefix##_tsNow - Prefix##_tsSuspend; \
875
# define STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix) do { } while (0)
877
/** @def STAM_PROFILE_ADV_RESUME
878
* Counter to STAM_PROFILE_ADV_SUSPEND.
880
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
881
* @param Prefix Identifier prefix used to internal variables. This must
882
* match the one used with the SUSPEND!
884
#ifdef VBOX_WITH_STATISTICS
885
# define STAM_PROFILE_ADV_RESUME(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix)
887
# define STAM_PROFILE_ADV_RESUME(pProfileAdv, Prefix) do { } while (0)
891
/** @def STAM_REL_PROFILE_ADV_STOP_EX
892
* Samples the stop time of a profiling period and updates both the sample
893
* and an attribution sample.
895
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
896
* @param pProfile2 Pointer to the STAMPROFILE structure which this
897
* interval should be attributed to as well. This may be NULL.
898
* @param Prefix Identifier prefix used to internal variables.
900
#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
901
# define STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) \
903
uint64_t Prefix##_tsStop; \
904
STAM_GET_TS(Prefix##_tsStop); \
905
if ((pProfileAdv)->tsStart) \
907
uint64_t Prefix##_cTicks = Prefix##_tsStop - (pProfileAdv)->tsStart; \
908
(pProfileAdv)->tsStart = 0; \
909
(pProfileAdv)->Core.cTicks += Prefix##_cTicks; \
910
(pProfileAdv)->Core.cPeriods++; \
911
if ((pProfileAdv)->Core.cTicksMax < Prefix##_cTicks) \
912
(pProfileAdv)->Core.cTicksMax = Prefix##_cTicks; \
913
if ((pProfileAdv)->Core.cTicksMin > Prefix##_cTicks) \
914
(pProfileAdv)->Core.cTicksMin = Prefix##_cTicks; \
917
(pProfile2)->cTicks += Prefix##_cTicks; \
918
(pProfile2)->cPeriods++; \
919
if ((pProfile2)->cTicksMax < Prefix##_cTicks) \
920
(pProfile2)->cTicksMax = Prefix##_cTicks; \
921
if ((pProfile2)->cTicksMin > Prefix##_cTicks) \
922
(pProfile2)->cTicksMin = Prefix##_cTicks; \
927
# define STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) do { } while (0)
929
/** @def STAM_PROFILE_ADV_STOP_EX
930
* Samples the stop time of a profiling period and updates both the sample
931
* and an attribution sample.
933
* @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
934
* @param pProfile2 Pointer to the STAMPROFILE structure which this
935
* interval should be attributed to as well. This may be NULL.
936
* @param Prefix Identifier prefix used to internal variables.
938
#ifdef VBOX_WITH_STATISTICS
939
# define STAM_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix)
941
# define STAM_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) do { } while (0)
946
* Ratio of A to B, uint32_t types.
947
* @remark Use STAM_STATS or STAM_REL_STATS for modifying A & B values.
949
typedef struct STAMRATIOU32
952
uint32_t volatile u32A;
954
uint32_t volatile u32B;
956
/** Pointer to a uint32_t ratio. */
957
typedef STAMRATIOU32 *PSTAMRATIOU32;
958
/** Pointer to const a uint32_t ratio. */
959
typedef const STAMRATIOU32 *PCSTAMRATIOU32;
964
/** @defgroup grp_stam_r3 The STAM Host Context Ring 3 API
969
VMMR3DECL(int) STAMR3InitUVM(PUVM pUVM);
970
VMMR3DECL(void) STAMR3TermUVM(PUVM pUVM);
971
VMMR3DECL(int) STAMR3RegisterU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
972
const char *pszName, STAMUNIT enmUnit, const char *pszDesc);
973
VMMR3DECL(int) STAMR3Register(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
974
const char *pszName, STAMUNIT enmUnit, const char *pszDesc);
976
/** @def STAM_REL_REG
977
* Registers a statistics sample.
979
* @param pVM VM Handle.
980
* @param pvSample Pointer to the sample.
981
* @param enmType Sample type. This indicates what pvSample is pointing at.
982
* @param pszName Sample name. The name is on this form "/<component>/<sample>".
983
* Further nesting is possible.
984
* @param enmUnit Sample unit.
985
* @param pszDesc Sample description.
987
#define STAM_REL_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
988
STAM_REL_STATS({ int rcStam = STAMR3Register(pVM, pvSample, enmType, STAMVISIBILITY_ALWAYS, pszName, enmUnit, pszDesc); \
991
* Registers a statistics sample if statistics are enabled.
993
* @param pVM VM Handle.
994
* @param pvSample Pointer to the sample.
995
* @param enmType Sample type. This indicates what pvSample is pointing at.
996
* @param pszName Sample name. The name is on this form "/<component>/<sample>".
997
* Further nesting is possible.
998
* @param enmUnit Sample unit.
999
* @param pszDesc Sample description.
1001
#define STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
1002
STAM_STATS({STAM_REL_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc);})
1004
/** @def STAM_REL_REG_USED
1005
* Registers a statistics sample which only shows when used.
1007
* @param pVM VM Handle.
1008
* @param pvSample Pointer to the sample.
1009
* @param enmType Sample type. This indicates what pvSample is pointing at.
1010
* @param pszName Sample name. The name is on this form "/<component>/<sample>".
1011
* Further nesting is possible.
1012
* @param enmUnit Sample unit.
1013
* @param pszDesc Sample description.
1015
#define STAM_REL_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
1016
STAM_REL_STATS({ int rcStam = STAMR3Register(pVM, pvSample, enmType, STAMVISIBILITY_USED, pszName, enmUnit, pszDesc); \
1018
/** @def STAM_REG_USED
1019
* Registers a statistics sample which only shows when used, if statistics are enabled.
1021
* @param pVM VM Handle.
1022
* @param pvSample Pointer to the sample.
1023
* @param enmType Sample type. This indicates what pvSample is pointing at.
1024
* @param pszName Sample name. The name is on this form "/<component>/<sample>".
1025
* Further nesting is possible.
1026
* @param enmUnit Sample unit.
1027
* @param pszDesc Sample description.
1029
#define STAM_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
1030
STAM_STATS({ STAM_REL_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc); })
1032
VMMR3DECL(int) STAMR3RegisterFU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1033
const char *pszDesc, const char *pszName, ...);
1034
VMMR3DECL(int) STAMR3RegisterF(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1035
const char *pszDesc, const char *pszName, ...);
1036
VMMR3DECL(int) STAMR3RegisterVU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1037
const char *pszDesc, const char *pszName, va_list args);
1038
VMMR3DECL(int) STAMR3RegisterV(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1039
const char *pszDesc, const char *pszName, va_list args);
1042
* Resets the sample.
1043
* @param pVM The VM handle.
1044
* @param pvSample The sample registered using STAMR3RegisterCallback.
1046
typedef void FNSTAMR3CALLBACKRESET(PVM pVM, void *pvSample);
1047
/** Pointer to a STAM sample reset callback. */
1048
typedef FNSTAMR3CALLBACKRESET *PFNSTAMR3CALLBACKRESET;
1051
* Prints the sample into the buffer.
1053
* @param pVM The VM handle.
1054
* @param pvSample The sample registered using STAMR3RegisterCallback.
1055
* @param pszBuf The buffer to print into.
1056
* @param cchBuf The size of the buffer.
1058
typedef void FNSTAMR3CALLBACKPRINT(PVM pVM, void *pvSample, char *pszBuf, size_t cchBuf);
1059
/** Pointer to a STAM sample print callback. */
1060
typedef FNSTAMR3CALLBACKPRINT *PFNSTAMR3CALLBACKPRINT;
1062
VMMR3DECL(int) STAMR3RegisterCallback(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1063
PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
1064
const char *pszDesc, const char *pszName, ...);
1065
VMMR3DECL(int) STAMR3RegisterCallbackV(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1066
PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
1067
const char *pszDesc, const char *pszName, va_list args);
1068
VMMR3DECL(int) STAMR3DeregisterU(PUVM pUVM, void *pvSample);
1069
VMMR3DECL(int) STAMR3Deregister(PVM pVM, void *pvSample);
1071
/** @def STAM_REL_DEREG
1072
* Deregisters a statistics sample if statistics are enabled.
1074
* @param pVM VM Handle.
1075
* @param pvSample Pointer to the sample.
1077
#define STAM_REL_DEREG(pVM, pvSample) \
1078
STAM_REL_STATS({ int rcStam = STAMR3Deregister(pVM, pvSample); AssertRC(rcStam); })
1080
* Deregisters a statistics sample if statistics are enabled.
1082
* @param pVM VM Handle.
1083
* @param pvSample Pointer to the sample.
1085
#define STAM_DEREG(pVM, pvSample) \
1086
STAM_STATS({ STAM_REL_DEREG(pVM, pvSample); })
1088
VMMR3DECL(int) STAMR3ResetU(PUVM pUVM, const char *pszPat);
1089
VMMR3DECL(int) STAMR3Reset(PVM pVM, const char *pszPat);
1090
VMMR3DECL(int) STAMR3SnapshotU(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc);
1091
VMMR3DECL(int) STAMR3Snapshot(PVM pVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc);
1092
VMMR3DECL(int) STAMR3SnapshotFreeU(PUVM pUVM, char *pszSnapshot);
1093
VMMR3DECL(int) STAMR3SnapshotFree(PVM pVM, char *pszSnapshot);
1094
VMMR3DECL(int) STAMR3DumpU(PUVM pUVM, const char *pszPat);
1095
VMMR3DECL(int) STAMR3Dump(PVM pVM, const char *pszPat);
1096
VMMR3DECL(int) STAMR3DumpToReleaseLogU(PUVM pUVM, const char *pszPat);
1097
VMMR3DECL(int) STAMR3DumpToReleaseLog(PVM pVM, const char *pszPat);
1098
VMMR3DECL(int) STAMR3PrintU(PUVM pUVM, const char *pszPat);
1099
VMMR3DECL(int) STAMR3Print(PVM pVM, const char *pszPat);
1102
* Callback function for STAMR3Enum().
1104
* @returns non-zero to halt the enumeration.
1106
* @param pszName The name of the sample.
1107
* @param enmType The type.
1108
* @param pvSample Pointer to the data. enmType indicates the format of this data.
1109
* @param enmUnit The unit.
1110
* @param enmVisibility The visibility.
1111
* @param pszDesc The description.
1112
* @param pvUser The pvUser argument given to STAMR3Enum().
1114
typedef DECLCALLBACK(int) FNSTAMR3ENUM(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
1115
STAMVISIBILITY enmVisiblity, const char *pszDesc, void *pvUser);
1116
/** Pointer to a FNSTAMR3ENUM(). */
1117
typedef FNSTAMR3ENUM *PFNSTAMR3ENUM;
1119
VMMR3DECL(int) STAMR3EnumU(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser);
1120
VMMR3DECL(int) STAMR3Enum(PVM pVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser);
1121
VMMR3DECL(const char *) STAMR3GetUnit(STAMUNIT enmUnit);