VirtualBox

Changeset 12471 in vbox for trunk/src


Ignore:
Timestamp:
Sep 15, 2008 6:32:32 PM (16 years ago)
Author:
vboxsync
Message:

Debugger: new stats (in progress).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/VBoxDbgStatsQt4.cpp

    r12469 r12471  
    3939#include <VBox/log.h>
    4040#include <iprt/string.h>
     41#include <iprt/mem.h>
    4142#include <iprt/assert.h>
    4243
     
    5758
    5859
     60/**
     61 * Formats a number into a 64-byte buffer.
     62 */
     63static char *formatNumber(char *psz, uint64_t u64)
     64{
     65    static const char s_szDigits[] = "0123456789";
     66    psz += 63;
     67    *psz-- = '\0';
     68    unsigned cDigits = 0;
     69    for (;;)
     70    {
     71        const unsigned iDigit = u64 % 10;
     72        u64 /= 10;
     73        *psz = s_szDigits[iDigit];
     74        if (!u64)
     75            break;
     76        psz--;
     77        if (!(++cDigits % 3))
     78            *psz-- = ',';
     79    }
     80    return psz;
     81}
     82
     83
     84/**
     85 * Formats a number into a 64-byte buffer.
     86 * (18.446.744.073.709.551.615)
     87 */
     88static char *formatNumberSigned(char *psz, int64_t i64)
     89{
     90    static const char s_szDigits[] = "0123456789";
     91    psz += 63;
     92    *psz-- = '\0';
     93    const bool fNegative = i64 < 0;
     94    uint64_t u64 = fNegative ? -i64 : i64;
     95    unsigned cDigits = 0;
     96    for (;;)
     97    {
     98        const unsigned iDigit = u64 % 10;
     99        u64 /= 10;
     100        *psz = s_szDigits[iDigit];
     101        if (!u64)
     102            break;
     103        psz--;
     104        if (!(++cDigits % 3))
     105            *psz-- = ',';
     106    }
     107    if (fNegative)
     108        *--psz = '-';
     109    return psz;
     110}
     111
     112
     113/**
     114 * Formats a unsigned hexadecimal number into a into a 64-byte buffer.
     115 */
     116static char *formatHexNumber(char *psz, uint64_t u64, unsigned cZeros)
     117{
     118    static const char s_szDigits[] = "0123456789abcdef";
     119    psz += 63;
     120    *psz-- = '\0';
     121    unsigned cDigits = 0;
     122    for (;;)
     123    {
     124        const unsigned iDigit = u64 % 16;
     125        u64 /= 16;
     126        *psz = s_szDigits[iDigit];
     127        ++cDigits;
     128        if (!u64 && cDigits >= cZeros)
     129            break;
     130        psz--;
     131        if (!(cDigits % 8))
     132            *psz-- = '\'';
     133    }
     134    return psz;
     135}
     136
     137
     138/**
     139 * Formats a sort key number.
     140 */
     141static void formatSortKey(char *psz, uint64_t u64)
     142{
     143    static const char s_szDigits[] = "0123456789abcdef";
     144    /* signed */
     145    *psz++ = '+';
     146
     147    /* 16 hex digits */
     148    psz[16] = '\0';
     149    unsigned i = 16;
     150    while (i-- > 0)
     151    {
     152        if (u64)
     153        {
     154            const unsigned iDigit = u64 % 16;
     155            u64 /= 16;
     156            psz[i] = s_szDigits[iDigit];
     157        }
     158        else
     159            psz[i] = '0';
     160    }
     161}
     162
     163
     164#if 0/* unused */
     165/**
     166 * Formats a sort key number.
     167 */
     168static void formatSortKeySigned(char *psz, int64_t i64)
     169{
     170    static const char s_szDigits[] = "0123456789abcdef";
     171
     172    /* signed */
     173    uint64_t u64;
     174    if (i64 >= 0)
     175    {
     176        *psz++ = '+';
     177        u64 = i64;
     178    }
     179    else
     180    {
     181        *psz++ = '-';
     182        u64 = -i64;
     183    }
     184
     185    /* 16 hex digits */
     186    psz[16] = '\0';
     187    unsigned i = 16;
     188    while (i-- > 0)
     189    {
     190        if (u64)
     191        {
     192            const unsigned iDigit = u64 % 16;
     193            u64 /= 16;
     194            psz[i] = s_szDigits[iDigit];
     195        }
     196        else
     197            psz[i] = '0';
     198    }
     199}
     200#endif
     201
     202
     203
     204/** Pointer to a statistics sample. */
     205typedef struct DBGGUISTATSNODE *PDBGGUISTATSNODE;
     206
     207/**
     208 * A tree node representing a statistic sample.
     209 *
     210 * The nodes carry a reference to the parent and to its position among its
     211 * siblings. Both of these need updating when the grand parent or parent adds a
     212 * new child. This will hopefully not be too expensive but rather pay off when
     213 * we need to create a parent index.
     214 */
     215typedef struct DBGGUISTATSNODE
     216{
     217    /** Pointer to the parent. */
     218    PDBGGUISTATSNODE    pParent;
     219    /** Array of children. */
     220    PDBGGUISTATSNODE    paChildren;
     221    /** The number of children. */
     222    uint32_t            cChildren;
     223    /** Our index among the parent's children. */
     224    uint32_t            iSelf;
     225    /** The unit. */
     226    STAMUNIT            enmUnit;
     227    /** The data type. */
     228    STAMTYPE            enmType;
     229    /** The data at last update. */
     230    union
     231    {
     232        /** STAMTYPE_COUNTER. */
     233        STAMCOUNTER     Counter;
     234        /** STAMTYPE_PROFILE. */
     235        STAMPROFILE     Profile;
     236        /** STAMTYPE_PROFILE_ADV. */
     237        STAMPROFILEADV  ProfileAdv;
     238        /** STAMTYPE_RATIO_U32. */
     239        STAMRATIOU32    RatioU32;
     240        /** STAMTYPE_U8 & STAMTYPE_U8_RESET. */
     241        uint8_t         u8;
     242        /** STAMTYPE_U16 & STAMTYPE_U16_RESET. */
     243        uint16_t        u16;
     244        /** STAMTYPE_U32 & STAMTYPE_U32_RESET. */
     245        uint32_t        u32;
     246        /** STAMTYPE_U64 & STAMTYPE_U64_RESET. */
     247        uint64_t        u64;
     248    } Data;
     249    /** The description string. */
     250    QString            *pDescStr;
     251} DBGGUISTATSNODE;
     252
     253
     254class VBoxDbgStatsModel : public QAbstractItemModel
     255{
     256private:
     257    /** The root of the sample tree. */
     258    PDBGGUISTATSNODE m_pRoot;
     259
     260public:
     261    /**
     262     * Constructor.
     263     *
     264     * @param   a_pParent       The parent object. See QAbstractItemModel in the Qt
     265     *                          docs for details.
     266     */
     267    VBoxDbgStatsModel(QObject *a_pParent);
     268
     269    /**
     270     * Destructor.
     271     *
     272     * This will free all the the data the model holds.
     273     */
     274    ~VBoxDbgStatsModel();
     275
     276    /**
     277     * Set the root node.
     278     *
     279     * This will free all the current data before taking the ownership of the new
     280     * root node and its children.
     281     *
     282     * @param   a_pRoot         The new root node.
     283     */
     284    void setRootNode(PDBGGUISTATSNODE a_pRoot);
     285
     286    /**
     287     * Constructs a new statistics tree by query data from the VM.
     288     *
     289     * @returns Pointer to the root of the tree we've constructed. This will be NULL
     290     *          if the STAM API throws an error or we run out of memory.
     291     *
     292     * @param   a_pVM           The VM handle.
     293     */
     294    static PDBGGUISTATSNODE createNewTree(PVM a_pVM);
     295
     296    /**
     297     * Destroys a statistics tree.
     298     *
     299     * @param   a_pRoot         The root of the tree. NULL is fine.
     300     */
     301    static void destroyTree(PDBGGUISTATSNODE a_pRoot);
     302
     303protected:
     304    /**
     305     * Destroys a node and all its children.
     306     *
     307     * @param   a_pNode         The node to destroy.
     308     */
     309    static void destroyNode(PDBGGUISTATSNODE a_pNode);
     310
     311    /**
     312     * Converts an index to a node pointer.
     313     *
     314     * @returns Pointer to the node, NULL if empty tree.
     315     * @param   a_rIndex        Reference to the index
     316     */
     317    inline PDBGGUISTATSNODE nodeFromIndex(const QModelIndex &a_rIndex) const
     318    {
     319        if (RT_LIKELY(a_rIndex.isValid()))
     320            return (PDBGGUISTATSNODE)a_rIndex.internalPointer();
     321        return m_pRoot;
     322    }
     323
     324public:
     325
     326    /** @name Methods we override
     327     * @{ */
     328    virtual int columnCount(const QModelIndex &parent) const;
     329    virtual QVariant data(const QModelIndex &index, int role) const;
     330    virtual bool hasChildren(const QModelIndex &parent) const;
     331    virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
     332    virtual QModelIndex index(int row, int column, const QModelIndex &parent) const;
     333    virtual QModelIndex parent(const QModelIndex &child) const;
     334    virtual int rowCount(const QModelIndex &parent) const;
     335    /** @}  */
     336};
     337
     338
     339VBoxDbgStatsModel::VBoxDbgStatsModel(QObject *a_pParent)
     340    : QAbstractItemModel(a_pParent), m_pRoot(NULL)
     341{
     342}
     343
     344
     345
     346VBoxDbgStatsModel::~VBoxDbgStatsModel()
     347{
     348    destroyTree(m_pRoot);
     349    m_pRoot = NULL;
     350}
     351
     352
     353/*static*/ void
     354VBoxDbgStatsModel::destroyTree(PDBGGUISTATSNODE a_pRoot)
     355{
     356    if (!a_pRoot)
     357        return;
     358    Assert(!a_pRoot->pParent);
     359    Assert(!a_pRoot->iSelf);
     360
     361    destroyNode(a_pRoot);
     362}
     363
     364
     365/* static*/ void
     366VBoxDbgStatsModel::destroyNode(PDBGGUISTATSNODE a_pNode)
     367{
     368    /* destroy all our children */
     369    uint32_t i = a_pNode->cChildren;
     370    while (i-- > 0)
     371        destroyNode(&a_pNode->paChildren[i]);
     372
     373    /* free the resources we're using */
     374    a_pNode->pParent = NULL;
     375
     376    RTMemFree(a_pNode->paChildren);
     377    a_pNode->paChildren = NULL;
     378
     379    a_pNode->cChildren = 0;
     380    a_pNode->iSelf = UINT32_MAX;
     381    a_pNode->enmUnit = STAMUNIT_INVALID;
     382    a_pNode->enmType = STAMTYPE_INVALID;
     383
     384    if (a_pNode->pDescStr)
     385    {
     386        delete a_pNode->pDescStr;
     387        a_pNode->pDescStr = NULL;
     388    }
     389}
     390
     391
     392/*static*/ PDBGGUISTATSNODE
     393VBoxDbgStatsModel::createNewTree(PVM a_pVM)
     394{
     395    /** @todo  */
     396    return NULL;
     397}
     398
     399
     400#if 0
     401/*static*/ PDBGGUISTATSNODE
     402VBoxDbgStatsModel::createNewTree(IMachineDebugger *a_pIMachineDebugger)
     403{
     404    /** @todo  */
     405    return NULL;
     406}
     407#endif
     408
     409
     410#if 0
     411/*static*/ PDBGGUISTATSNODE
     412VBoxDbgStatsModel::createNewTree(const char *pszFilename)
     413{
     414    /** @todo  */
     415    return NULL;
     416}
     417#endif
     418
     419
     420#if 0
     421/*static*/ PDBGGUISTATSNODE
     422VBoxDbgStatsModel::createDiffTree(PDBGGUISTATSNODE pTree1, PDBGGUISTATSNODE pTree2)
     423{
     424    /** @todo  */
     425    return NULL;
     426}
     427#endif
     428
     429
     430int
     431VBoxDbgStatsModel::columnCount(const QModelIndex &parent) const
     432{
     433    return 9; /* fixed */
     434}
     435
     436
     437int
     438VBoxDbgStatsModel::rowCount(const QModelIndex &a_rParent) const
     439{
     440    PDBGGUISTATSNODE pParent = nodeFromIndex(a_rParent);
     441    return pParent ? pParent->cChildren : 0;
     442}
     443
     444
     445bool
     446VBoxDbgStatsModel::hasChildren(const QModelIndex &a_rParent) const
     447{
     448    PDBGGUISTATSNODE pParent = nodeFromIndex(a_rParent);
     449    return pParent
     450        && pParent->cChildren > 0;
     451}
     452
     453
     454QModelIndex
     455VBoxDbgStatsModel::index(int iRow, int iColumn, const QModelIndex &r_pParent) const
     456{
     457    PDBGGUISTATSNODE pParent = nodeFromIndex(r_pParent);
     458    if (!pParent)
     459        return QModelIndex(); /* bug? */
     460    if ((unsigned)iRow >= pParent->cChildren)
     461        return QModelIndex(); /* bug? */
     462    if ((unsigned)iColumn >= 9)
     463        return QModelIndex(); /* bug? */
     464
     465    return createIndex(iRow, iColumn, &pParent->paChildren[iRow]);
     466}
     467
     468
     469QModelIndex
     470VBoxDbgStatsModel::parent(const QModelIndex &a_rChild) const
     471{
     472    PDBGGUISTATSNODE pChild = nodeFromIndex(a_rChild);
     473    if (!pChild)
     474        return QModelIndex(); /* bug */
     475    PDBGGUISTATSNODE pParent = pChild->pParent;
     476    if (!pParent)
     477        return QModelIndex(); /* root child */
     478
     479    return createIndex(pParent->iSelf, a_rChild.column(), pParent);
     480}
     481
     482
     483QVariant
     484VBoxDbgStatsModel::headerData(int a_iSection, Qt::Orientation a_eOrientation, int a_eRole) const
     485{
     486    if (    a_eOrientation != Qt::Horizontal
     487        ||  a_eRole != Qt::DisplayRole)
     488        return QVariant();
     489    switch (a_iSection)
     490    {
     491        case 0: return tr("Name");
     492        case 1: return tr("Unit");
     493        case 2: return tr("Value/Times");
     494        case 3: return tr("Min");
     495        case 4: return tr("Average");
     496        case 5: return tr("Max");
     497        case 6: return tr("Total");
     498        case 7: return tr("dInt");
     499        case 8: return tr("Description");
     500        default:
     501            return QVariant(); /* bug */
     502    }
     503}
     504
     505
     506QVariant
     507VBoxDbgStatsModel::data(const QModelIndex &a_rIndex, int role) const
     508{
     509    /** @todo data formatting... */
     510    return QVariant();
     511}
    59512
    60513
     
    171624
    172625
    173 /**
    174  * Formats a number into a 64-byte buffer.
    175  */
    176 static char *formatNumber(char *psz, uint64_t u64)
    177 {
    178     static const char s_szDigits[] = "0123456789";
    179     psz += 63;
    180     *psz-- = '\0';
    181     unsigned cDigits = 0;
    182     for (;;)
    183     {
    184         const unsigned iDigit = u64 % 10;
    185         u64 /= 10;
    186         *psz = s_szDigits[iDigit];
    187         if (!u64)
    188             break;
    189         psz--;
    190         if (!(++cDigits % 3))
    191             *psz-- = ',';
    192     }
    193     return psz;
    194 }
    195 
    196 
    197 /**
    198  * Formats a number into a 64-byte buffer.
    199  * (18.446.744.073.709.551.615)
    200  */
    201 static char *formatNumberSigned(char *psz, int64_t i64)
    202 {
    203     static const char s_szDigits[] = "0123456789";
    204     psz += 63;
    205     *psz-- = '\0';
    206     const bool fNegative = i64 < 0;
    207     uint64_t u64 = fNegative ? -i64 : i64;
    208     unsigned cDigits = 0;
    209     for (;;)
    210     {
    211         const unsigned iDigit = u64 % 10;
    212         u64 /= 10;
    213         *psz = s_szDigits[iDigit];
    214         if (!u64)
    215             break;
    216         psz--;
    217         if (!(++cDigits % 3))
    218             *psz-- = ',';
    219     }
    220     if (fNegative)
    221         *--psz = '-';
    222     return psz;
    223 }
    224 
    225 
    226 /**
    227  * Formats a unsigned hexadecimal number into a into a 64-byte buffer.
    228  */
    229 static char *formatHexNumber(char *psz, uint64_t u64, unsigned cZeros)
    230 {
    231     static const char s_szDigits[] = "0123456789abcdef";
    232     psz += 63;
    233     *psz-- = '\0';
    234     unsigned cDigits = 0;
    235     for (;;)
    236     {
    237         const unsigned iDigit = u64 % 16;
    238         u64 /= 16;
    239         *psz = s_szDigits[iDigit];
    240         ++cDigits;
    241         if (!u64 && cDigits >= cZeros)
    242             break;
    243         psz--;
    244         if (!(cDigits % 8))
    245             *psz-- = '\'';
    246     }
    247     return psz;
    248 }
    249 
    250 
    251 /**
    252  * Formats a sort key number.
    253  */
    254 static void formatSortKey(char *psz, uint64_t u64)
    255 {
    256     static const char s_szDigits[] = "0123456789abcdef";
    257     /* signed */
    258     *psz++ = '+';
    259 
    260     /* 16 hex digits */
    261     psz[16] = '\0';
    262     unsigned i = 16;
    263     while (i-- > 0)
    264     {
    265         if (u64)
    266         {
    267             const unsigned iDigit = u64 % 16;
    268             u64 /= 16;
    269             psz[i] = s_szDigits[iDigit];
    270         }
    271         else
    272             psz[i] = '0';
    273     }
    274 }
    275 
    276 
    277 #if 0/* unused */
    278 /**
    279  * Formats a sort key number.
    280  */
    281 static void formatSortKeySigned(char *psz, int64_t i64)
    282 {
    283     static const char s_szDigits[] = "0123456789abcdef";
    284 
    285     /* signed */
    286     uint64_t u64;
    287     if (i64 >= 0)
    288     {
    289         *psz++ = '+';
    290         u64 = i64;
    291     }
    292     else
    293     {
    294         *psz++ = '-';
    295         u64 = -i64;
    296     }
    297 
    298     /* 16 hex digits */
    299     psz[16] = '\0';
    300     unsigned i = 16;
    301     while (i-- > 0)
    302     {
    303         if (u64)
    304         {
    305             const unsigned iDigit = u64 % 16;
    306             u64 /= 16;
    307             psz[i] = s_szDigits[iDigit];
    308         }
    309         else
    310             psz[i] = '0';
    311     }
    312 }
    313 #endif
    314626
    315627
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette