Changeset 46781 in vbox for trunk/src/VBox/VMM/VMMR3/CFGM.cpp
- Timestamp:
- Jun 25, 2013 2:04:17 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CFGM.cpp
r45189 r46781 66 66 #include <VBox/log.h> 67 67 #include <iprt/assert.h> 68 #include <iprt/mem.h> 68 69 #include <iprt/param.h> 69 70 #include <iprt/string.h> … … 81 82 static int cfgmR3InsertLeaf(PCFGMNODE pNode, const char *pszName, PCFGMLEAF *ppLeaf); 82 83 static void cfgmR3RemoveLeaf(PCFGMNODE pNode, PCFGMLEAF pLeaf); 83 static void cfgmR3FreeValue(PCFGMLEAF pLeaf); 84 static 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 */ 95 static 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 */ 110 static 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 */ 127 static 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 */ 142 static 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 */ 156 static 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 84 171 85 172 … … 1203 1290 * @returns Pointer to the root node, NULL on error (out of memory or invalid 1204 1291 * 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. 1206 1297 */ 1207 1298 VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PUVM pUVM) 1208 1299 { 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)); 1213 1311 if (pNew) 1214 1312 { … … 1218 1316 pNew->pFirstChild = NULL; 1219 1317 pNew->pFirstLeaf = NULL; 1220 pNew->pVM = pUVM ->pVM;1318 pNew->pVM = pUVM ? pUVM->pVM : NULL; 1221 1319 pNew->fRestrictedRoot = false; 1222 1320 pNew->cchName = 0; … … 1242 1340 * Create a new tree. 1243 1341 */ 1244 PCFGMNODE pNewRoot = CFGMR3CreateTree(pRoot->pVM ->pUVM);1342 PCFGMNODE pNewRoot = CFGMR3CreateTree(pRoot->pVM ? pRoot->pVM->pUVM : NULL); 1245 1343 if (!pNewRoot) 1246 1344 return VERR_NO_MEMORY; … … 1352 1450 AssertReturn(pNode != pSubTree, VERR_INVALID_PARAMETER); 1353 1451 AssertReturn(!pSubTree->pParent, VERR_INVALID_PARAMETER); 1354 AssertReturn(p SubTree->pVM, VERR_INVALID_PARAMETER);1452 AssertReturn(pNode->pVM == pSubTree->pVM, VERR_INVALID_PARAMETER); 1355 1453 Assert(!pSubTree->pNext); 1356 1454 Assert(!pSubTree->pPrev); … … 1376 1474 1377 1475 /* free the old subtree root */ 1378 pSubTree->pVM = NULL; 1379 pSubTree->pFirstLeaf = NULL; 1380 pSubTree->pFirstChild = NULL; 1381 MMR3HeapFree(pSubTree); 1476 cfgmR3FreeNodeOnly(pSubTree); 1382 1477 } 1383 1478 return rc; … … 1407 1502 AssertReturn(pRoot != pNewRoot, VERR_INVALID_PARAMETER); 1408 1503 AssertReturn(!pNewRoot->pParent, VERR_INVALID_PARAMETER); 1409 AssertReturn(pNewRoot->pVM, VERR_INVALID_PARAMETER);1410 1504 AssertReturn(pNewRoot->pVM == pRoot->pVM, VERR_INVALID_PARAMETER); 1411 1505 AssertReturn(!pNewRoot->pNext, VERR_INVALID_PARAMETER); … … 1429 1523 pChild->pParent = pRoot; 1430 1524 1431 pNewRoot->pFirstLeaf = NULL; 1432 pNewRoot->pFirstChild = NULL; 1433 pNewRoot->pVM = NULL; 1434 MMR3HeapFree(pNewRoot); 1525 cfgmR3FreeNodeOnly(pNewRoot); 1435 1526 1436 1527 return VINF_SUCCESS; … … 1644 1735 * Allocate and init node. 1645 1736 */ 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); 1647 1738 if (pNew) 1648 1739 { … … 1786 1877 * Allocate and init node. 1787 1878 */ 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); 1789 1880 if (pNew) 1790 1881 { … … 1856 1947 1857 1948 /* 1858 * Free ourselves. (bit of paranoia first)1949 * Free ourselves. 1859 1950 */ 1860 pNode->pVM = NULL; 1861 pNode->pNext = NULL; 1862 pNode->pPrev = NULL; 1863 pNode->pParent = NULL; 1864 MMR3HeapFree(pNode); 1951 cfgmR3FreeNodeOnly(pNode); 1865 1952 } 1866 1953 } … … 1890 1977 * Free value and node. 1891 1978 */ 1892 cfgmR3FreeValue(p Leaf);1979 cfgmR3FreeValue(pNode->pVM, pLeaf); 1893 1980 pLeaf->pNext = NULL; 1894 1981 pLeaf->pPrev = NULL; 1895 MMR3HeapFree(pLeaf);1982 cfgmR3MemFree(pNode->pVM, pLeaf); 1896 1983 } 1897 1984 } … … 1904 1991 * The caller must either free the leaf or assign a new value to it. 1905 1992 * 1993 * @param pVM Used to select the heap. 1906 1994 * @param pLeaf Pointer to the leaf which value should be free. 1907 1995 */ 1908 static void cfgmR3FreeValue(P CFGMLEAF pLeaf)1996 static void cfgmR3FreeValue(PVM pVM, PCFGMLEAF pLeaf) 1909 1997 { 1910 1998 if (pLeaf) … … 1913 2001 { 1914 2002 case CFGMVALUETYPE_BYTES: 1915 MMR3HeapFree(pLeaf->Value.Bytes.pau8);2003 cfgmR3MemFree(pVM, pLeaf->Value.Bytes.pau8); 1916 2004 pLeaf->Value.Bytes.pau8 = NULL; 1917 2005 pLeaf->Value.Bytes.cb = 0; … … 1919 2007 1920 2008 case CFGMVALUETYPE_STRING: 1921 MMR3HeapFree(pLeaf->Value.String.psz);2009 cfgmR3StrFree(pVM, pLeaf->Value.String.psz); 1922 2010 pLeaf->Value.String.psz = NULL; 1923 2011 pLeaf->Value.String.cb = 0; … … 1974 2062 * Allocate string object first. 1975 2063 */ 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); 1977 2065 if (pszStringCopy) 1978 2066 { … … 1992 2080 } 1993 2081 else 1994 MMR3HeapFree(pszStringCopy);2082 cfgmR3StrFree(pNode->pVM, pszStringCopy); 1995 2083 } 1996 2084 else … … 2037 2125 * Allocate string object first. 2038 2126 */ 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); 2040 2132 if (pszString) 2041 2133 { … … 2052 2144 } 2053 2145 else 2054 MMR3HeapFree(pszString);2146 cfgmR3StrFree(pNode->pVM, pszString); 2055 2147 } 2056 2148 else … … 2124 2216 * Allocate string object first. 2125 2217 */ 2126 void *pvCopy = MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cbBytes);2218 void *pvCopy = cfgmR3MemAlloc(pNode->pVM, MM_TAG_CFGM_STRING, cbBytes); 2127 2219 if (pvCopy || !cbBytes) 2128 2220 { … … 2140 2232 pLeaf->Value.Bytes.pau8 = (uint8_t *)pvCopy; 2141 2233 } 2234 else 2235 cfgmR3MemFree(pNode->pVM, pvCopy); 2142 2236 } 2143 2237 else … … 2918 3012 * @param pszName Value name. This value must be of zero terminated character string type. 2919 3013 * @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). 2921 3016 */ 2922 3017 VMMR3DECL(int) CFGMR3QueryStringAlloc(PCFGMNODE pNode, const char *pszName, char **ppszString) … … 2926 3021 if (RT_SUCCESS(rc)) 2927 3022 { 2928 char *pszString = (char *)MMR3HeapAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbString);3023 char *pszString = cfgmR3StrAlloc(pNode->pVM, MM_TAG_CFGM_USER, cbString); 2929 3024 if (pszString) 2930 3025 { … … 2933 3028 *ppszString = pszString; 2934 3029 else 2935 MMR3HeapFree(pszString);3030 cfgmR3StrFree(pNode->pVM, pszString); 2936 3031 } 2937 3032 else … … 2953 3048 * @param pszName Value name. This value must be of zero terminated character string type. 2954 3049 * @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). 2956 3052 * @param pszDef The default return value. This can be NULL. 2957 3053 */ … … 2971 3067 { 2972 3068 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); 2974 3070 if (pszString) 2975 3071 { … … 2988 3084 *ppszString = NULL; 2989 3085 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 } 2991 3091 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT) 2992 3092 rc = VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.