tracebuf.cpp revision 20024c6bd4100e9925d1ff0516af5753814fc43d
/*******************************************************************************
* Header Files *
*******************************************************************************/
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/** Alignment used to place the trace buffer members, this should be a multiple
* of the cache line size if possible. (We should dynamically determine it.) */
#define RTTRACEBUF_ALIGNMENT 64
/**
* The volatile trace buffer members.
*/
typedef struct RTTRACEBUFVOLATILE
{
/** Reference counter. */
/** The current entry. */
/** Pointer to the volatile parts of a trace buffer. */
typedef RTTRACEBUFVOLATILE *PRTTRACEBUFVOLATILE;
/**
* Trace buffer entry.
*/
typedef struct RTTRACEBUFENTRY
{
/** The nano second entry time stamp. */
/** The message. */
/** Pointer to a trace buffer entry. */
typedef RTTRACEBUFENTRY *PRTTRACEBUFENTRY;
/**
* Trace buffer structure.
*
* @remarks This structure must be context agnostic, i.e. no pointers or
*/
typedef struct RTTRACEBUFINT
{
/** Magic value (RTTRACEBUF_MAGIC). */
/** The entry size. */
/** The number of entries. */
/** Flags (always zero for now). */
/** The offset to the volatile members (RTTRACEBUFVOLATILE) (relative to
* the start of this structure). */
/** The offset to the entries (relative to the start of this structure). */
/** Reserved entries. */
/** Pointer to a const trace buffer. */
typedef RTTRACEBUFINT const *PCRTTRACEBUFINT;
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
/** Calculates the address of the volatile trace buffer members. */
#define RTTRACEBUF_TO_VOLATILE(a_pThis) ((PRTTRACEBUFVOLATILE)((uint8_t *)(a_pThis) + (a_pThis)->offVolatile))
/** Calculates the address of a trace buffer entry. */
((PRTTRACEBUFENTRY)( (uint8_t *)(a_pThis) + (a_pThis)->offEntries + (a_iEntry) * (a_pThis)->cbEntry ))
/** Validates a trace buffer handle and returns rc if not valid. */
do { \
} while (0)
/**
* Resolves and validates a trace buffer handle and returns rc if not valid.
*
* @param a_hTraceBuf The trace buffer handle passed by the user.
* @param a_pThis Where to store the trace buffer pointer.
*/
do { \
if ((a_hTraceBuf) == RTTRACEBUF_DEFAULT) \
{ \
(a_pThis) = RTTraceGetDefaultBuf(); \
if (!RT_VALID_PTR(a_pThis)) \
return VERR_NOT_FOUND; \
} \
else \
{ \
(a_pThis) = (a_hTraceBuf); \
} \
\
{ \
} \
} while (0)
/**
* Drops a trace buffer reference.
*
* @param a_pThis Pointer to the trace buffer.
*/
#define RTTRACEBUF_DROP_REFERENCE(a_pThis) \
do { \
if (!cRefs) \
} while (0)
/**
* The prologue code for a RTTraceAddSomething function.
*
* Resolves a trace buffer handle, grabs a reference to it and allocates the
* next entry. Return with an appropriate error status on failure.
*
* @param a_hTraceBuf The trace buffer handle passed by the user.
*
* @remarks This is kind of ugly, sorry.
*/
#define RTTRACEBUF_ADD_PROLOGUE(a_hTraceBuf) \
int rc; \
char *pszBuf; \
\
/* Resolve and validate the handle. */ \
if ((a_hTraceBuf) == RTTRACEBUF_DEFAULT) \
{ \
pThis = RTTraceGetDefaultBuf(); \
if (!RT_VALID_PTR(pThis)) \
return VERR_NOT_FOUND; \
} \
else \
{ \
pThis = (a_hTraceBuf); \
} \
\
/* Grab a reference. */ \
{ \
} \
\
/* Grab the next entry and set the time stamp. */ \
*pszBuf = '\0'; \
/**
* Used by a RTTraceAddPosSomething to store the source position in the entry
* prior to adding the actual trace message text.
*
* Both pszBuf and cchBuf will be adjusted such that pszBuf points and the zero
* terminator after the source position part.
*/
#define RTTRACEBUF_ADD_STORE_SRC_POS() \
do { \
/* file(line): - no path */ \
} while (0)
/**
* The epilogue code for a RTTraceAddSomething function.
*
* This will release the trace buffer reference.
*/
#define RTTRACEBUF_ADD_EPILOGUE() \
if (!cRefs) \
return rc
#ifndef IN_RC /* Drop this in RC context (too lazy to split the file). */
RTDECL(int) RTTraceBufCreate(PRTTRACEBUF phTraceBuf, uint32_t cEntries, uint32_t cbEntry, uint32_t fFlags)
{
/*
* Apply default and alignment adjustments.
*/
if (!cbEntry)
else
if (!cEntries)
cEntries = 64;
else if (cEntries < 4)
cEntries = 4;
/*
* Calculate the required buffer size, allocte it and hand it on to the
* carver API.
*/
{
}
int rc;
if (pvBlock)
{
if (RT_FAILURE(rc))
}
else
rc = VERR_NO_MEMORY;
return rc;
}
RTDECL(int) RTTraceBufCarve(PRTTRACEBUF phTraceBuf, uint32_t cEntries, uint32_t cbEntry, uint32_t fFlags,
{
/*
* Apply defaults, align sizes and check against available buffer space.
* This code can be made a bit more clever, if someone feels like it.
*/
if (cbEntry)
else
{
if (!cbEntryBuf)
else if (cEntries)
{
}
else
cbEntry = sizeof(RTTRACEBUFENTRY);
}
if (!cEntries)
if (cEntries < 4)
cEntries = 4;
if (offVolatile < sizeof(RTTRACEBUFINT))
if (*pcbBlock < cbReqBlock)
{
*pcbBlock = cbReqBlock;
return VERR_BUFFER_OVERFLOW;
}
/*
* Do the carving.
*/
*phTraceBuf = pThis;
return VINF_SUCCESS;
}
#endif /* !IN_RC */
/**
* Destructor.
*
* @param pThis The trace buffer to destroy.
*/
{
}
{
}
{
if (hTraceBuf == NIL_RTTRACEBUF)
return 0;
if (!cRefs)
return cRefs;
}
{
}
{
}
{
int rc;
return rc;
}
{
}
{
}
{
}
RTDECL(int) RTTraceBufAddPosMsgEx(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsg, size_t cbMaxMsg)
{
}
{
int rc;
return rc;
}
RTDECL(int) RTTraceBufAddPosMsgV(RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsgFmt, va_list va)
{
}
{
while (cLeft--)
{
/* next */
iBase += 1;
}
return VINF_SUCCESS;
}
{
while (cLeft--)
{
/* next */
iBase += 1;
}
return VINF_SUCCESS;
}