VBoxDbgStatsQt4.cpp revision 6f9e1c121045d6e48b923006bb7ec77b123fbea2
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VBox Debugger GUI - Statistics.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License (GPL) as published by the Free Software
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * additional information or have any questions.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/*******************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync* Header Files *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Defined Constants And Macros *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** The number of column. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Structures and Typedefs *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * The state of a statistics sample node.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This is used for two pass refresh (1. get data, 2. update the view) and
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * for saving the result of a diff.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The typical invalid zeroth entry. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The node is the root node. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The node is visible. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The node should be refreshed. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** diff: The node equals. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** diff: The node in set 1 is less than the one in set 2. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** diff: The node in set 1 is greater than the one in set 2. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** diff: The node is only in set 1. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** diff: The node is only in set 2. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The end of the valid state values. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * A tree node representing a statistic sample.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * The nodes carry a reference to the parent and to its position among its
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * siblings. Both of these need updating when the grand parent or parent adds a
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * new child. This will hopefully not be too expensive but rather pay off when
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * we need to create a parent index.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Pointer to the parent. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Array of pointers to the child nodes. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The number of children. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Our index among the parent's children. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The unit. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The data type.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * For filler nodes not containing data, this will be set to STAMTYPE_INVALID. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The data at last update. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** STAMTYPE_COUNTER. */
} Data;
char *pszName;
typedef struct DBGGUISTATSSTACK
struct DBGGUISTATSSTACKENTRY
bool m_fUpdateInsertRemove;
virtual ~VBoxDbgStatsModel();
static PDBGGUISTATSNODE createAndInsertNode(PDBGGUISTATSNODE pParent, const char *pszName, size_t cchName, uint32_t iPosition);
PDBGGUISTATSNODE createAndInsert(PDBGGUISTATSNODE pParent, const char *pszName, size_t cchName, uint32_t iPosition);
static int initNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit, const char *pszDesc);
static void updateNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit, const char *pszDesc);
bool updatePrepare(void);
static DECLCALLBACK(int) updateCallback(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
return NULL;
virtual ~VBoxDbgStatsModelVM();
static DECLCALLBACK(int) createNewTreeCallback(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
unsigned cDigits = 0;
if (!u64)
psz--;
return psz;
unsigned cDigits = 0;
if (!u64)
psz--;
if (fNegative)
return psz;
unsigned cDigits = 0;
++cDigits;
psz--;
return psz;
if (u64)
if (i64 >= 0)
if (u64)
if (!a_pRoot)
#ifdef VBOX_STRICT
if (!pRoot)
return NULL;
return pRoot;
VBoxDbgStatsModel::createAndInsertNode(PDBGGUISTATSNODE pParent, const char *pszName, size_t cchName, uint32_t iPosition)
if (!pNode)
return NULL;
void *pvNew = RTMemRealloc(pParent->papChildren, sizeof(*pParent->papChildren) * (pParent->cChildren + 32));
if (!pvNew)
return NULL;
return pNode;
VBoxDbgStatsModel::createAndInsert(PDBGGUISTATSNODE pParent, const char *pszName, size_t cchName, uint32_t iPosition)
return pNode;
if (pParent)
return pNode;
/* destroy the children first with the appropriate begin/endRemoveRows signals. */
#elif 0
m_fUpdateInsertRemove = true;
VBoxDbgStatsModel::initNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit, const char *pszDesc)
if (pszDesc)
pNode->pDescStr = new QString(pszDesc); /* ignore allocation failure (well, at least up to the point we can ignore it) */
switch (enmType)
case STAMTYPE_COUNTER:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
case STAMTYPE_RATIO_U32:
case STAMTYPE_RATIO_U32_RESET:
case STAMTYPE_CALLBACK:
case STAMTYPE_U8:
case STAMTYPE_U8_RESET:
case STAMTYPE_X8:
case STAMTYPE_X8_RESET:
case STAMTYPE_U16:
case STAMTYPE_U16_RESET:
case STAMTYPE_X16:
case STAMTYPE_X16_RESET:
case STAMTYPE_U32:
case STAMTYPE_U32_RESET:
case STAMTYPE_X32:
case STAMTYPE_X32_RESET:
case STAMTYPE_U64:
case STAMTYPE_U64_RESET:
case STAMTYPE_X64:
case STAMTYPE_X64_RESET:
return VINF_SUCCESS;
VBoxDbgStatsModel::updateNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit, const char *pszDesc)
switch (enmType)
case STAMTYPE_COUNTER:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
case STAMTYPE_RATIO_U32:
case STAMTYPE_RATIO_U32_RESET:
if (iDeltaA >= 0)
case STAMTYPE_CALLBACK:
case STAMTYPE_U8:
case STAMTYPE_U8_RESET:
case STAMTYPE_X8:
case STAMTYPE_X8_RESET:
case STAMTYPE_U16:
case STAMTYPE_U16_RESET:
case STAMTYPE_X16:
case STAMTYPE_X16_RESET:
case STAMTYPE_U32:
case STAMTYPE_U32_RESET:
case STAMTYPE_X32:
case STAMTYPE_X32_RESET:
case STAMTYPE_U64:
case STAMTYPE_U64_RESET:
case STAMTYPE_X64:
case STAMTYPE_X64_RESET:
off = 0;
if (off >= 0)
return off;
while (pDescendant)
if (!pNode)
return NULL;
if (!pParent)
return NULL;
if (!pParent)
return NULL;
while ( pNode
return pNode;
if (!pNode)
return NULL;
if (!pParent)
return NULL;
return pNode;
return pParent;
while ( pNode
return pNode;
return NULL;
return NULL;
return NULL;
if (!pszEnd)
if (!iDiff)
if (iDiff > 0)
else if (iDiff < 0)
if (pPrev)
return pNode;
while (*pszCur)
if (!pszNext)
return pNode;
#ifdef VBOX_STRICT
if (!pParent)
m_cchUpdateParent = 0;
VBoxDbgStatsModel::updateCallback(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
if (!pNode)
return VERR_NO_MEMORY;
if (!pNode)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
if (pFirst)
m_cchUpdateParent = 0;
m_fUpdateInsertRemove = false;
if ( a_fSuccess
if (!pLast)
m_fUpdateInsertRemove = true;
reset();
iChild = 0;
iChild++;
QModelIndex BottomRight = createIndex(iChild - 1, DBGGUI_STATS_COLUMNS - 1, pNode->papChildren[iChild - 1]);
return m_fUpdateInsertRemove;
if (fSubTree)
else if (pNode)
if (!m_pRoot)
return QModelIndex();
reset();
return fFlags;
return DBGGUI_STATS_COLUMNS;
if (!pParent)
Log(("index: iRow=%d >= cChildren=%u (iColumn=%d)\n", iRow, (unsigned)pParent->cChildren, iColumn));
if (!pChild)
if (!pParent)
return QVariant();
switch (a_iSection)
case STAMTYPE_COUNTER:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
case STAMTYPE_RATIO_U32:
case STAMTYPE_RATIO_U32_RESET:
return psz;
case STAMTYPE_CALLBACK:
case STAMTYPE_U8:
case STAMTYPE_U8_RESET:
case STAMTYPE_X8:
case STAMTYPE_X8_RESET:
case STAMTYPE_U16:
case STAMTYPE_U16_RESET:
case STAMTYPE_X16:
case STAMTYPE_X16_RESET:
case STAMTYPE_U32:
case STAMTYPE_U32_RESET:
case STAMTYPE_X32:
case STAMTYPE_X32_RESET:
case STAMTYPE_U64:
case STAMTYPE_U64_RESET:
case STAMTYPE_X64:
case STAMTYPE_X64_RESET:
case STAMTYPE_INVALID:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
case STAMTYPE_PROFILE:
case STAMTYPE_PROFILE_ADV:
return QVariant();
if (!pNode)
return QVariant();
switch (iCol)
return QVariant();
if (pRoot)
if (pClipboard)
if (a_fReleaseLog)
if (pRoot)
if (fRc)
return fRc;
VBoxDbgStatsModelVM::createNewTreeCallback(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
while (*pszCur)
if (!pszNext)
if (!pNode)
return VERR_NO_MEMORY;
if (pRoot)
return pRoot;
return NULL;
VBoxDbgStatsView::VBoxDbgStatsView(PVM a_pVM, VBoxDbgStatsModel *a_pModel, VBoxDbgStats *a_pParent/* = NULL*/)
setRootIsDecorated(true);
setItemsExpandable(true);
if (m_pModel)
delete m_pModel;
for (int i = 0; i < cRows; i++)
if (pMenu)
VBoxDbgStats::VBoxDbgStats(PVM pVM, const char *pszPat/* = NULL*/, unsigned uRefreshRate/* = 0*/, QWidget *pParent/* = NULL*/)
: QWidget(pParent), VBoxDbgBase(pVM), m_PatStr(pszPat), m_pPatCB(NULL), m_uRefreshRate(0), m_pTimer(NULL), m_pView(NULL)
if (m_pTimer)
delete m_pTimer;
if (m_pPatCB)
delete m_pPatCB;
if (m_pView)
delete m_pView;
refresh();