diff options
Diffstat (limited to '')
-rw-r--r-- | include/VBox/vmm/stam.h | 1376 |
1 files changed, 1376 insertions, 0 deletions
diff --git a/include/VBox/vmm/stam.h b/include/VBox/vmm/stam.h new file mode 100644 index 00000000..4c5764b4 --- /dev/null +++ b/include/VBox/vmm/stam.h @@ -0,0 +1,1376 @@ +/** @file + * STAM - Statistics Manager. + */ + +/* + * Copyright (C) 2006-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef VBOX_INCLUDED_vmm_stam_h +#define VBOX_INCLUDED_vmm_stam_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <VBox/types.h> +#include <iprt/stdarg.h> +#ifdef _MSC_VER +# if RT_MSC_PREREQ(RT_MSC_VER_VS2005) +# include <iprt/sanitized/intrin.h> +# endif +#endif +#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) +# include <iprt/asm-arm.h> +#endif + +RT_C_DECLS_BEGIN + +/** @defgroup grp_stam The Statistics Manager API + * @ingroup grp_vmm + * @{ + */ + +#if defined(VBOX_WITHOUT_RELEASE_STATISTICS) && defined(VBOX_WITH_STATISTICS) +# error "Both VBOX_WITHOUT_RELEASE_STATISTICS and VBOX_WITH_STATISTICS are defined! Make up your mind!" +#endif + + +/** @def STAM_GET_TS + * Gets the CPU timestamp counter. + * + * @param u64 The 64-bit variable which the timestamp shall be saved in. + */ +#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) +# define STAM_GET_TS(u64) do { (u64) = ASMReadTSC(); } while (0) +#elif defined(__GNUC__) +# if defined(RT_ARCH_X86) + /* This produces optimal assembler code for x86 but does not work for AMD64 ('A' means 'either rax or rdx') */ +# define STAM_GET_TS(u64) __asm__ __volatile__ ("rdtsc\n\t" : "=A" (u64)) +# elif defined(RT_ARCH_AMD64) +# define STAM_GET_TS(u64) \ + do { uint64_t low; uint64_t high; \ + __asm__ __volatile__ ("rdtsc\n\t" : "=a"(low), "=d"(high)); \ + (u64) = ((high << 32) | low); \ + } while (0) +# endif +#else +# if RT_MSC_PREREQ(RT_MSC_VER_VS2005) +# pragma intrinsic(__rdtsc) +# define STAM_GET_TS(u64) \ + do { (u64) = __rdtsc(); } while (0) +# else +# define STAM_GET_TS(u64) \ + do { \ + uint64_t u64Tmp; \ + __asm { \ + __asm rdtsc \ + __asm mov dword ptr [u64Tmp], eax \ + __asm mov dword ptr [u64Tmp + 4], edx \ + } \ + (u64) = u64Tmp; \ + } while (0) +# endif +#endif + + +/** @def STAM_REL_STATS + * Code for inclusion only when VBOX_WITH_STATISTICS is defined. + * @param code A code block enclosed in {}. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_STATS(code) do code while(0) +#else +# define STAM_REL_STATS(code) do {} while(0) +#endif +/** @def STAM_STATS + * Code for inclusion only when VBOX_WITH_STATISTICS is defined. + * @param code A code block enclosed in {}. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_STATS(code) STAM_REL_STATS(code) +#else +# define STAM_STATS(code) do {} while(0) +#endif + + +/** + * Sample type. + */ +typedef enum STAMTYPE +{ + /** Invalid entry. */ + STAMTYPE_INVALID = 0, + /** Generic counter. */ + STAMTYPE_COUNTER, + /** Profiling of an function. */ + STAMTYPE_PROFILE, + /** Profiling of an operation. */ + STAMTYPE_PROFILE_ADV, + /** Ratio of A to B, uint32_t types. Not reset. */ + STAMTYPE_RATIO_U32, + /** Ratio of A to B, uint32_t types. Reset both to 0. */ + STAMTYPE_RATIO_U32_RESET, + /** Callback. */ + STAMTYPE_CALLBACK, + /** Generic unsigned 8-bit value. Not reset. */ + STAMTYPE_U8, + /** Generic unsigned 8-bit value. Reset to 0. */ + STAMTYPE_U8_RESET, + /** Generic hexadecimal unsigned 8-bit value. Not reset. */ + STAMTYPE_X8, + /** Generic hexadecimal unsigned 8-bit value. Reset to 0. */ + STAMTYPE_X8_RESET, + /** Generic unsigned 16-bit value. Not reset. */ + STAMTYPE_U16, + /** Generic unsigned 16-bit value. Reset to 0. */ + STAMTYPE_U16_RESET, + /** Generic hexadecimal unsigned 16-bit value. Not reset. */ + STAMTYPE_X16, + /** Generic hexadecimal unsigned 16-bit value. Reset to 0. */ + STAMTYPE_X16_RESET, + /** Generic unsigned 32-bit value. Not reset. */ + STAMTYPE_U32, + /** Generic unsigned 32-bit value. Reset to 0. */ + STAMTYPE_U32_RESET, + /** Generic hexadecimal unsigned 32-bit value. Not reset. */ + STAMTYPE_X32, + /** Generic hexadecimal unsigned 32-bit value. Reset to 0. */ + STAMTYPE_X32_RESET, + /** Generic unsigned 64-bit value. Not reset. */ + STAMTYPE_U64, + /** Generic unsigned 64-bit value. Reset to 0. */ + STAMTYPE_U64_RESET, + /** Generic hexadecimal unsigned 64-bit value. Not reset. */ + STAMTYPE_X64, + /** Generic hexadecimal unsigned 64-bit value. Reset to 0. */ + STAMTYPE_X64_RESET, + /** Generic boolean value. Not reset. */ + STAMTYPE_BOOL, + /** Generic boolean value. Reset to false. */ + STAMTYPE_BOOL_RESET, + /** The end (exclusive). */ + STAMTYPE_END +} STAMTYPE; + +/** + * Sample visibility type. + */ +typedef enum STAMVISIBILITY +{ + /** Invalid entry. */ + STAMVISIBILITY_INVALID = 0, + /** Always visible. */ + STAMVISIBILITY_ALWAYS, + /** Only visible when used (/hit). */ + STAMVISIBILITY_USED, + /** Not visible in the GUI. */ + STAMVISIBILITY_NOT_GUI, + /** The end (exclusive). */ + STAMVISIBILITY_END +} STAMVISIBILITY; + +/** + * Sample unit. + */ +typedef enum STAMUNIT +{ + /** Invalid entry .*/ + STAMUNIT_INVALID = 0, + /** No unit. */ + STAMUNIT_NONE, + /** Number of calls. */ + STAMUNIT_CALLS, + /** Count of whatever. */ + STAMUNIT_COUNT, + /** Count of bytes. */ + STAMUNIT_BYTES, + /** Count of bytes per call. */ + STAMUNIT_BYTES_PER_CALL, + /** Count of bytes. */ + STAMUNIT_PAGES, + /** Error count. */ + STAMUNIT_ERRORS, + /** Number of occurences. */ + STAMUNIT_OCCURENCES, + /** Ticks. */ + STAMUNIT_TICKS, + /** Ticks per call. */ + STAMUNIT_TICKS_PER_CALL, + /** Ticks per occurence. */ + STAMUNIT_TICKS_PER_OCCURENCE, + /** Ratio of good vs. bad. */ + STAMUNIT_GOOD_BAD, + /** Megabytes. */ + STAMUNIT_MEGABYTES, + /** Kilobytes. */ + STAMUNIT_KILOBYTES, + /** Nano seconds. */ + STAMUNIT_NS, + /** Nanoseconds per call. */ + STAMUNIT_NS_PER_CALL, + /** Nanoseconds per call. */ + STAMUNIT_NS_PER_OCCURENCE, + /** Percentage. */ + STAMUNIT_PCT, + /** Hertz. */ + STAMUNIT_HZ, + /** The end (exclusive). */ + STAMUNIT_END +} STAMUNIT; + +/** @name STAM_REFRESH_GRP_XXX - STAM refresh groups + * @{ */ +#define STAM_REFRESH_GRP_NONE UINT8_MAX +#define STAM_REFRESH_GRP_GVMM 0 +#define STAM_REFRESH_GRP_GMM 1 +#define STAM_REFRESH_GRP_NEM 2 +/** @} */ + + +/** @def STAM_REL_U8_INC + * Increments a uint8_t sample by one. + * + * @param pCounter Pointer to the uint8_t variable to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U8_INC(pCounter) \ + do { ++*(pCounter); } while (0) +#else +# define STAM_REL_U8_INC(pCounter) do { } while (0) +#endif +/** @def STAM_U8_INC + * Increments a uint8_t sample by one. + * + * @param pCounter Pointer to the uint8_t variable to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U8_INC(pCounter) STAM_REL_U8_INC(pCounter) +#else +# define STAM_U8_INC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_U8_DEC + * Decrements a uint8_t sample by one. + * + * @param pCounter Pointer to the uint8_t variable to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U8_DEC(pCounter) \ + do { --*(pCounter); } while (0) +#else +# define STAM_REL_U8_DEC(pCounter) do { } while (0) +#endif +/** @def STAM_U8_DEC + * Decrements a uint8_t sample by one. + * + * @param pCounter Pointer to the uint8_t variable to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U8_DEC(pCounter) STAM_REL_U8_DEC(pCounter) +#else +# define STAM_U8_DEC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_U8_ADD + * Increments a uint8_t sample by a value. + * + * @param pCounter Pointer to the uint8_t variable to operate on. + * @param Addend The value to add. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U8_ADD(pCounter, Addend) \ + do { *(pCounter) += (Addend); } while (0) +#else +# define STAM_REL_U8_ADD(pCounter, Addend) do { } while (0) +#endif +/** @def STAM_U8_ADD + * Increments a uint8_t sample by a value. + * + * @param pCounter Pointer to the uint8_t variable to operate on. + * @param Addend The value to add. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U8_ADD(pCounter, Addend) STAM_REL_U8_ADD(pCounter, Addend +#else +# define STAM_U8_ADD(pCounter, Addend) do { } while (0) +#endif + + +/** @def STAM_REL_U16_INC + * Increments a uint16_t sample by one. + * + * @param pCounter Pointer to the uint16_t variable to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U16_INC(pCounter) \ + do { ++*(pCounter); } while (0) +#else +# define STAM_REL_U16_INC(pCounter) do { } while (0) +#endif +/** @def STAM_U16_INC + * Increments a uint16_t sample by one. + * + * @param pCounter Pointer to the uint16_t variable to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U16_INC(pCounter) STAM_REL_U16_INC(pCounter) +#else +# define STAM_U16_INC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_U16_DEC + * Decrements a uint16_t sample by one. + * + * @param pCounter Pointer to the uint16_t variable to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U16_DEC(pCounter) \ + do { --*(pCounter); } while (0) +#else +# define STAM_REL_U16_DEC(pCounter) do { } while (0) +#endif +/** @def STAM_U16_DEC + * Decrements a uint16_t sample by one. + * + * @param pCounter Pointer to the uint16_t variable to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U16_DEC(pCounter) STAM_REL_U16_DEC(pCounter) +#else +# define STAM_U16_DEC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_U16_ADD + * Increments a uint16_t sample by a value. + * + * @param pCounter Pointer to the uint16_t variable to operate on. + * @param Addend The value to add. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U16_ADD(pCounter, Addend) \ + do { *(pCounter) += (Addend); } while (0) +#else +# define STAM_REL_U16_ADD(pCounter, Addend) do { } while (0) +#endif +/** @def STAM_U16_ADD + * Increments a uint16_t sample by a value. + * + * @param pCounter Pointer to the uint16_t variable to operate on. + * @param Addend The value to add. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U16_ADD(pCounter, Addend) STAM_REL_U16_ADD(pCounter, Addend) +#else +# define STAM_U16_ADD(pCounter, Addend) do { } while (0) +#endif + + +/** @def STAM_REL_U32_INC + * Increments a uint32_t sample by one. + * + * @param pCounter Pointer to the uint32_t variable to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U32_INC(pCounter) \ + do { ++*(pCounter); } while (0) +#else +# define STAM_REL_U32_INC(pCounter) do { } while (0) +#endif +/** @def STAM_U32_INC + * Increments a uint32_t sample by one. + * + * @param pCounter Pointer to the uint32_t variable to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U32_INC(pCounter) STAM_REL_U32_INC(pCounter) +#else +# define STAM_U32_INC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_U32_DEC + * Decrements a uint32_t sample by one. + * + * @param pCounter Pointer to the uint32_t variable to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U32_DEC(pCounter) \ + do { --*(pCounter); } while (0) +#else +# define STAM_REL_U32_DEC(pCounter) do { } while (0) +#endif +/** @def STAM_U32_DEC + * Decrements a uint32_t sample by one. + * + * @param pCounter Pointer to the uint32_t variable to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U32_DEC(pCounter) STAM_REL_U32_DEC(pCounter) +#else +# define STAM_U32_DEC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_U32_ADD + * Increments a uint32_t sample by value. + * + * @param pCounter Pointer to the uint32_t variable to operate on. + * @param Addend The value to add. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U32_ADD(pCounter, Addend) \ + do { *(pCounter) += (Addend); } while (0) +#else +# define STAM_REL_U32_ADD(pCounter, Addend) do { } while (0) +#endif +/** @def STAM_U32_ADD + * Increments a uint32_t sample by value. + * + * @param pCounter Pointer to the uint32_t variable to operate on. + * @param Addend The value to add. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U32_ADD(pCounter, Addend) STAM_REL_U32_ADD(pCounter, Addend) +#else +# define STAM_U32_ADD(pCounter, Addend) do { } while (0) +#endif + + +/** @def STAM_REL_U64_INC + * Increments a uint64_t sample by one. + * + * @param pCounter Pointer to the uint64_t variable to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U64_INC(pCounter) \ + do { ++*(pCounter); } while (0) +#else +# define STAM_REL_U64_INC(pCounter) do { } while (0) +#endif +/** @def STAM_U64_INC + * Increments a uint64_t sample by one. + * + * @param pCounter Pointer to the uint64_t variable to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U64_INC(pCounter) STAM_REL_U64_INC(pCounter) +#else +# define STAM_U64_INC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_U64_DEC + * Decrements a uint64_t sample by one. + * + * @param pCounter Pointer to the uint64_t variable to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U64_DEC(pCounter) \ + do { --*(pCounter); } while (0) +#else +# define STAM_REL_U64_DEC(pCounter) do { } while (0) +#endif +/** @def STAM_U64_DEC + * Decrements a uint64_t sample by one. + * + * @param pCounter Pointer to the uint64_t variable to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U64_DEC(pCounter) STAM_REL_U64_DEC(pCounter) +#else +# define STAM_U64_DEC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_U64_ADD + * Increments a uint64_t sample by a value. + * + * @param pCounter Pointer to the uint64_t variable to operate on. + * @param Addend The value to add. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_U64_ADD(pCounter, Addend) \ + do { *(pCounter) += (Addend); } while (0) +#else +# define STAM_REL_U64_ADD(pCounter, Addend) do { } while (0) +#endif +/** @def STAM_U64_ADD + * Increments a uint64_t sample by a value. + * + * @param pCounter Pointer to the uint64_t variable to operate on. + * @param Addend The value to add. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_U64_ADD(pCounter, Addend) STAM_REL_U64_ADD(pCounter, Addend) +#else +# define STAM_U64_ADD(pCounter, Addend) do { } while (0) +#endif + + +/** + * Counter sample - STAMTYPE_COUNTER. + */ +typedef struct STAMCOUNTER +{ + /** The current count. */ + volatile uint64_t c; +} STAMCOUNTER; +/** Pointer to a counter. */ +typedef STAMCOUNTER *PSTAMCOUNTER; +/** Pointer to a const counter. */ +typedef const STAMCOUNTER *PCSTAMCOUNTER; + + +/** @def STAM_REL_COUNTER_INC + * Increments a counter sample by one. + * + * @param pCounter Pointer to the STAMCOUNTER structure to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_COUNTER_INC(pCounter) \ + do { (pCounter)->c++; } while (0) +#else +# define STAM_REL_COUNTER_INC(pCounter) do { } while (0) +#endif +/** @def STAM_COUNTER_INC + * Increments a counter sample by one. + * + * @param pCounter Pointer to the STAMCOUNTER structure to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_COUNTER_INC(pCounter) STAM_REL_COUNTER_INC(pCounter) +#else +# define STAM_COUNTER_INC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_COUNTER_DEC + * Decrements a counter sample by one. + * + * @param pCounter Pointer to the STAMCOUNTER structure to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_COUNTER_DEC(pCounter) \ + do { (pCounter)->c--; } while (0) +#else +# define STAM_REL_COUNTER_DEC(pCounter) do { } while (0) +#endif +/** @def STAM_COUNTER_DEC + * Decrements a counter sample by one. + * + * @param pCounter Pointer to the STAMCOUNTER structure to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_COUNTER_DEC(pCounter) STAM_REL_COUNTER_DEC(pCounter) +#else +# define STAM_COUNTER_DEC(pCounter) do { } while (0) +#endif + + +/** @def STAM_REL_COUNTER_ADD + * Increments a counter sample by a value. + * + * @param pCounter Pointer to the STAMCOUNTER structure to operate on. + * @param Addend The value to add to the counter. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_COUNTER_ADD(pCounter, Addend) \ + do { (pCounter)->c += (Addend); } while (0) +#else +# define STAM_REL_COUNTER_ADD(pCounter, Addend) do { } while (0) +#endif +/** @def STAM_COUNTER_ADD + * Increments a counter sample by a value. + * + * @param pCounter Pointer to the STAMCOUNTER structure to operate on. + * @param Addend The value to add to the counter. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_COUNTER_ADD(pCounter, Addend) STAM_REL_COUNTER_ADD(pCounter, Addend) +#else +# define STAM_COUNTER_ADD(pCounter, Addend) do { } while (0) +#endif + + +/** @def STAM_REL_COUNTER_RESET + * Resets the statistics sample. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_COUNTER_RESET(pCounter) do { (pCounter)->c = 0; } while (0) +#else +# define STAM_REL_COUNTER_RESET(pCounter) do { } while (0) +#endif +/** @def STAM_COUNTER_RESET + * Resets the statistics sample. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_COUNTER_RESET(pCounter) STAM_REL_COUNTER_RESET(pCounter) +#else +# define STAM_COUNTER_RESET(pCounter) do { } while (0) +#endif + + + +/** + * Profiling sample - STAMTYPE_PROFILE. + */ +typedef struct STAMPROFILE +{ + /** Number of periods. */ + volatile uint64_t cPeriods; + /** Total count of ticks. */ + volatile uint64_t cTicks; + /** Maximum tick count during a sampling. */ + volatile uint64_t cTicksMax; + /** Minimum tick count during a sampling. */ + volatile uint64_t cTicksMin; +} STAMPROFILE; +/** Pointer to a profile sample. */ +typedef STAMPROFILE *PSTAMPROFILE; +/** Pointer to a const profile sample. */ +typedef const STAMPROFILE *PCSTAMPROFILE; + + +/** @def STAM_REL_PROFILE_ADD_PERIOD + * Adds a period. + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param cTicksInPeriod The number of tick (or whatever) of the preiod + * being added. This is only referenced once. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) \ + do { \ + uint64_t const StamPrefix_cTicks = (cTicksInPeriod); \ + (pProfile)->cTicks += StamPrefix_cTicks; \ + (pProfile)->cPeriods++; \ + if ((pProfile)->cTicksMax < StamPrefix_cTicks) \ + (pProfile)->cTicksMax = StamPrefix_cTicks; \ + if ((pProfile)->cTicksMin > StamPrefix_cTicks) \ + (pProfile)->cTicksMin = StamPrefix_cTicks; \ + } while (0) +#else +# define STAM_REL_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) do { } while (0) +#endif +/** @def STAM_PROFILE_ADD_PERIOD + * Adds a period. + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param cTicksInPeriod The number of tick (or whatever) of the preiod + * being added. This is only referenced once. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) STAM_REL_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) +#else +# define STAM_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) do { } while (0) +#endif + + +/** @def STAM_REL_PROFILE_START + * Samples the start time of a profiling period. + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + * + * @remarks Declears a stack variable that will be used by related macros. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_START(pProfile, Prefix) \ + uint64_t Prefix##_tsStart; \ + STAM_GET_TS(Prefix##_tsStart) +#else +# define STAM_REL_PROFILE_START(pProfile, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_START + * Samples the start time of a profiling period. + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + * + * @remarks Declears a stack variable that will be used by related macros. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_START(pProfile, Prefix) STAM_REL_PROFILE_START(pProfile, Prefix) +#else +# define STAM_PROFILE_START(pProfile, Prefix) do { } while (0) +#endif + +/** @def STAM_REL_PROFILE_STOP + * Samples the stop time of a profiling period and updates the sample. + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_STOP(pProfile, Prefix) \ + do { \ + uint64_t Prefix##_cTicks; \ + STAM_GET_TS(Prefix##_cTicks); \ + Prefix##_cTicks -= Prefix##_tsStart; \ + (pProfile)->cTicks += Prefix##_cTicks; \ + (pProfile)->cPeriods++; \ + if ((pProfile)->cTicksMax < Prefix##_cTicks) \ + (pProfile)->cTicksMax = Prefix##_cTicks; \ + if ((pProfile)->cTicksMin > Prefix##_cTicks) \ + (pProfile)->cTicksMin = Prefix##_cTicks; \ + } while (0) +#else +# define STAM_REL_PROFILE_STOP(pProfile, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_STOP + * Samples the stop time of a profiling period and updates the sample. + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_STOP(pProfile, Prefix) STAM_REL_PROFILE_STOP(pProfile, Prefix) +#else +# define STAM_PROFILE_STOP(pProfile, Prefix) do { } while (0) +#endif + + +/** @def STAM_REL_PROFILE_STOP_EX + * Samples the stop time of a profiling period and updates both the sample + * and an attribution sample. + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param pProfile2 Pointer to the STAMPROFILE structure which this + * interval should be attributed to as well. This may be NULL. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) \ + do { \ + uint64_t Prefix##_cTicks; \ + STAM_GET_TS(Prefix##_cTicks); \ + Prefix##_cTicks -= Prefix##_tsStart; \ + (pProfile)->cTicks += Prefix##_cTicks; \ + (pProfile)->cPeriods++; \ + if ((pProfile)->cTicksMax < Prefix##_cTicks) \ + (pProfile)->cTicksMax = Prefix##_cTicks; \ + if ((pProfile)->cTicksMin > Prefix##_cTicks) \ + (pProfile)->cTicksMin = Prefix##_cTicks; \ + \ + if ((pProfile2)) \ + { \ + (pProfile2)->cTicks += Prefix##_cTicks; \ + (pProfile2)->cPeriods++; \ + if ((pProfile2)->cTicksMax < Prefix##_cTicks) \ + (pProfile2)->cTicksMax = Prefix##_cTicks; \ + if ((pProfile2)->cTicksMin > Prefix##_cTicks) \ + (pProfile2)->cTicksMin = Prefix##_cTicks; \ + } \ + } while (0) +#else +# define STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_STOP_EX + * Samples the stop time of a profiling period and updates both the sample + * and an attribution sample. + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param pProfile2 Pointer to the STAMPROFILE structure which this + * interval should be attributed to as well. This may be NULL. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) +#else +# define STAM_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) do { } while (0) +#endif + + +/** @def STAM_REL_PROFILE_STOP_START + * Stops one profile counter (if running) and starts another one. + * + * @param pProfile1 Pointer to the STAMPROFILE structure to stop. + * @param pProfile2 Pointer to the STAMPROFILE structure to start. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_STOP_START(pProfile1, pProfile2, Prefix) \ + do { \ + uint64_t Prefix##_tsStop; \ + STAM_GET_TS(Prefix##_tsStop); \ + STAM_REL_PROFILE_ADD_PERIOD(pProfile1, Prefix##_tsStop - Prefix##_tsStart); \ + Prefix##_tsStart = Prefix##_tsStop; \ + } while (0) +#else +# define STAM_REL_PROFILE_STOP_START(pProfile1, pProfile2, Prefix) \ + do { } while (0) +#endif +/** @def STAM_PROFILE_STOP_START + * Samples the stop time of a profiling period (if running) and updates the + * sample. + * + * @param pProfile1 Pointer to the STAMPROFILE structure to stop. + * @param pProfile2 Pointer to the STAMPROFILE structure to start. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_STOP_START(pProfile1, pProfile2, Prefix) \ + STAM_REL_PROFILE_STOP_START(pProfile1, pProfile2, Prefix) +#else +# define STAM_PROFILE_STOP_START(pProfile1, pProfile2, Prefix) \ + do { } while (0) +#endif + + +/** @def STAM_REL_PROFILE_START_NS + * Samples the start time of a profiling period, using RTTimeNanoTS(). + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + * + * @remarks Declears a stack variable that will be used by related macros. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_START_NS(pProfile, Prefix) \ + uint64_t const Prefix##_tsStart = RTTimeNanoTS() +#else +# define STAM_REL_PROFILE_START_NS(pProfile, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_START_NS + * Samples the start time of a profiling period, using RTTimeNanoTS(). + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + * + * @remarks Declears a stack variable that will be used by related macros. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_START_NS(pProfile, Prefix) STAM_REL_PROFILE_START_NS(pProfile, Prefix) +#else +# define STAM_PROFILE_START_NS(pProfile, Prefix) do { } while (0) +#endif + +/** @def STAM_REL_PROFILE_STOP_NS + * Samples the stop time of a profiling period and updates the sample, using + * RTTimeNanoTS(). + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_STOP_NS(pProfile, Prefix) \ + STAM_REL_PROFILE_ADD_PERIOD(pProfile, RTTimeNanoTS() - Prefix##_tsStart) +#else +# define STAM_REL_PROFILE_STOP_NS(pProfile, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_STOP_NS + * Samples the stop time of a profiling period and updates the sample, using + * RTTimeNanoTS(). + * + * @param pProfile Pointer to the STAMPROFILE structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_STOP_NS(pProfile, Prefix) STAM_REL_PROFILE_STOP_NS(pProfile, Prefix) +#else +# define STAM_PROFILE_STOP_NS(pProfile, Prefix) do { } while (0) +#endif + + +/** + * Advanced profiling sample - STAMTYPE_PROFILE_ADV. + * + * Identical to a STAMPROFILE sample, but the start timestamp + * is stored after the STAMPROFILE structure so the sampling + * can start and stop in different functions. + */ +typedef struct STAMPROFILEADV +{ + /** The STAMPROFILE core. */ + STAMPROFILE Core; + /** The start timestamp. */ + volatile uint64_t tsStart; +} STAMPROFILEADV; +/** Pointer to a advanced profile sample. */ +typedef STAMPROFILEADV *PSTAMPROFILEADV; +/** Pointer to a const advanced profile sample. */ +typedef const STAMPROFILEADV *PCSTAMPROFILEADV; + + +/** @def STAM_REL_PROFILE_ADV_START + * Samples the start time of a profiling period. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix) \ + STAM_GET_TS((pProfileAdv)->tsStart) +#else +# define STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_ADV_START + * Samples the start time of a profiling period. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_ADV_START(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix) +#else +# define STAM_PROFILE_ADV_START(pProfileAdv, Prefix) do { } while (0) +#endif + + +/** @def STAM_REL_PROFILE_ADV_STOP + * Samples the stop time of a profiling period (if running) and updates the + * sample. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix) \ + do { \ + if ((pProfileAdv)->tsStart) \ + { \ + uint64_t Prefix##_cTicks; \ + STAM_GET_TS(Prefix##_cTicks); \ + Prefix##_cTicks -= (pProfileAdv)->tsStart; \ + (pProfileAdv)->tsStart = 0; \ + (pProfileAdv)->Core.cTicks += Prefix##_cTicks; \ + (pProfileAdv)->Core.cPeriods++; \ + if ((pProfileAdv)->Core.cTicksMax < Prefix##_cTicks) \ + (pProfileAdv)->Core.cTicksMax = Prefix##_cTicks; \ + if ((pProfileAdv)->Core.cTicksMin > Prefix##_cTicks) \ + (pProfileAdv)->Core.cTicksMin = Prefix##_cTicks; \ + } \ + } while (0) +#else +# define STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_ADV_STOP + * Samples the stop time of a profiling period (if running) and updates the + * sample. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_ADV_STOP(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix) +#else +# define STAM_PROFILE_ADV_STOP(pProfileAdv, Prefix) do { } while (0) +#endif + + +/** @def STAM_REL_PROFILE_ADV_STOP_START + * Stops one profile counter (if running) and starts another one. + * + * @param pProfileAdv1 Pointer to the STAMPROFILEADV structure to stop. + * @param pProfileAdv2 Pointer to the STAMPROFILEADV structure to start. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \ + do { \ + uint64_t Prefix##_cTicks; \ + STAM_GET_TS(Prefix##_cTicks); \ + (pProfileAdv2)->tsStart = Prefix##_cTicks; \ + if ((pProfileAdv1)->tsStart) \ + { \ + Prefix##_cTicks -= (pProfileAdv1)->tsStart; \ + (pProfileAdv1)->tsStart = 0; \ + (pProfileAdv1)->Core.cTicks += Prefix##_cTicks; \ + (pProfileAdv1)->Core.cPeriods++; \ + if ((pProfileAdv1)->Core.cTicksMax < Prefix##_cTicks) \ + (pProfileAdv1)->Core.cTicksMax = Prefix##_cTicks; \ + if ((pProfileAdv1)->Core.cTicksMin > Prefix##_cTicks) \ + (pProfileAdv1)->Core.cTicksMin = Prefix##_cTicks; \ + } \ + } while (0) +#else +# define STAM_REL_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \ + do { } while (0) +#endif +/** @def STAM_PROFILE_ADV_STOP_START + * Samples the stop time of a profiling period (if running) and updates the + * sample. + * + * @param pProfileAdv1 Pointer to the STAMPROFILEADV structure to stop. + * @param pProfileAdv2 Pointer to the STAMPROFILEADV structure to start. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \ + STAM_REL_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) +#else +# define STAM_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \ + do { } while (0) +#endif + + +/** @def STAM_REL_PROFILE_ADV_SUSPEND + * Suspends the sampling for a while. This can be useful to exclude parts + * covered by other samples without screwing up the count, and average+min times. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param Prefix Identifier prefix used to internal variables. The prefix + * must match that of the resume one since it stores the + * suspend time in a stack variable. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) \ + uint64_t Prefix##_tsSuspend; \ + STAM_GET_TS(Prefix##_tsSuspend) +#else +# define STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_ADV_SUSPEND + * Suspends the sampling for a while. This can be useful to exclude parts + * covered by other samples without screwing up the count, and average+min times. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param Prefix Identifier prefix used to internal variables. The prefix + * must match that of the resume one since it stores the + * suspend time in a stack variable. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) +#else +# define STAM_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) do { } while (0) +#endif + + +/** @def STAM_REL_PROFILE_ADV_RESUME + * Counter to STAM_REL_PROFILE_ADV_SUSPEND. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param Prefix Identifier prefix used to internal variables. This must + * match the one used with the SUSPEND! + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix) \ + do { \ + uint64_t Prefix##_tsNow; \ + STAM_GET_TS(Prefix##_tsNow); \ + (pProfileAdv)->tsStart += Prefix##_tsNow - Prefix##_tsSuspend; \ + } while (0) +#else +# define STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_ADV_RESUME + * Counter to STAM_PROFILE_ADV_SUSPEND. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param Prefix Identifier prefix used to internal variables. This must + * match the one used with the SUSPEND! + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_ADV_RESUME(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix) +#else +# define STAM_PROFILE_ADV_RESUME(pProfileAdv, Prefix) do { } while (0) +#endif + + +/** @def STAM_REL_PROFILE_ADV_STOP_EX + * Samples the stop time of a profiling period (if running) and updates both + * the sample and an attribution sample. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param pProfile2 Pointer to the STAMPROFILE structure which this + * interval should be attributed to as well. This may be NULL. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) \ + do { \ + if ((pProfileAdv)->tsStart) \ + { \ + uint64_t Prefix##_cTicks; \ + STAM_GET_TS(Prefix##_cTicks); \ + Prefix##_cTicks -= (pProfileAdv)->tsStart; \ + (pProfileAdv)->tsStart = 0; \ + (pProfileAdv)->Core.cTicks += Prefix##_cTicks; \ + (pProfileAdv)->Core.cPeriods++; \ + if ((pProfileAdv)->Core.cTicksMax < Prefix##_cTicks) \ + (pProfileAdv)->Core.cTicksMax = Prefix##_cTicks; \ + if ((pProfileAdv)->Core.cTicksMin > Prefix##_cTicks) \ + (pProfileAdv)->Core.cTicksMin = Prefix##_cTicks; \ + if ((pProfile2)) \ + { \ + (pProfile2)->cTicks += Prefix##_cTicks; \ + (pProfile2)->cPeriods++; \ + if ((pProfile2)->cTicksMax < Prefix##_cTicks) \ + (pProfile2)->cTicksMax = Prefix##_cTicks; \ + if ((pProfile2)->cTicksMin > Prefix##_cTicks) \ + (pProfile2)->cTicksMin = Prefix##_cTicks; \ + } \ + } \ + } while (0) +#else +# define STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) do { } while (0) +#endif +/** @def STAM_PROFILE_ADV_STOP_EX + * Samples the stop time of a profiling period (if running) and updates both + * the sample and an attribution sample. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + * @param pProfile2 Pointer to the STAMPROFILE structure which this + * interval should be attributed to as well. This may be NULL. + * @param Prefix Identifier prefix used to internal variables. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) +#else +# define STAM_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) do { } while (0) +#endif + +/** @def STAM_REL_PROFILE_ADV_IS_RUNNING + * Checks if it is running. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_ADV_IS_RUNNING(pProfileAdv) (pProfileAdv)->tsStart +#else +# define STAM_REL_PROFILE_ADV_IS_RUNNING(pProfileAdv) (false) +#endif +/** @def STAM_PROFILE_ADV_IS_RUNNING + * Checks if it is running. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_ADV_IS_RUNNING(pProfileAdv) STAM_REL_PROFILE_ADV_IS_RUNNING(pProfileAdv) +#else +# define STAM_PROFILE_ADV_IS_RUNNING(pProfileAdv) (false) +#endif + +/** @def STAM_REL_PROFILE_ADV_SET_STOPPED + * Marks the profile counter as stopped. + * + * This is for avoiding screwups in twisty code. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + */ +#ifndef VBOX_WITHOUT_RELEASE_STATISTICS +# define STAM_REL_PROFILE_ADV_SET_STOPPED(pProfileAdv) do { (pProfileAdv)->tsStart = 0; } while (0) +#else +# define STAM_REL_PROFILE_ADV_SET_STOPPED(pProfileAdv) do { } while (0) +#endif +/** @def STAM_PROFILE_ADV_SET_STOPPED + * Marks the profile counter as stopped. + * + * This is for avoiding screwups in twisty code. + * + * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on. + */ +#ifdef VBOX_WITH_STATISTICS +# define STAM_PROFILE_ADV_SET_STOPPED(pProfileAdv) STAM_REL_PROFILE_ADV_SET_STOPPED(pProfileAdv) +#else +# define STAM_PROFILE_ADV_SET_STOPPED(pProfileAdv) do { } while (0) +#endif + + +/** + * Ratio of A to B, uint32_t types. + * @remark Use STAM_STATS or STAM_REL_STATS for modifying A & B values. + */ +typedef struct STAMRATIOU32 +{ + /** Sample A. */ + uint32_t volatile u32A; + /** Sample B. */ + uint32_t volatile u32B; +} STAMRATIOU32; +/** Pointer to a uint32_t ratio. */ +typedef STAMRATIOU32 *PSTAMRATIOU32; +/** Pointer to const a uint32_t ratio. */ +typedef const STAMRATIOU32 *PCSTAMRATIOU32; + + + + +/** @defgroup grp_stam_r3 The STAM Host Context Ring 3 API + * @{ + */ + +VMMR3DECL(int) STAMR3InitUVM(PUVM pUVM); +VMMR3DECL(void) STAMR3TermUVM(PUVM pUVM); +VMMR3DECL(int) STAMR3RegisterU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, + const char *pszName, STAMUNIT enmUnit, const char *pszDesc); +VMMR3DECL(int) STAMR3Register(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, + const char *pszName, STAMUNIT enmUnit, const char *pszDesc); + +/** @def STAM_REL_REG + * Registers a statistics sample. + * + * @param pVM The cross context VM structure. + * @param pvSample Pointer to the sample. + * @param enmType Sample type. This indicates what pvSample is pointing at. + * @param pszName Sample name. The name is on this form "/<component>/<sample>". + * Further nesting is possible. + * @param enmUnit Sample unit. + * @param pszDesc Sample description. + */ +#define STAM_REL_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \ + STAM_REL_STATS({ int rcStam = STAMR3Register(pVM, pvSample, enmType, STAMVISIBILITY_ALWAYS, pszName, enmUnit, pszDesc); \ + AssertRC(rcStam); }) +/** @def STAM_REG + * Registers a statistics sample if statistics are enabled. + * + * @param pVM The cross context VM structure. + * @param pvSample Pointer to the sample. + * @param enmType Sample type. This indicates what pvSample is pointing at. + * @param pszName Sample name. The name is on this form "/<component>/<sample>". + * Further nesting is possible. + * @param enmUnit Sample unit. + * @param pszDesc Sample description. + */ +#define STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \ + STAM_STATS({STAM_REL_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc);}) + +/** @def STAM_REL_REG_USED + * Registers a statistics sample which only shows when used. + * + * @param pVM The cross context VM structure. + * @param pvSample Pointer to the sample. + * @param enmType Sample type. This indicates what pvSample is pointing at. + * @param pszName Sample name. The name is on this form "/<component>/<sample>". + * Further nesting is possible. + * @param enmUnit Sample unit. + * @param pszDesc Sample description. + */ +#define STAM_REL_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \ + STAM_REL_STATS({ int rcStam = STAMR3Register(pVM, pvSample, enmType, STAMVISIBILITY_USED, pszName, enmUnit, pszDesc); \ + AssertRC(rcStam);}) +/** @def STAM_REG_USED + * Registers a statistics sample which only shows when used, if statistics are enabled. + * + * @param pVM The cross context VM structure. + * @param pvSample Pointer to the sample. + * @param enmType Sample type. This indicates what pvSample is pointing at. + * @param pszName Sample name. The name is on this form "/<component>/<sample>". + * Further nesting is possible. + * @param enmUnit Sample unit. + * @param pszDesc Sample description. + */ +#define STAM_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \ + STAM_STATS({ STAM_REL_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc); }) + +VMMR3DECL(int) STAMR3RegisterFU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, + const char *pszDesc, const char *pszName, ...) RT_IPRT_FORMAT_ATTR(7, 8); +VMMR3DECL(int) STAMR3RegisterF(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, + const char *pszDesc, const char *pszName, ...) RT_IPRT_FORMAT_ATTR(7, 8); +VMMR3DECL(int) STAMR3RegisterVU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, + const char *pszDesc, const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(7, 0); +VMMR3DECL(int) STAMR3RegisterV(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, + const char *pszDesc, const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(7, 0); + +/** + * Resets the sample. + * @param pVM The cross context VM structure. + * @param pvSample The sample registered using STAMR3RegisterCallback. + */ +typedef DECLCALLBACKTYPE(void, FNSTAMR3CALLBACKRESET,(PVM pVM, void *pvSample)); +/** Pointer to a STAM sample reset callback. */ +typedef FNSTAMR3CALLBACKRESET *PFNSTAMR3CALLBACKRESET; + +/** + * Prints the sample into the buffer. + * + * @param pVM The cross context VM structure. + * @param pvSample The sample registered using STAMR3RegisterCallback. + * @param pszBuf The buffer to print into. + * @param cchBuf The size of the buffer. + */ +typedef DECLCALLBACKTYPE(void, FNSTAMR3CALLBACKPRINT,(PVM pVM, void *pvSample, char *pszBuf, size_t cchBuf)); +/** Pointer to a STAM sample print callback. */ +typedef FNSTAMR3CALLBACKPRINT *PFNSTAMR3CALLBACKPRINT; + +VMMR3DECL(int) STAMR3RegisterCallback(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, + PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint, + const char *pszDesc, const char *pszName, ...) RT_IPRT_FORMAT_ATTR(8, 9); +VMMR3DECL(int) STAMR3RegisterCallbackV(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, + PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint, + const char *pszDesc, const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(8, 0); + +VMMR3DECL(int) STAMR3RegisterRefresh(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, + STAMUNIT enmUnit, uint8_t iRefreshGrp, const char *pszDesc, + const char *pszName, ...) RT_IPRT_FORMAT_ATTR(8, 9); +VMMR3DECL(int) STAMR3RegisterRefreshV(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, + STAMUNIT enmUnit, uint8_t iRefreshGrp, const char *pszDesc, + const char *pszName, va_list va) RT_IPRT_FORMAT_ATTR(8, 0); + +VMMR3DECL(int) STAMR3Deregister(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3DeregisterF(PUVM pUVM, const char *pszPatFmt, ...) RT_IPRT_FORMAT_ATTR(2, 3); +VMMR3DECL(int) STAMR3DeregisterV(PUVM pUVM, const char *pszPatFmt, va_list va) RT_IPRT_FORMAT_ATTR(2, 0); +VMMR3DECL(int) STAMR3DeregisterByPrefix(PUVM pUVM, const char *pszPrefix); +VMMR3DECL(int) STAMR3DeregisterByAddr(PUVM pUVM, void *pvSample); + +VMMR3DECL(int) STAMR3Reset(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3Snapshot(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc); +VMMR3DECL(int) STAMR3SnapshotFree(PUVM pUVM, char *pszSnapshot); +VMMR3DECL(int) STAMR3Dump(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3DumpToReleaseLog(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3Print(PUVM pUVM, const char *pszPat); + +/** + * Callback function for STAMR3Enum(). + * + * @returns non-zero to halt the enumeration. + * + * @param pszName The name of the sample. + * @param enmType The type. + * @param pvSample Pointer to the data. enmType indicates the format of this data. + * @param enmUnit The unit. + * @param pszUnit The unit as string. This is a permanent string, + * same as returned by STAMR3GetUnit(). + * @param enmVisibility The visibility. + * @param pszDesc The description. + * @param pvUser The pvUser argument given to STAMR3Enum(). + */ +typedef DECLCALLBACKTYPE(int, FNSTAMR3ENUM,(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit, + const char *pszUnit, STAMVISIBILITY enmVisibility, const char *pszDesc, void *pvUser)); +/** Pointer to a FNSTAMR3ENUM(). */ +typedef FNSTAMR3ENUM *PFNSTAMR3ENUM; + +VMMR3DECL(int) STAMR3Enum(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser); +VMMR3DECL(const char *) STAMR3GetUnit(STAMUNIT enmUnit); +VMMR3DECL(const char *) STAMR3GetUnit1(STAMUNIT enmUnit); +VMMR3DECL(const char *) STAMR3GetUnit2(STAMUNIT enmUnit); + +/** @} */ + +/** @} */ + +RT_C_DECLS_END + +#endif /* !VBOX_INCLUDED_vmm_stam_h */ + |