VirtualBox

Ignore:
Timestamp:
Jun 25, 2013 2:04:17 PM (11 years ago)
Author:
vboxsync
Message:

CFGM: Made the CFGMR3CreateTree usable with pUVM == NULL for testing purposes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/CFGM.cpp

    r45189 r46781  
    6666#include <VBox/log.h>
    6767#include <iprt/assert.h>
     68#include <iprt/mem.h>
    6869#include <iprt/param.h>
    6970#include <iprt/string.h>
     
    8182static int  cfgmR3InsertLeaf(PCFGMNODE pNode, const char *pszName, PCFGMLEAF *ppLeaf);
    8283static void cfgmR3RemoveLeaf(PCFGMNODE pNode, PCFGMLEAF pLeaf);
    83 static void cfgmR3FreeValue(PCFGMLEAF pLeaf);
     84static void cfgmR3FreeValue(PVM pVM, PCFGMLEAF pLeaf);
     85
     86
     87/**
     88 * Allocator wrapper.
     89 *
     90 * @returns Pointer to the allocated memory, NULL on failure.
     91 * @param   pVM                 The VM handle, if tree associated with one.
     92 * @param   enmTag              The allocation tag.
     93 * @param   cb                  The size of the allocation.
     94 */
     95static void *cfgmR3MemAlloc(PVM pVM, MMTAG enmTag, size_t cb)
     96{
     97    if (pVM)
     98        return MMR3HeapAlloc(pVM, enmTag, cb);
     99    return RTMemAlloc(cb);
     100}
     101
     102
     103/**
     104 * Free wrapper.
     105 *
     106 * @returns Pointer to the allocated memory, NULL on failure.
     107 * @param   pVM                 The VM handle, if tree associated with one.
     108 * @param   pv                  The memory block to free.
     109 */
     110static void cfgmR3MemFree(PVM pVM, void *pv)
     111{
     112    if (pVM)
     113        MMR3HeapFree(pv);
     114    else
     115        RTMemFree(pv);
     116}
     117
     118
     119/**
     120 * String allocator wrapper.
     121 *
     122 * @returns Pointer to the allocated memory, NULL on failure.
     123 * @param   pVM                 The VM handle, if tree associated with one.
     124 * @param   enmTag              The allocation tag.
     125 * @param   cbString            The size of the allocation, terminator included.
     126 */
     127static char *cfgmR3StrAlloc(PVM pVM, MMTAG enmTag,  size_t cbString)
     128{
     129    if (pVM)
     130        return (char *)MMR3HeapAlloc(pVM, enmTag, cbString);
     131    return (char *)RTStrAlloc(cbString);
     132}
     133
     134
     135/**
     136 * String free wrapper.
     137 *
     138 * @returns Pointer to the allocated memory, NULL on failure.
     139 * @param   pVM                 The VM handle, if tree associated with one.
     140 * @param   pszString           The memory block to free.
     141 */
     142static void cfgmR3StrFree(PVM pVM, char *pszString)
     143{
     144    if (pVM)
     145        MMR3HeapFree(pszString);
     146    else
     147        RTStrFree(pszString);
     148}
     149
     150
     151/**
     152 * Frees one node, leaving any children or leaves to the caller.
     153 *
     154 * @param   pNode               The node structure to free.
     155 */
     156static void cfgmR3FreeNodeOnly(PCFGMNODE pNode)
     157{
     158    pNode->pFirstLeaf    = NULL;
     159    pNode->pFirstChild   = NULL;
     160    pNode->pNext         = NULL;
     161    pNode->pPrev         = NULL;
     162    if (!pNode->pVM)
     163        RTMemFree(pNode);
     164    else
     165    {
     166        pNode->pVM       = NULL;
     167        MMR3HeapFree(pNode);
     168    }
     169}
     170
    84171
    85172
     
    12031290 * @returns Pointer to the root node, NULL on error (out of memory or invalid
    12041291 *          VM handle).
    1205  * @param   pUVM            The user mode VM handle.
     1292 * @param   pUVM            The user mode VM handle.  For testcase (and other
     1293 *                          purposes, NULL can be used.  However, the resulting
     1294 *                          tree cannot be inserted into a tree that has a
     1295 *                          non-NULL value.  Using NULL can be usedful for
     1296 *                          testcases and similar, non VMM uses.
    12061297 */
    12071298VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PUVM pUVM)
    12081299{
    1209     UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
    1210     VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, NULL);
    1211 
    1212     PCFGMNODE pNew = (PCFGMNODE)MMR3HeapAllocU(pUVM, MM_TAG_CFGM, sizeof(*pNew));
     1300    if (pUVM)
     1301    {
     1302        UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
     1303        VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, NULL);
     1304    }
     1305
     1306    PCFGMNODE pNew;
     1307    if (pUVM)
     1308        pNew = (PCFGMNODE)MMR3HeapAllocU(pUVM, MM_TAG_CFGM, sizeof(*pNew));
     1309    else
     1310        pNew = (PCFGMNODE)RTMemAlloc(sizeof(*pNew));
    12131311    if (pNew)
    12141312    {
     
    12181316        pNew->pFirstChild   = NULL;
    12191317        pNew->pFirstLeaf    = NULL;
    1220         pNew->pVM           = pUVM->pVM;
     1318        pNew->pVM           = pUVM ? pUVM->pVM : NULL;
    12211319        pNew->fRestrictedRoot = false;
    12221320        pNew->cchName       = 0;
     
    12421340     * Create a new tree.
    12431341     */
    1244     PCFGMNODE pNewRoot = CFGMR3CreateTree(pRoot->pVM->pUVM);
     1342    PCFGMNODE pNewRoot = CFGMR3CreateTree(pRoot->pVM ? pRoot->pVM->pUVM : NULL);
    12451343    if (!pNewRoot)
    12461344        return VERR_NO_MEMORY;
     
    13521450    AssertReturn(pNode != pSubTree, VERR_INVALID_PARAMETER);
    13531451    AssertReturn(!pSubTree->pParent, VERR_INVALID_PARAMETER);
    1354     AssertReturn(pSubTree->pVM, VERR_INVALID_PARAMETER);
     1452    AssertReturn(pNode->pVM == pSubTree->pVM, VERR_INVALID_PARAMETER);
    13551453    Assert(!pSubTree->pNext);
    13561454    Assert(!pSubTree->pPrev);
     
    13761474
    13771475        /* free the old subtree root */
    1378         pSubTree->pVM = NULL;
    1379         pSubTree->pFirstLeaf = NULL;
    1380         pSubTree->pFirstChild = NULL;
    1381         MMR3HeapFree(pSubTree);
     1476        cfgmR3FreeNodeOnly(pSubTree);
    13821477    }
    13831478    return rc;
     
    14071502    AssertReturn(pRoot != pNewRoot, VERR_INVALID_PARAMETER);
    14081503    AssertReturn(!pNewRoot->pParent, VERR_INVALID_PARAMETER);
    1409     AssertReturn(pNewRoot->pVM, VERR_INVALID_PARAMETER);
    14101504    AssertReturn(pNewRoot->pVM == pRoot->pVM, VERR_INVALID_PARAMETER);
    14111505    AssertReturn(!pNewRoot->pNext, VERR_INVALID_PARAMETER);
     
    14291523        pChild->pParent     = pRoot;
    14301524
    1431     pNewRoot->pFirstLeaf    = NULL;
    1432     pNewRoot->pFirstChild   = NULL;
    1433     pNewRoot->pVM           = NULL;
    1434     MMR3HeapFree(pNewRoot);
     1525    cfgmR3FreeNodeOnly(pNewRoot);
    14351526
    14361527    return VINF_SUCCESS;
     
    16441735             * Allocate and init node.
    16451736             */
    1646             PCFGMNODE pNew = (PCFGMNODE)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM, sizeof(*pNew) + cchName);
     1737            PCFGMNODE pNew = (PCFGMNODE)cfgmR3MemAlloc(pNode->pVM, MM_TAG_CFGM, sizeof(*pNew) + cchName);
    16471738            if (pNew)
    16481739            {
     
    17861877             * Allocate and init node.
    17871878             */
    1788             PCFGMLEAF pNew = (PCFGMLEAF)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM, sizeof(*pNew) + cchName);
     1879            PCFGMLEAF pNew = (PCFGMLEAF)cfgmR3MemAlloc(pNode->pVM, MM_TAG_CFGM, sizeof(*pNew) + cchName);
    17891880            if (pNew)
    17901881            {
     
    18561947
    18571948        /*
    1858          * Free ourselves. (bit of paranoia first)
     1949         * Free ourselves.
    18591950         */
    1860         pNode->pVM = NULL;
    1861         pNode->pNext = NULL;
    1862         pNode->pPrev = NULL;
    1863         pNode->pParent = NULL;
    1864         MMR3HeapFree(pNode);
     1951        cfgmR3FreeNodeOnly(pNode);
    18651952    }
    18661953}
     
    18901977         * Free value and node.
    18911978         */
    1892         cfgmR3FreeValue(pLeaf);
     1979        cfgmR3FreeValue(pNode->pVM, pLeaf);
    18931980        pLeaf->pNext = NULL;
    18941981        pLeaf->pPrev = NULL;
    1895         MMR3HeapFree(pLeaf);
     1982        cfgmR3MemFree(pNode->pVM, pLeaf);
    18961983    }
    18971984}
     
    19041991 * The caller must either free the leaf or assign a new value to it.
    19051992 *
     1993 * @param   pVM         Used to select the heap.
    19061994 * @param   pLeaf       Pointer to the leaf which value should be free.
    19071995 */
    1908 static void cfgmR3FreeValue(PCFGMLEAF pLeaf)
     1996static void cfgmR3FreeValue(PVM pVM, PCFGMLEAF pLeaf)
    19091997{
    19101998    if (pLeaf)
     
    19132001        {
    19142002            case CFGMVALUETYPE_BYTES:
    1915                 MMR3HeapFree(pLeaf->Value.Bytes.pau8);
     2003                cfgmR3MemFree(pVM, pLeaf->Value.Bytes.pau8);
    19162004                pLeaf->Value.Bytes.pau8 = NULL;
    19172005                pLeaf->Value.Bytes.cb = 0;
     
    19192007
    19202008            case CFGMVALUETYPE_STRING:
    1921                 MMR3HeapFree(pLeaf->Value.String.psz);
     2009                cfgmR3StrFree(pVM, pLeaf->Value.String.psz);
    19222010                pLeaf->Value.String.psz = NULL;
    19232011                pLeaf->Value.String.cb = 0;
     
    19742062         * Allocate string object first.
    19752063         */
    1976         char *pszStringCopy = (char *)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cchString + 1);
     2064        char *pszStringCopy = (char *)cfgmR3StrAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cchString + 1);
    19772065        if (pszStringCopy)
    19782066        {
     
    19922080            }
    19932081            else
    1994                 MMR3HeapFree(pszStringCopy);
     2082                cfgmR3StrFree(pNode->pVM, pszStringCopy);
    19952083        }
    19962084        else
     
    20372125         * Allocate string object first.
    20382126         */
    2039         char *pszString = MMR3HeapAPrintfVU(pNode->pVM->pUVM, MM_TAG_CFGM_STRING, pszFormat, va);
     2127        char *pszString;
     2128        if (!pNode->pVM)
     2129            pszString = RTStrAPrintf2(pszFormat, va);
     2130        else
     2131            pszString = MMR3HeapAPrintfVU(pNode->pVM->pUVM, MM_TAG_CFGM_STRING, pszFormat, va);
    20402132        if (pszString)
    20412133        {
     
    20522144            }
    20532145            else
    2054                 MMR3HeapFree(pszString);
     2146                cfgmR3StrFree(pNode->pVM, pszString);
    20552147        }
    20562148        else
     
    21242216             * Allocate string object first.
    21252217             */
    2126             void *pvCopy = MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cbBytes);
     2218            void *pvCopy = cfgmR3MemAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cbBytes);
    21272219            if (pvCopy || !cbBytes)
    21282220            {
     
    21402232                    pLeaf->Value.Bytes.pau8 = (uint8_t *)pvCopy;
    21412233                }
     2234                else
     2235                    cfgmR3MemFree(pNode->pVM, pvCopy);
    21422236            }
    21432237            else
     
    29183012 * @param   pszName         Value name. This value must be of zero terminated character string type.
    29193013 * @param   ppszString      Where to store the string pointer.
    2920  *                          Free this using MMR3HeapFree().
     3014 *                          Free this using MMR3HeapFree() (or RTStrFree if not
     3015 *                          associated with a pUVM - see CFGMR3CreateTree).
    29213016 */
    29223017VMMR3DECL(int) CFGMR3QueryStringAlloc(PCFGMNODE pNode, const char *pszName, char **ppszString)
     
    29263021    if (RT_SUCCESS(rc))
    29273022    {
    2928         char *pszString = (char *)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbString);
     3023        char *pszString = cfgmR3StrAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbString);
    29293024        if (pszString)
    29303025        {
     
    29333028                *ppszString = pszString;
    29343029            else
    2935                 MMR3HeapFree(pszString);
     3030                cfgmR3StrFree(pNode->pVM, pszString);
    29363031        }
    29373032        else
     
    29533048 * @param   pszName         Value name. This value must be of zero terminated character string type.
    29543049 * @param   ppszString      Where to store the string pointer. Not set on failure.
    2955  *                          Free this using MMR3HeapFree().
     3050 *                          Free this using MMR3HeapFree() (or RTStrFree if not
     3051 *                          associated with a pUVM - see CFGMR3CreateTree).
    29563052 * @param   pszDef          The default return value.  This can be NULL.
    29573053 */
     
    29713067        {
    29723068            size_t const cbSrc = pLeaf->Value.String.cb;
    2973             char *pszString = (char *)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbSrc);
     3069            char *pszString = cfgmR3StrAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbSrc);
    29743070            if (pszString)
    29753071            {
     
    29883084            *ppszString = NULL;
    29893085        else
    2990             *ppszString = MMR3HeapStrDup(pNode->pVM, MM_TAG_CFGM_USER, pszDef);
     3086        {
     3087            size_t const cbDef = strlen(pszDef) + 1;
     3088            *ppszString = cfgmR3StrAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbDef);
     3089            memcpy(*ppszString, pszDef, cbDef);
     3090        }
    29913091        if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
    29923092            rc = VINF_SUCCESS;
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