20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/*******************************************************************************
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync* Header Files *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync*******************************************************************************/
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#include "internal/iprt.h"
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#include <iprt/trace.h>
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#include <iprt/assert.h>
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#include <iprt/asm.h>
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#include <iprt/err.h>
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#include <iprt/log.h>
7490c9e261ac385e367d089e253be9019336d7a8vboxsync#ifndef IN_RC
7490c9e261ac385e367d089e253be9019336d7a8vboxsync# include <iprt/mem.h>
7490c9e261ac385e367d089e253be9019336d7a8vboxsync#endif
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync#if defined(IN_RING0) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync# include <iprt/mp.h>
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync#else
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync# include <iprt/asm-amd64-x86.h>
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync#endif
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync#include <iprt/path.h>
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#include <iprt/string.h>
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#include <iprt/time.h>
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#include "internal/magics.h"
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/*******************************************************************************
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync* Structures and Typedefs *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync*******************************************************************************/
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/** Alignment used to place the trace buffer members, this should be a multiple
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * of the cache line size if possible. (We should dynamically determine it.) */
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync#define RTTRACEBUF_ALIGNMENT 64
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncAssertCompile(RTTRACEBUF_ALIGNMENT >= sizeof(uint64_t) * 2);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync/** The maximum number of entries. */
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync#define RTTRACEBUF_MAX_ENTRIES _64K
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync/** The minimum number of entries. */
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync#define RTTRACEBUF_MIN_ENTRIES 4
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync/** The default number of entries. */
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync#define RTTRACEBUF_DEF_ENTRIES 256
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync/** The maximum entry size. */
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync#define RTTRACEBUF_MAX_ENTRY_SIZE _1M
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync/** The minimum entry size. */
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync#define RTTRACEBUF_MIN_ENTRY_SIZE RTTRACEBUF_ALIGNMENT
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync/** The default entry size. */
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync#define RTTRACEBUF_DEF_ENTRY_SIZE 256
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsyncAssertCompile(!(RTTRACEBUF_DEF_ENTRY_SIZE & (RTTRACEBUF_DEF_ENTRY_SIZE - 1)));
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/**
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * The volatile trace buffer members.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsynctypedef struct RTTRACEBUFVOLATILE
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** Reference counter. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t volatile cRefs;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync /** The next entry to make use of. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t volatile iEntry;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync} RTTRACEBUFVOLATILE;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/** Pointer to the volatile parts of a trace buffer. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsynctypedef RTTRACEBUFVOLATILE *PRTTRACEBUFVOLATILE;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/**
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Trace buffer entry.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsynctypedef struct RTTRACEBUFENTRY
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** The nano second entry time stamp. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint64_t NanoTS;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync /** The ID of the CPU the event was recorded. */
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync RTCPUID idCpu;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** The message. */
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync char szMsg[RTTRACEBUF_ALIGNMENT - sizeof(uint64_t) - sizeof(RTCPUID)];
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync} RTTRACEBUFENTRY;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncAssertCompile(sizeof(RTTRACEBUFENTRY) <= RTTRACEBUF_ALIGNMENT);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/** Pointer to a trace buffer entry. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsynctypedef RTTRACEBUFENTRY *PRTTRACEBUFENTRY;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/**
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Trace buffer structure.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * @remarks This structure must be context agnostic, i.e. no pointers or
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * other types that may differ between contexts (R3/R0/RC).
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsynctypedef struct RTTRACEBUFINT
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** Magic value (RTTRACEBUF_MAGIC). */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t u32Magic;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** The entry size. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t cbEntry;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** The number of entries. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t cEntries;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** Flags (always zero for now). */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t fFlags;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** The offset to the volatile members (RTTRACEBUFVOLATILE) (relative to
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * the start of this structure). */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t offVolatile;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** The offset to the entries (relative to the start of this structure). */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t offEntries;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /** Reserved entries. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t au32Reserved[2];
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync} RTTRACEBUFINT;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/** Pointer to a const trace buffer. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsynctypedef RTTRACEBUFINT const *PCRTTRACEBUFINT;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/*******************************************************************************
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync* Defined Constants And Macros *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync*******************************************************************************/
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync/**
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync * Get the current CPU Id.
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync */
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync#if defined(IN_RING0) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync# define RTTRACEBUF_CUR_CPU() RTMpCpuId()
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync#else
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync# define RTTRACEBUF_CUR_CPU() ASMGetApicId()
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync#endif
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/** Calculates the address of the volatile trace buffer members. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#define RTTRACEBUF_TO_VOLATILE(a_pThis) ((PRTTRACEBUFVOLATILE)((uint8_t *)(a_pThis) + (a_pThis)->offVolatile))
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/** Calculates the address of a trace buffer entry. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#define RTTRACEBUF_TO_ENTRY(a_pThis, a_iEntry) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync ((PRTTRACEBUFENTRY)( (uint8_t *)(a_pThis) + (a_pThis)->offEntries + (a_iEntry) * (a_pThis)->cbEntry ))
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/** Validates a trace buffer handle and returns rc if not valid. */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#define RTTRACEBUF_VALID_RETURN_RC(a_pThis, a_rc) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync do { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertPtrReturn((a_pThis), (a_rc)); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertReturn((a_pThis)->u32Magic == RTTRACEBUF_MAGIC, (a_rc)); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertReturn((a_pThis)->offVolatile < RTTRACEBUF_ALIGNMENT * 2, (a_rc)); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertReturn(RTTRACEBUF_TO_VOLATILE(a_pThis)->cRefs > 0, (a_rc)); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } while (0)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/**
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Resolves and validates a trace buffer handle and returns rc if not valid.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * @param a_hTraceBuf The trace buffer handle passed by the user.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * @param a_pThis Where to store the trace buffer pointer.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#define RTTRACEBUF_RESOLVE_VALIDATE_RETAIN_RETURN(a_hTraceBuf, a_pThis) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync do { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t cRefs; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if ((a_hTraceBuf) == RTTRACEBUF_DEFAULT) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync (a_pThis) = RTTraceGetDefaultBuf(); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!RT_VALID_PTR(a_pThis)) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return VERR_NOT_FOUND; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync else \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync (a_pThis) = (a_hTraceBuf); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertPtrReturn((a_pThis), VERR_INVALID_HANDLE); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertReturn((a_pThis)->u32Magic == RTTRACEBUF_MAGIC, VERR_INVALID_HANDLE); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertReturn((a_pThis)->offVolatile < RTTRACEBUF_ALIGNMENT * 2, VERR_INVALID_HANDLE); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync cRefs = ASMAtomicIncU32(&RTTRACEBUF_TO_VOLATILE(a_pThis)->cRefs); \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync if (RT_UNLIKELY(cRefs < 1 || cRefs >= _1M)) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync ASMAtomicDecU32(&RTTRACEBUF_TO_VOLATILE(a_pThis)->cRefs); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertFailedReturn(VERR_INVALID_HANDLE); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } while (0)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/**
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Drops a trace buffer reference.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * @param a_pThis Pointer to the trace buffer.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#define RTTRACEBUF_DROP_REFERENCE(a_pThis) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync do { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t cRefs = ASMAtomicDecU32(&RTTRACEBUF_TO_VOLATILE(a_pThis)->cRefs); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!cRefs) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync rtTraceBufDestroy((RTTRACEBUFINT *)a_pThis); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } while (0)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/**
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * The prologue code for a RTTraceAddSomething function.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Resolves a trace buffer handle, grabs a reference to it and allocates the
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * next entry. Return with an appropriate error status on failure.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * @param a_hTraceBuf The trace buffer handle passed by the user.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * @remarks This is kind of ugly, sorry.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#define RTTRACEBUF_ADD_PROLOGUE(a_hTraceBuf) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync int rc; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t cRefs; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t iEntry; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PCRTTRACEBUFINT pThis; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PRTTRACEBUFVOLATILE pVolatile; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PRTTRACEBUFENTRY pEntry; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync char *pszBuf; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync size_t cchBuf; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /* Resolve and validate the handle. */ \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if ((a_hTraceBuf) == RTTRACEBUF_DEFAULT) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pThis = RTTraceGetDefaultBuf(); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!RT_VALID_PTR(pThis)) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return VERR_NOT_FOUND; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync else if ((a_hTraceBuf) != NIL_RTTRACEBUF) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pThis = (a_hTraceBuf); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync else \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync return VERR_INVALID_HANDLE; \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertReturn(pThis->u32Magic == RTTRACEBUF_MAGIC, VERR_INVALID_HANDLE); \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync if (pThis->fFlags & RTTRACEBUF_FLAGS_DISABLED) \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync return VINF_SUCCESS; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertReturn(pThis->offVolatile < RTTRACEBUF_ALIGNMENT * 2, VERR_INVALID_HANDLE); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pVolatile = RTTRACEBUF_TO_VOLATILE(pThis); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /* Grab a reference. */ \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync cRefs = ASMAtomicIncU32(&pVolatile->cRefs); \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync if (RT_UNLIKELY(cRefs < 1 || cRefs >= _1M)) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync ASMAtomicDecU32(&pVolatile->cRefs); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertFailedReturn(VERR_INVALID_HANDLE); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /* Grab the next entry and set the time stamp. */ \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync iEntry = ASMAtomicIncU32(&pVolatile->iEntry) - 1; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync iEntry %= pThis->cEntries; \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync pEntry = RTTRACEBUF_TO_ENTRY(pThis, iEntry); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pEntry->NanoTS = RTTimeNanoTS(); \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync pEntry->idCpu = RTTRACEBUF_CUR_CPU(); \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync pszBuf = &pEntry->szMsg[0]; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *pszBuf = '\0'; \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync cchBuf = pThis->cbEntry - RT_OFFSETOF(RTTRACEBUFENTRY, szMsg) - 1; \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync rc = VINF_SUCCESS
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/**
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Used by a RTTraceAddPosSomething to store the source position in the entry
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * prior to adding the actual trace message text.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Both pszBuf and cchBuf will be adjusted such that pszBuf points and the zero
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * terminator after the source position part.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#define RTTRACEBUF_ADD_STORE_SRC_POS() \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync do { \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /* file(line): - no path */ \
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync size_t cchPos = RTStrPrintf(pszBuf, cchBuf, "%s(%d): ", RTPathFilename(pszFile), iLine); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pszBuf += cchPos; \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync cchBuf -= cchPos; \
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync NOREF(pszFunction); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync } while (0)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/**
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * The epilogue code for a RTTraceAddSomething function.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * This will release the trace buffer reference.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#define RTTRACEBUF_ADD_EPILOGUE() \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync cRefs = ASMAtomicDecU32(&pVolatile->cRefs); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!cRefs) \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync rtTraceBufDestroy((RTTRACEBUFINT *)pThis); \
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return rc
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#ifndef IN_RC /* Drop this in RC context (too lazy to split the file). */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufCreate(PRTTRACEBUF phTraceBuf, uint32_t cEntries, uint32_t cbEntry, uint32_t fFlags)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertPtrReturn(phTraceBuf, VERR_INVALID_POINTER);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync AssertReturn(!(fFlags & ~(RTTRACEBUF_FLAGS_MASK & ~ RTTRACEBUF_FLAGS_FREE_ME)), VERR_INVALID_PARAMETER);
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync AssertMsgReturn(cbEntry <= RTTRACEBUF_MAX_ENTRIES, ("%#x\n", cbEntry), VERR_OUT_OF_RANGE);
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync AssertMsgReturn(cEntries <= RTTRACEBUF_MAX_ENTRY_SIZE, ("%#x\n", cEntries), VERR_OUT_OF_RANGE);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /*
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Apply default and alignment adjustments.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!cbEntry)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntry = RTTRACEBUF_DEF_ENTRY_SIZE;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync else
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntry = RT_ALIGN_32(cbEntry, RTTRACEBUF_ALIGNMENT);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!cEntries)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cEntries = RTTRACEBUF_DEF_ENTRIES;
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync else if (cEntries < RTTRACEBUF_MIN_ENTRIES)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cEntries = RTTRACEBUF_MIN_ENTRIES;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /*
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Calculate the required buffer size, allocte it and hand it on to the
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * carver API.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync size_t cbBlock = cbEntry * cEntries
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync + RT_ALIGN_Z(sizeof(RTTRACEBUFINT), RTTRACEBUF_ALIGNMENT)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync + RT_ALIGN_Z(sizeof(RTTRACEBUFVOLATILE), RTTRACEBUF_ALIGNMENT);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync void *pvBlock = RTMemAlloc(cbBlock);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!((uintptr_t)pvBlock & (RTTRACEBUF_ALIGNMENT - 1)))
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync {
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTMemFree(pvBlock);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync cbBlock += RTTRACEBUF_ALIGNMENT - 1;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pvBlock = RTMemAlloc(cbBlock);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync }
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync int rc;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (pvBlock)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync {
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync rc = RTTraceBufCarve(phTraceBuf, cEntries, cbEntry, fFlags, pvBlock, &cbBlock);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (RT_FAILURE(rc))
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTMemFree(pvBlock);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync }
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync else
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync rc = VERR_NO_MEMORY;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return rc;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufCarve(PRTTRACEBUF phTraceBuf, uint32_t cEntries, uint32_t cbEntry, uint32_t fFlags,
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync void *pvBlock, size_t *pcbBlock)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertPtrReturn(phTraceBuf, VERR_INVALID_POINTER);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertReturn(!(fFlags & ~RTTRACEBUF_FLAGS_MASK), VERR_INVALID_PARAMETER);
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync AssertMsgReturn(cbEntry <= RTTRACEBUF_MAX_ENTRIES, ("%#x\n", cbEntry), VERR_OUT_OF_RANGE);
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync AssertMsgReturn(cEntries <= RTTRACEBUF_MAX_ENTRY_SIZE, ("%#x\n", cEntries), VERR_OUT_OF_RANGE);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertPtrReturn(pcbBlock, VERR_INVALID_POINTER);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync size_t const cbBlock = *pcbBlock;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync AssertReturn(RT_VALID_PTR(pvBlock) || !cbBlock, VERR_INVALID_POINTER);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /*
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Apply defaults, align sizes and check against available buffer space.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * This code can be made a bit more clever, if someone feels like it.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync size_t const cbHdr = RT_ALIGN_Z(sizeof(RTTRACEBUFINT), RTTRACEBUF_ALIGNMENT)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync + RT_ALIGN_Z(sizeof(RTTRACEBUFVOLATILE), RTTRACEBUF_ALIGNMENT);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync size_t const cbEntryBuf = cbBlock > cbHdr ? cbBlock - cbHdr : 0;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (cbEntry)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntry = RT_ALIGN_32(cbEntry, RTTRACEBUF_ALIGNMENT);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync else
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync {
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!cbEntryBuf)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync {
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntry = RTTRACEBUF_DEF_ENTRY_SIZE;
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cEntries = RTTRACEBUF_DEF_ENTRIES;
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync }
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync else if (cEntries)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync {
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync size_t cbEntryZ = cbBlock / cEntries;
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntryZ &= ~(RTTRACEBUF_ALIGNMENT - 1);
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync if (cbEntryZ > RTTRACEBUF_MAX_ENTRIES)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntryZ = RTTRACEBUF_MAX_ENTRIES;
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntry = (uint32_t)cbEntryZ;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync }
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync else if (cbBlock >= RT_ALIGN_32(512, RTTRACEBUF_ALIGNMENT) * 256)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntry = RT_ALIGN_32(512, RTTRACEBUF_ALIGNMENT);
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync else if (cbBlock >= RT_ALIGN_32(256, RTTRACEBUF_ALIGNMENT) * 64)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntry = RT_ALIGN_32(256, RTTRACEBUF_ALIGNMENT);
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync else if (cbBlock >= RT_ALIGN_32(128, RTTRACEBUF_ALIGNMENT) * 32)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cbEntry = RT_ALIGN_32(128, RTTRACEBUF_ALIGNMENT);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync else
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync cbEntry = sizeof(RTTRACEBUFENTRY);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync }
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync Assert(RT_ALIGN_32(cbEntry, RTTRACEBUF_ALIGNMENT) == cbEntry);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!cEntries)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync {
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync size_t cEntriesZ = cbEntryBuf / cbEntry;
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync if (cEntriesZ > RTTRACEBUF_MAX_ENTRIES)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cEntriesZ = RTTRACEBUF_MAX_ENTRIES;
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cEntries = (uint32_t)cEntriesZ;
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync }
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync if (cEntries < RTTRACEBUF_MIN_ENTRIES)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync cEntries = RTTRACEBUF_MIN_ENTRIES;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t offVolatile = RTTRACEBUF_ALIGNMENT - ((uintptr_t)pvBlock & (RTTRACEBUF_ALIGNMENT - 1));
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (offVolatile < sizeof(RTTRACEBUFINT))
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync offVolatile += RTTRACEBUF_ALIGNMENT;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync size_t cbReqBlock = offVolatile
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync + RT_ALIGN_Z(sizeof(RTTRACEBUFVOLATILE), RTTRACEBUF_ALIGNMENT)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync + cbEntry * cEntries;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (*pcbBlock < cbReqBlock)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync {
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *pcbBlock = cbReqBlock;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return VERR_BUFFER_OVERFLOW;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync }
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /*
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Do the carving.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync memset(pvBlock, 0, cbBlock);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUFINT *pThis = (RTTRACEBUFINT *)pvBlock;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pThis->u32Magic = RTTRACEBUF_MAGIC;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pThis->cbEntry = cbEntry;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pThis->cEntries = cEntries;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pThis->fFlags = fFlags;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pThis->offVolatile = offVolatile;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pThis->offEntries = offVolatile + RT_ALIGN_Z(sizeof(RTTRACEBUFVOLATILE), RTTRACEBUF_ALIGNMENT);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PRTTRACEBUFVOLATILE pVolatile = (PRTTRACEBUFVOLATILE)((uint8_t *)pThis + offVolatile);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pVolatile->cRefs = 1;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pVolatile->iEntry = 0;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *pcbBlock = cbBlock - cbReqBlock;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *phTraceBuf = pThis;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return VINF_SUCCESS;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync#endif /* !IN_RC */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync/**
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * Destructor.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync *
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync * @param pThis The trace buffer to destroy.
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncstatic void rtTraceBufDestroy(RTTRACEBUFINT *pThis)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync AssertReturnVoid(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTTRACEBUF_MAGIC_DEAD, RTTRACEBUF_MAGIC));
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (pThis->fFlags & RTTRACEBUF_FLAGS_FREE_ME)
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync {
2c142cdd90355e7378d005eaca33c41df7b8af15vboxsync#ifdef IN_RC
2c142cdd90355e7378d005eaca33c41df7b8af15vboxsync AssertReleaseFailed();
2c142cdd90355e7378d005eaca33c41df7b8af15vboxsync#else
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTMemFree(pThis);
2c142cdd90355e7378d005eaca33c41df7b8af15vboxsync#endif
b0044ef099dee745cab7cdb6cae37d00e6de3653vboxsync }
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
d793e85931b7b22b0a443db1510b26c180d44a18vboxsyncRTDECL(uint32_t) RTTraceBufRetain(RTTRACEBUF hTraceBuf)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PCRTTRACEBUFINT pThis = hTraceBuf;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_VALID_RETURN_RC(pThis, UINT32_MAX);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return ASMAtomicIncU32(&RTTRACEBUF_TO_VOLATILE(pThis)->cRefs);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(uint32_t) RTTraceBufRelease(RTTRACEBUF hTraceBuf)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (hTraceBuf == NIL_RTTRACEBUF)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return 0;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PCRTTRACEBUFINT pThis = hTraceBuf;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_VALID_RETURN_RC(pThis, UINT32_MAX);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t cRefs = ASMAtomicDecU32(&RTTRACEBUF_TO_VOLATILE(pThis)->cRefs);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (!cRefs)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync rtTraceBufDestroy((RTTRACEBUFINT *)pThis);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return cRefs;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufAddMsg(RTTRACEBUF hTraceBuf, const char *pszMsg)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTStrCopy(pszBuf, cchBuf, pszMsg);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_EPILOGUE();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufAddMsgEx( RTTRACEBUF hTraceBuf, const char *pszMsg, size_t cbMaxMsg)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTStrCopyEx(pszBuf, cchBuf, pszMsg, cbMaxMsg);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_EPILOGUE();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufAddMsgF(RTTRACEBUF hTraceBuf, const char *pszMsgFmt, ...)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync int rc;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync va_list va;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync va_start(va, pszMsgFmt);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync rc = RTTraceBufAddMsgV(hTraceBuf, pszMsgFmt, va);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync va_end(va);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return rc;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufAddMsgV(RTTRACEBUF hTraceBuf, const char *pszMsgFmt, va_list va)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTStrPrintfV(pszBuf, cchBuf, pszMsgFmt, va);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_EPILOGUE();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufAddPos(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_STORE_SRC_POS();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_EPILOGUE();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufAddPosMsg(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsg)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_STORE_SRC_POS();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTStrCopy(pszBuf, cchBuf, pszMsg);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_EPILOGUE();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufAddPosMsgEx(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsg, size_t cbMaxMsg)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_STORE_SRC_POS();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTStrCopyEx(pszBuf, cchBuf, pszMsg, cbMaxMsg);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_EPILOGUE();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufAddPosMsgF(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsgFmt, ...)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync int rc;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync va_list va;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync va_start(va, pszMsgFmt);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync rc = RTTraceBufAddPosMsgV(hTraceBuf, RT_SRC_POS_ARGS, pszMsgFmt, va);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync va_end(va);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return rc;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufAddPosMsgV(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsgFmt, va_list va)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_PROLOGUE(hTraceBuf);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_STORE_SRC_POS();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTStrPrintfV(pszBuf, cchBuf, pszMsgFmt, va);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_ADD_EPILOGUE();
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsyncRTDECL(int) RTTraceBufEnumEntries(RTTRACEBUF hTraceBuf, PFNRTTRACEBUFCALLBACK pfnCallback, void *pvUser)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync{
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync int rc = VINF_SUCCESS;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync uint32_t iBase;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync uint32_t cLeft;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync PCRTTRACEBUFINT pThis;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync RTTRACEBUF_RESOLVE_VALIDATE_RETAIN_RETURN(hTraceBuf, pThis);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync iBase = ASMAtomicReadU32(&RTTRACEBUF_TO_VOLATILE(pThis)->iEntry);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync cLeft = pThis->cEntries;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync while (cLeft--)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync {
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync PRTTRACEBUFENTRY pEntry;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync iBase %= pThis->cEntries;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync pEntry = RTTRACEBUF_TO_ENTRY(pThis, iBase);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync if (pEntry->NanoTS)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync {
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync rc = pfnCallback((RTTRACEBUF)pThis, cLeft, pEntry->NanoTS, pEntry->idCpu, pEntry->szMsg, pvUser);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync if (rc != VINF_SUCCESS)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync break;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync }
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync /* next */
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync iBase += 1;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync }
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync RTTRACEBUF_DROP_REFERENCE(pThis);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync return rc;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync}
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsyncRTDECL(uint32_t) RTTraceBufGetEntrySize(RTTRACEBUF hTraceBuf)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync{
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync PCRTTRACEBUFINT pThis = hTraceBuf;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync RTTRACEBUF_VALID_RETURN_RC(pThis, 0);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync return pThis->cbEntry;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync}
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsyncRTDECL(uint32_t) RTTraceBufGetEntryCount(RTTRACEBUF hTraceBuf)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync{
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync PCRTTRACEBUFINT pThis = hTraceBuf;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync RTTRACEBUF_VALID_RETURN_RC(pThis, 0);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync return pThis->cEntries;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync}
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsyncRTDECL(bool) RTTraceBufDisable(RTTRACEBUF hTraceBuf)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync{
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync PCRTTRACEBUFINT pThis = hTraceBuf;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync RTTRACEBUF_VALID_RETURN_RC(pThis, false);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync return !ASMAtomicBitTestAndSet((void volatile *)&pThis->fFlags, RTTRACEBUF_FLAGS_DISABLED_BIT);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync}
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsyncRTDECL(bool) RTTraceBufEnable(RTTRACEBUF hTraceBuf)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync{
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync PCRTTRACEBUFINT pThis = hTraceBuf;
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync RTTRACEBUF_VALID_RETURN_RC(pThis, false);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync return !ASMAtomicBitTestAndClear((void volatile *)&pThis->fFlags, RTTRACEBUF_FLAGS_DISABLED_BIT);
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync}
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync/*
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync *
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync * Move the following to a separate file, consider using the enumerator.
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync *
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufDumpToLog(RTTRACEBUF hTraceBuf)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t iBase;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t cLeft;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PCRTTRACEBUFINT pThis;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_RESOLVE_VALIDATE_RETAIN_RETURN(hTraceBuf, pThis);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync iBase = ASMAtomicReadU32(&RTTRACEBUF_TO_VOLATILE(pThis)->iEntry);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync cLeft = pThis->cEntries;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync while (cLeft--)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync {
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PRTTRACEBUFENTRY pEntry;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync iBase %= pThis->cEntries;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pEntry = RTTRACEBUF_TO_ENTRY(pThis, iBase);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (pEntry->NanoTS)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync RTLogPrintf("%04u/%'llu/%02x: %s\n", cLeft, pEntry->NanoTS, pEntry->idCpu, pEntry->szMsg);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /* next */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync iBase += 1;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync }
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_DROP_REFERENCE(pThis);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return VINF_SUCCESS;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsyncRTDECL(int) RTTraceBufDumpToAssert(RTTRACEBUF hTraceBuf)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync{
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t iBase;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync uint32_t cLeft;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PCRTTRACEBUFINT pThis;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_RESOLVE_VALIDATE_RETAIN_RETURN(hTraceBuf, pThis);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync iBase = ASMAtomicReadU32(&RTTRACEBUF_TO_VOLATILE(pThis)->iEntry);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync cLeft = pThis->cEntries;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync while (cLeft--)
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync {
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync PRTTRACEBUFENTRY pEntry;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync iBase %= pThis->cEntries;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync pEntry = RTTRACEBUF_TO_ENTRY(pThis, iBase);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync if (pEntry->NanoTS)
5c47137ffdbcb823e83b3cfc93bf8ccd3318bec3vboxsync RTAssertMsg2AddWeak("%u/%'llu/%02x: %s\n", cLeft, pEntry->NanoTS, pEntry->idCpu, pEntry->szMsg);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync /* next */
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync iBase += 1;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync }
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync RTTRACEBUF_DROP_REFERENCE(pThis);
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync return VINF_SUCCESS;
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync}
20024c6bd4100e9925d1ff0516af5753814fc43dvboxsync