VirtualBox

Changeset 60977 in vbox


Ignore:
Timestamp:
May 13, 2016 1:06:26 PM (9 years ago)
Author:
vboxsync
Message:

Main/VirtualBoxBase: Add code for collecting information about how many API objects of each component type are currently around and how many have been created ever. While working on this the tiny bug in the event code was found (harmless, as before VirtualBoxBase::BaseFinalRelease was idempotent, but now no longer acceptable)

Location:
trunk/src/VBox/Main
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/idl/comimpl.xsl

    r60765 r60977  
    507507    void FinalRelease()
    508508    {
    509         mEvent->FinalRelease();
     509        uninit();
    510510        BaseFinalRelease();
    511511    }
  • trunk/src/VBox/Main/include/VirtualBoxBase.h

    r60765 r60977  
    699699#endif
    700700
    701      HRESULT BaseFinalConstruct()
    702      {
    703 #ifdef RT_OS_WINDOWS
    704         return CoCreateFreeThreadedMarshaler(this, //GetControllingUnknown(),
    705                                              m_pUnkMarshaler.asOutParam());
    706 #else
    707         return S_OK;
    708 #endif
    709      }
    710 
    711      void BaseFinalRelease()
    712      {
    713 #ifdef RT_OS_WINDOWS
    714          m_pUnkMarshaler.setNull();
    715 #endif
    716      }
    717 
     701     HRESULT BaseFinalConstruct();
     702     void BaseFinalRelease();
    718703
    719704public:
     
    819804    /** User-level object lock for subclasses */
    820805    mutable RWLockHandle *mObjectLock;
     806
     807    /** Slot of this object in the saFactoryStats array */
     808    uint32_t iFactoryStat;
    821809};
     810
     811/** Structure for counting the currently existing and ever created objects
     812 * for each component name. */
     813typedef struct CLASSFACTORY_STAT
     814{
     815    const char *psz;
     816    uint64_t current;
     817    uint64_t overall;
     818} CLASSFACTORY_STAT;
     819
     820/** Maximum number of component names to deal with. There will be debug
     821 * assertions if the value is too low. Since the table is global and its
     822 * entries are reasonably small, it's not worth squeezing out the last bit. */
     823#define CLASSFACTORYSTATS_MAX 128
     824
     825/* global variables (defined in VirtualBoxBase.cpp) */
     826extern CLASSFACTORY_STAT g_aClassFactoryStats[CLASSFACTORYSTATS_MAX];
     827extern RWLockHandle *g_pClassFactoryStatsLock;
     828
     829extern void APIDumpComponentFactoryStats();
    822830
    823831/**
  • trunk/src/VBox/Main/src-all/VirtualBoxBase.cpp

    r58132 r60977  
    77
    88/*
    9  * Copyright (C) 2006-2014 Oracle Corporation
     9 * Copyright (C) 2006-2016 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4848////////////////////////////////////////////////////////////////////////////////
    4949
    50 VirtualBoxBase::VirtualBoxBase() : mState(this)
     50CLASSFACTORY_STAT g_aClassFactoryStats[CLASSFACTORYSTATS_MAX] =
     51{
     52    { "--- totals ---", 0 },
     53    { NULL, 0 }
     54};
     55
     56RWLockHandle *g_pClassFactoryStatsLock = NULL;
     57
     58
     59VirtualBoxBase::VirtualBoxBase() :
     60    mState(this),
     61    iFactoryStat(~0U)
    5162{
    5263    mObjectLock = NULL;
     64
     65    if (!g_pClassFactoryStatsLock)
     66    {
     67        RWLockHandle *lock = new RWLockHandle(LOCKCLASS_OBJECTSTATE);
     68        if (!ASMAtomicCmpXchgPtr(&g_pClassFactoryStatsLock, lock, NULL))
     69            delete lock;
     70    }
     71    Assert(g_pClassFactoryStatsLock);
    5372}
    5473
    5574VirtualBoxBase::~VirtualBoxBase()
    5675{
     76    Assert(iFactoryStat == ~0U);
    5777    if (mObjectLock)
    5878        delete mObjectLock;
     79}
     80
     81HRESULT VirtualBoxBase::BaseFinalConstruct()
     82{
     83    Assert(iFactoryStat == ~0U);
     84    if (g_pClassFactoryStatsLock)
     85    {
     86        AutoWriteLock alock(g_pClassFactoryStatsLock COMMA_LOCKVAL_SRC_POS);
     87        g_aClassFactoryStats[0].current++;
     88        g_aClassFactoryStats[0].overall++;
     89        const char *pszName = getComponentName();
     90        uint32_t i = 1;
     91        while (i < CLASSFACTORYSTATS_MAX && g_aClassFactoryStats[i].psz)
     92        {
     93            if (g_aClassFactoryStats[i].psz == pszName)
     94                break;
     95            i++;
     96        }
     97        if (i < CLASSFACTORYSTATS_MAX)
     98        {
     99            if (!g_aClassFactoryStats[i].psz)
     100            {
     101                g_aClassFactoryStats[i].psz = pszName;
     102                g_aClassFactoryStats[i].current = 0;
     103                g_aClassFactoryStats[i].overall = 0;
     104            }
     105            iFactoryStat = i;
     106            g_aClassFactoryStats[i].current++;
     107            g_aClassFactoryStats[i].overall++;
     108        }
     109        else
     110            AssertMsg(i < CLASSFACTORYSTATS_MAX, ("%u exhausts size of factory housekeeping array\n", i));
     111    }
     112    else
     113        Assert(g_pClassFactoryStatsLock);
     114
     115#ifdef RT_OS_WINDOWS
     116    return CoCreateFreeThreadedMarshaler(this, //GetControllingUnknown(),
     117                                         m_pUnkMarshaler.asOutParam());
     118#else
     119    return S_OK;
     120#endif
     121}
     122
     123void VirtualBoxBase::BaseFinalRelease()
     124{
     125    if (g_pClassFactoryStatsLock)
     126    {
     127        AutoWriteLock alock(g_pClassFactoryStatsLock COMMA_LOCKVAL_SRC_POS);
     128        g_aClassFactoryStats[0].current--;
     129        const char *pszName = getComponentName();
     130        if (iFactoryStat < CLASSFACTORYSTATS_MAX)
     131        {
     132            if (g_aClassFactoryStats[iFactoryStat].psz == pszName)
     133            {
     134                g_aClassFactoryStats[iFactoryStat].current--;
     135                iFactoryStat = ~0U;
     136            }
     137            else
     138                AssertMsgFailed(("could not find factory housekeeping array entry for %s (index %u contains %s)\n", pszName, iFactoryStat, g_aClassFactoryStats[iFactoryStat].psz));
     139        }
     140        else
     141            AssertMsgFailed(("factory housekeeping array corruption, index %u is too large\n", iFactoryStat));
     142    }
     143    else
     144        Assert(g_pClassFactoryStatsLock);
     145
     146#ifdef RT_OS_WINDOWS
     147     m_pUnkMarshaler.setNull();
     148#endif
     149}
     150
     151void APIDumpComponentFactoryStats()
     152{
     153    if (g_pClassFactoryStatsLock)
     154    {
     155        AutoReadLock alock(g_pClassFactoryStatsLock COMMA_LOCKVAL_SRC_POS);
     156        for (uint32_t i = 0; i < CLASSFACTORYSTATS_MAX && g_aClassFactoryStats[i].psz; i++)
     157            LogRel(("CFS: component %-30s current %-10u total %-10u\n",
     158                    g_aClassFactoryStats[i].psz, g_aClassFactoryStats[i].current,
     159                    g_aClassFactoryStats[i].overall));
     160    }
     161    else
     162        Assert(g_pClassFactoryStatsLock);
    59163}
    60164
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