Changeset 37527 in vbox
- Timestamp:
- Jun 17, 2011 10:18:02 AM (14 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/TMAll.cpp
r37517 r37527 72 72 73 73 74 #ifndef tmTimerLock 75 76 /** 77 * Try take the timer lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC. 78 * 79 * @retval VINF_SUCCESS on success (always in ring-3). 80 * @retval VERR_SEM_BUSY in RC and R0 if the semaphore is busy. 81 * 74 /** 75 * Gets the current warp drive percent. 76 * 77 * @returns The warp drive percent. 82 78 * @param pVM The VM handle. 83 * 84 * @thread EMTs for the time being. 85 */ 86 int tmTimerLock(PVM pVM) 87 { 88 VM_ASSERT_EMT(pVM); 89 int rc = PDMCritSectEnter(&pVM->tm.s.TimerCritSect, VERR_SEM_BUSY); 90 return rc; 91 } 92 93 94 /** 95 * Try take the timer lock, no waiting. 96 * 97 * @retval VINF_SUCCESS on success. 98 * @retval VERR_SEM_BUSY if busy. 99 * 100 * @param pVM The VM handle. 101 */ 102 int tmTimerTryLock(PVM pVM) 103 { 104 int rc = PDMCritSectTryEnter(&pVM->tm.s.TimerCritSect); 105 return rc; 106 } 107 108 109 /** 110 * Release the EMT/TM lock. 111 * 112 * @param pVM The VM handle. 113 */ 114 void tmTimerUnlock(PVM pVM) 115 { 116 PDMCritSectLeave(&pVM->tm.s.TimerCritSect); 117 } 118 119 120 /** 121 * Try take the VirtualSync lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC. 122 * 123 * @retval VINF_SUCCESS on success (always in ring-3). 124 * @retval VERR_SEM_BUSY in RC and R0 if the semaphore is busy. 125 * 126 * @param pVM The VM handle. 127 */ 128 int tmVirtualSyncLock(PVM pVM) 129 { 130 VM_ASSERT_EMT(pVM); 131 int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_SEM_BUSY); 132 return rc; 133 } 134 135 136 /** 137 * Try take the VirtualSync lock, no waiting. 138 * 139 * @retval VINF_SUCCESS on success. 140 * @retval VERR_SEM_BUSY if busy. 141 * 142 * @param pVM The VM handle. 143 */ 144 int tmVirtualSyncTryLock(PVM pVM) 145 { 146 VM_ASSERT_EMT(pVM); 147 int rc = PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock); 148 return rc; 149 } 150 151 152 /** 153 * Release the VirtualSync lock. 154 * 155 * @param pVM The VM handle. 156 */ 157 void tmVirtualSyncUnlock(PVM pVM) 158 { 159 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 160 } 161 162 #endif /* ! macros */ 79 */ 80 VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM) 81 { 82 return pVM->tm.s.u32VirtualWarpDrivePercentage; 83 } 84 163 85 164 86 /** … … 327 249 PVM pVM = pTimer->CTX_SUFF(pVM); 328 250 if ( VM_IS_EMT(pVM) 329 && RT_SUCCESS( tmTimerTryLock(pVM)))251 && RT_SUCCESS(TM_TRY_LOCK_TIMERS(pVM))) 330 252 { 331 253 STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatScheduleOne), a); … … 336 258 #endif 337 259 STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatScheduleOne), a); 338 tmTimerUnlock(pVM);260 TM_UNLOCK_TIMERS(pVM); 339 261 } 340 262 else … … 568 490 void tmTimerQueueSchedule(PVM pVM, PTMTIMERQUEUE pQueue) 569 491 { 570 TM_ASSERT_ LOCK(pVM);492 TM_ASSERT_TIMER_LOCK_OWNERSHIP(pVM); 571 493 572 494 /* … … 609 531 void tmTimerQueuesSanityChecks(PVM pVM, const char *pszWhere) 610 532 { 611 TM_ASSERT_ LOCK(pVM);533 TM_ASSERT_TIMER_LOCK_OWNERSHIP(pVM); 612 534 613 535 /* … … 1195 1117 1196 1118 STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetOpt); 1197 tmTimerUnlock(pVM);1119 TM_UNLOCK_TIMERS(pVM); 1198 1120 return VINF_SUCCESS; 1199 1121 } … … 1215 1137 STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerSetVs), a); 1216 1138 VM_ASSERT_EMT(pVM); 1139 Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock)); 1217 1140 int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VINF_SUCCESS); 1218 1141 AssertRCReturn(rc, rc); … … 1320 1243 { 1321 1244 /* Try take the TM lock and check the state again. */ 1322 if (RT_SUCCESS_NP( tmTimerTryLock(pVM)))1245 if (RT_SUCCESS_NP(TM_TRY_LOCK_TIMERS(pVM))) 1323 1246 { 1324 1247 if (RT_LIKELY(tmTimerTry(pTimer, TMTIMERSTATE_ACTIVE, enmState1))) … … 1328 1251 return VINF_SUCCESS; 1329 1252 } 1330 tmTimerUnlock(pVM);1253 TM_UNLOCK_TIMERS(pVM); 1331 1254 } 1332 1255 } … … 1492 1415 1493 1416 STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetRelativeOpt); 1494 tmTimerUnlock(pVM);1417 TM_UNLOCK_TIMERS(pVM); 1495 1418 return VINF_SUCCESS; 1496 1419 } … … 1513 1436 STAM_PROFILE_START(pVM->tm.s.CTX_SUFF_Z(StatTimerSetRelativeVs), a); 1514 1437 VM_ASSERT_EMT(pVM); 1438 Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock)); 1515 1439 int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VINF_SUCCESS); 1516 1440 AssertRCReturn(rc, rc); … … 1626 1550 * get the innermost locks. 1627 1551 */ 1628 bool fOwnTMLock = RT_SUCCESS_NP( tmTimerTryLock(pVM));1552 bool fOwnTMLock = RT_SUCCESS_NP(TM_TRY_LOCK_TIMERS(pVM)); 1629 1553 #if 1 1630 1554 if ( fOwnTMLock … … 1778 1702 */ 1779 1703 if (!fOwnTMLock) 1780 fOwnTMLock = RT_SUCCESS_NP( tmTimerTryLock(pVM));1704 fOwnTMLock = RT_SUCCESS_NP(TM_TRY_LOCK_TIMERS(pVM)); 1781 1705 1782 1706 } /* for (;;) */ … … 1786 1710 */ 1787 1711 if (fOwnTMLock) 1788 tmTimerUnlock(pVM);1712 TM_UNLOCK_TIMERS(pVM); 1789 1713 1790 1714 STAM_PROFILE_STOP(&pTimer->CTX_SUFF(pVM)->tm.s.CTX_SUFF_Z(StatTimerSetRelative), a); 1791 1715 return rc; 1792 }1793 1794 1795 /**1796 * Arm a timer with a (new) expire time relative to current time.1797 *1798 * @returns VBox status.1799 * @param pTimer Timer handle as returned by one of the create functions.1800 * @param cMilliesToNext Number of milliseconds to the next tick.1801 */1802 VMMDECL(int) TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext)1803 {1804 PVM pVM = pTimer->CTX_SUFF(pVM);1805 PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */1806 1807 switch (pTimer->enmClock)1808 {1809 case TMCLOCK_VIRTUAL:1810 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);1811 return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);1812 1813 case TMCLOCK_VIRTUAL_SYNC:1814 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);1815 return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL);1816 1817 case TMCLOCK_REAL:1818 AssertCompile(TMCLOCK_FREQ_REAL == 1000);1819 return TMTimerSetRelative(pTimer, cMilliesToNext, NULL);1820 1821 default:1822 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));1823 return VERR_INTERNAL_ERROR;1824 }1825 }1826 1827 1828 /**1829 * Arm a timer with a (new) expire time relative to current time.1830 *1831 * @returns VBox status.1832 * @param pTimer Timer handle as returned by one of the create functions.1833 * @param cMicrosToNext Number of microseconds to the next tick.1834 */1835 VMMDECL(int) TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext)1836 {1837 PVM pVM = pTimer->CTX_SUFF(pVM);1838 PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */1839 1840 switch (pTimer->enmClock)1841 {1842 case TMCLOCK_VIRTUAL:1843 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);1844 return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);1845 1846 case TMCLOCK_VIRTUAL_SYNC:1847 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);1848 return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL);1849 1850 case TMCLOCK_REAL:1851 AssertCompile(TMCLOCK_FREQ_REAL == 1000);1852 return TMTimerSetRelative(pTimer, cMicrosToNext / 1000, NULL);1853 1854 default:1855 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));1856 return VERR_INTERNAL_ERROR;1857 }1858 }1859 1860 1861 /**1862 * Arm a timer with a (new) expire time relative to current time.1863 *1864 * @returns VBox status.1865 * @param pTimer Timer handle as returned by one of the create functions.1866 * @param cNanosToNext Number of nanoseconds to the next tick.1867 */1868 VMMDECL(int) TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext)1869 {1870 PVM pVM = pTimer->CTX_SUFF(pVM);1871 PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */1872 1873 switch (pTimer->enmClock)1874 {1875 case TMCLOCK_VIRTUAL:1876 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);1877 return TMTimerSetRelative(pTimer, cNanosToNext, NULL);1878 1879 case TMCLOCK_VIRTUAL_SYNC:1880 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);1881 return TMTimerSetRelative(pTimer, cNanosToNext, NULL);1882 1883 case TMCLOCK_REAL:1884 AssertCompile(TMCLOCK_FREQ_REAL == 1000);1885 return TMTimerSetRelative(pTimer, cNanosToNext / 1000000, NULL);1886 1887 default:1888 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));1889 return VERR_INTERNAL_ERROR;1890 }1891 1716 } 1892 1717 … … 1938 1763 STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerStopVs), a); 1939 1764 VM_ASSERT_EMT(pVM); 1765 Assert(PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock)); 1940 1766 int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VINF_SUCCESS); 1941 1767 AssertRCReturn(rc, rc); … … 2149 1975 case TMCLOCK_REAL: 2150 1976 return TMCLOCK_FREQ_REAL; 2151 2152 default:2153 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));2154 return 0;2155 }2156 }2157 2158 2159 /**2160 * Get the current clock time as nanoseconds.2161 *2162 * @returns The timer clock as nanoseconds.2163 * @param pTimer Timer handle as returned by one of the create functions.2164 */2165 VMMDECL(uint64_t) TMTimerGetNano(PTMTIMER pTimer)2166 {2167 return TMTimerToNano(pTimer, TMTimerGet(pTimer));2168 }2169 2170 2171 /**2172 * Get the current clock time as microseconds.2173 *2174 * @returns The timer clock as microseconds.2175 * @param pTimer Timer handle as returned by one of the create functions.2176 */2177 VMMDECL(uint64_t) TMTimerGetMicro(PTMTIMER pTimer)2178 {2179 return TMTimerToMicro(pTimer, TMTimerGet(pTimer));2180 }2181 2182 2183 /**2184 * Get the current clock time as milliseconds.2185 *2186 * @returns The timer clock as milliseconds.2187 * @param pTimer Timer handle as returned by one of the create functions.2188 */2189 VMMDECL(uint64_t) TMTimerGetMilli(PTMTIMER pTimer)2190 {2191 return TMTimerToMilli(pTimer, TMTimerGet(pTimer));2192 }2193 2194 2195 /**2196 * Converts the specified timer clock time to nanoseconds.2197 *2198 * @returns nanoseconds.2199 * @param pTimer Timer handle as returned by one of the create functions.2200 * @param u64Ticks The clock ticks.2201 * @remark There could be rounding errors here. We just do a simple integer divide2202 * without any adjustments.2203 */2204 VMMDECL(uint64_t) TMTimerToNano(PTMTIMER pTimer, uint64_t u64Ticks)2205 {2206 switch (pTimer->enmClock)2207 {2208 case TMCLOCK_VIRTUAL:2209 case TMCLOCK_VIRTUAL_SYNC:2210 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);2211 return u64Ticks;2212 2213 case TMCLOCK_REAL:2214 AssertCompile(TMCLOCK_FREQ_REAL == 1000);2215 return u64Ticks * 1000000;2216 2217 default:2218 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));2219 return 0;2220 }2221 }2222 2223 2224 /**2225 * Converts the specified timer clock time to microseconds.2226 *2227 * @returns microseconds.2228 * @param pTimer Timer handle as returned by one of the create functions.2229 * @param u64Ticks The clock ticks.2230 * @remark There could be rounding errors here. We just do a simple integer divide2231 * without any adjustments.2232 */2233 VMMDECL(uint64_t) TMTimerToMicro(PTMTIMER pTimer, uint64_t u64Ticks)2234 {2235 switch (pTimer->enmClock)2236 {2237 case TMCLOCK_VIRTUAL:2238 case TMCLOCK_VIRTUAL_SYNC:2239 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);2240 return u64Ticks / 1000;2241 2242 case TMCLOCK_REAL:2243 AssertCompile(TMCLOCK_FREQ_REAL == 1000);2244 return u64Ticks * 1000;2245 2246 default:2247 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));2248 return 0;2249 }2250 }2251 2252 2253 /**2254 * Converts the specified timer clock time to milliseconds.2255 *2256 * @returns milliseconds.2257 * @param pTimer Timer handle as returned by one of the create functions.2258 * @param u64Ticks The clock ticks.2259 * @remark There could be rounding errors here. We just do a simple integer divide2260 * without any adjustments.2261 */2262 VMMDECL(uint64_t) TMTimerToMilli(PTMTIMER pTimer, uint64_t u64Ticks)2263 {2264 switch (pTimer->enmClock)2265 {2266 case TMCLOCK_VIRTUAL:2267 case TMCLOCK_VIRTUAL_SYNC:2268 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);2269 return u64Ticks / 1000000;2270 2271 case TMCLOCK_REAL:2272 AssertCompile(TMCLOCK_FREQ_REAL == 1000);2273 return u64Ticks;2274 2275 default:2276 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));2277 return 0;2278 }2279 }2280 2281 2282 /**2283 * Converts the specified nanosecond timestamp to timer clock ticks.2284 *2285 * @returns timer clock ticks.2286 * @param pTimer Timer handle as returned by one of the create functions.2287 * @param cNanoSecs The nanosecond value ticks to convert.2288 * @remark There could be rounding and overflow errors here.2289 */2290 VMMDECL(uint64_t) TMTimerFromNano(PTMTIMER pTimer, uint64_t cNanoSecs)2291 {2292 switch (pTimer->enmClock)2293 {2294 case TMCLOCK_VIRTUAL:2295 case TMCLOCK_VIRTUAL_SYNC:2296 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);2297 return cNanoSecs;2298 2299 case TMCLOCK_REAL:2300 AssertCompile(TMCLOCK_FREQ_REAL == 1000);2301 return cNanoSecs / 1000000;2302 2303 default:2304 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));2305 return 0;2306 }2307 }2308 2309 2310 /**2311 * Converts the specified microsecond timestamp to timer clock ticks.2312 *2313 * @returns timer clock ticks.2314 * @param pTimer Timer handle as returned by one of the create functions.2315 * @param cMicroSecs The microsecond value ticks to convert.2316 * @remark There could be rounding and overflow errors here.2317 */2318 VMMDECL(uint64_t) TMTimerFromMicro(PTMTIMER pTimer, uint64_t cMicroSecs)2319 {2320 switch (pTimer->enmClock)2321 {2322 case TMCLOCK_VIRTUAL:2323 case TMCLOCK_VIRTUAL_SYNC:2324 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);2325 return cMicroSecs * 1000;2326 2327 case TMCLOCK_REAL:2328 AssertCompile(TMCLOCK_FREQ_REAL == 1000);2329 return cMicroSecs / 1000;2330 2331 default:2332 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));2333 return 0;2334 }2335 }2336 2337 2338 /**2339 * Converts the specified millisecond timestamp to timer clock ticks.2340 *2341 * @returns timer clock ticks.2342 * @param pTimer Timer handle as returned by one of the create functions.2343 * @param cMilliSecs The millisecond value ticks to convert.2344 * @remark There could be rounding and overflow errors here.2345 */2346 VMMDECL(uint64_t) TMTimerFromMilli(PTMTIMER pTimer, uint64_t cMilliSecs)2347 {2348 switch (pTimer->enmClock)2349 {2350 case TMCLOCK_VIRTUAL:2351 case TMCLOCK_VIRTUAL_SYNC:2352 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);2353 return cMilliSecs * 1000000;2354 2355 case TMCLOCK_REAL:2356 AssertCompile(TMCLOCK_FREQ_REAL == 1000);2357 return cMilliSecs;2358 1977 2359 1978 default: … … 2472 2091 2473 2092 2474 /** 2475 * Gets the current warp drive percent. 2476 * 2477 * @returns The warp drive percent. 2478 * @param pVM The VM handle. 2479 */ 2480 VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM) 2481 { 2482 return pVM->tm.s.u32VirtualWarpDrivePercentage; 2093 /* -=-=-=-=-=-=- Convenience APIs -=-=-=-=-=-=- */ 2094 2095 2096 /** 2097 * Arm a timer with a (new) expire time relative to current time. 2098 * 2099 * @returns VBox status. 2100 * @param pTimer Timer handle as returned by one of the create functions. 2101 * @param cMilliesToNext Number of milliseconds to the next tick. 2102 */ 2103 VMMDECL(int) TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext) 2104 { 2105 PVM pVM = pTimer->CTX_SUFF(pVM); 2106 PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */ 2107 2108 switch (pTimer->enmClock) 2109 { 2110 case TMCLOCK_VIRTUAL: 2111 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2112 return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL); 2113 2114 case TMCLOCK_VIRTUAL_SYNC: 2115 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2116 return TMTimerSetRelative(pTimer, cMilliesToNext * UINT64_C(1000000), NULL); 2117 2118 case TMCLOCK_REAL: 2119 AssertCompile(TMCLOCK_FREQ_REAL == 1000); 2120 return TMTimerSetRelative(pTimer, cMilliesToNext, NULL); 2121 2122 default: 2123 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock)); 2124 return VERR_INTERNAL_ERROR; 2125 } 2126 } 2127 2128 2129 /** 2130 * Arm a timer with a (new) expire time relative to current time. 2131 * 2132 * @returns VBox status. 2133 * @param pTimer Timer handle as returned by one of the create functions. 2134 * @param cMicrosToNext Number of microseconds to the next tick. 2135 */ 2136 VMMDECL(int) TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext) 2137 { 2138 PVM pVM = pTimer->CTX_SUFF(pVM); 2139 PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */ 2140 2141 switch (pTimer->enmClock) 2142 { 2143 case TMCLOCK_VIRTUAL: 2144 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2145 return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL); 2146 2147 case TMCLOCK_VIRTUAL_SYNC: 2148 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2149 return TMTimerSetRelative(pTimer, cMicrosToNext * 1000, NULL); 2150 2151 case TMCLOCK_REAL: 2152 AssertCompile(TMCLOCK_FREQ_REAL == 1000); 2153 return TMTimerSetRelative(pTimer, cMicrosToNext / 1000, NULL); 2154 2155 default: 2156 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock)); 2157 return VERR_INTERNAL_ERROR; 2158 } 2159 } 2160 2161 2162 /** 2163 * Arm a timer with a (new) expire time relative to current time. 2164 * 2165 * @returns VBox status. 2166 * @param pTimer Timer handle as returned by one of the create functions. 2167 * @param cNanosToNext Number of nanoseconds to the next tick. 2168 */ 2169 VMMDECL(int) TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext) 2170 { 2171 PVM pVM = pTimer->CTX_SUFF(pVM); 2172 PVMCPU pVCpu = &pVM->aCpus[0]; /* just take the first VCPU */ 2173 2174 switch (pTimer->enmClock) 2175 { 2176 case TMCLOCK_VIRTUAL: 2177 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2178 return TMTimerSetRelative(pTimer, cNanosToNext, NULL); 2179 2180 case TMCLOCK_VIRTUAL_SYNC: 2181 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2182 return TMTimerSetRelative(pTimer, cNanosToNext, NULL); 2183 2184 case TMCLOCK_REAL: 2185 AssertCompile(TMCLOCK_FREQ_REAL == 1000); 2186 return TMTimerSetRelative(pTimer, cNanosToNext / 1000000, NULL); 2187 2188 default: 2189 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock)); 2190 return VERR_INTERNAL_ERROR; 2191 } 2192 } 2193 2194 2195 /** 2196 * Get the current clock time as nanoseconds. 2197 * 2198 * @returns The timer clock as nanoseconds. 2199 * @param pTimer Timer handle as returned by one of the create functions. 2200 */ 2201 VMMDECL(uint64_t) TMTimerGetNano(PTMTIMER pTimer) 2202 { 2203 return TMTimerToNano(pTimer, TMTimerGet(pTimer)); 2204 } 2205 2206 2207 /** 2208 * Get the current clock time as microseconds. 2209 * 2210 * @returns The timer clock as microseconds. 2211 * @param pTimer Timer handle as returned by one of the create functions. 2212 */ 2213 VMMDECL(uint64_t) TMTimerGetMicro(PTMTIMER pTimer) 2214 { 2215 return TMTimerToMicro(pTimer, TMTimerGet(pTimer)); 2216 } 2217 2218 2219 /** 2220 * Get the current clock time as milliseconds. 2221 * 2222 * @returns The timer clock as milliseconds. 2223 * @param pTimer Timer handle as returned by one of the create functions. 2224 */ 2225 VMMDECL(uint64_t) TMTimerGetMilli(PTMTIMER pTimer) 2226 { 2227 return TMTimerToMilli(pTimer, TMTimerGet(pTimer)); 2228 } 2229 2230 2231 /** 2232 * Converts the specified timer clock time to nanoseconds. 2233 * 2234 * @returns nanoseconds. 2235 * @param pTimer Timer handle as returned by one of the create functions. 2236 * @param u64Ticks The clock ticks. 2237 * @remark There could be rounding errors here. We just do a simple integer divide 2238 * without any adjustments. 2239 */ 2240 VMMDECL(uint64_t) TMTimerToNano(PTMTIMER pTimer, uint64_t u64Ticks) 2241 { 2242 switch (pTimer->enmClock) 2243 { 2244 case TMCLOCK_VIRTUAL: 2245 case TMCLOCK_VIRTUAL_SYNC: 2246 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2247 return u64Ticks; 2248 2249 case TMCLOCK_REAL: 2250 AssertCompile(TMCLOCK_FREQ_REAL == 1000); 2251 return u64Ticks * 1000000; 2252 2253 default: 2254 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock)); 2255 return 0; 2256 } 2257 } 2258 2259 2260 /** 2261 * Converts the specified timer clock time to microseconds. 2262 * 2263 * @returns microseconds. 2264 * @param pTimer Timer handle as returned by one of the create functions. 2265 * @param u64Ticks The clock ticks. 2266 * @remark There could be rounding errors here. We just do a simple integer divide 2267 * without any adjustments. 2268 */ 2269 VMMDECL(uint64_t) TMTimerToMicro(PTMTIMER pTimer, uint64_t u64Ticks) 2270 { 2271 switch (pTimer->enmClock) 2272 { 2273 case TMCLOCK_VIRTUAL: 2274 case TMCLOCK_VIRTUAL_SYNC: 2275 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2276 return u64Ticks / 1000; 2277 2278 case TMCLOCK_REAL: 2279 AssertCompile(TMCLOCK_FREQ_REAL == 1000); 2280 return u64Ticks * 1000; 2281 2282 default: 2283 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock)); 2284 return 0; 2285 } 2286 } 2287 2288 2289 /** 2290 * Converts the specified timer clock time to milliseconds. 2291 * 2292 * @returns milliseconds. 2293 * @param pTimer Timer handle as returned by one of the create functions. 2294 * @param u64Ticks The clock ticks. 2295 * @remark There could be rounding errors here. We just do a simple integer divide 2296 * without any adjustments. 2297 */ 2298 VMMDECL(uint64_t) TMTimerToMilli(PTMTIMER pTimer, uint64_t u64Ticks) 2299 { 2300 switch (pTimer->enmClock) 2301 { 2302 case TMCLOCK_VIRTUAL: 2303 case TMCLOCK_VIRTUAL_SYNC: 2304 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2305 return u64Ticks / 1000000; 2306 2307 case TMCLOCK_REAL: 2308 AssertCompile(TMCLOCK_FREQ_REAL == 1000); 2309 return u64Ticks; 2310 2311 default: 2312 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock)); 2313 return 0; 2314 } 2315 } 2316 2317 2318 /** 2319 * Converts the specified nanosecond timestamp to timer clock ticks. 2320 * 2321 * @returns timer clock ticks. 2322 * @param pTimer Timer handle as returned by one of the create functions. 2323 * @param cNanoSecs The nanosecond value ticks to convert. 2324 * @remark There could be rounding and overflow errors here. 2325 */ 2326 VMMDECL(uint64_t) TMTimerFromNano(PTMTIMER pTimer, uint64_t cNanoSecs) 2327 { 2328 switch (pTimer->enmClock) 2329 { 2330 case TMCLOCK_VIRTUAL: 2331 case TMCLOCK_VIRTUAL_SYNC: 2332 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2333 return cNanoSecs; 2334 2335 case TMCLOCK_REAL: 2336 AssertCompile(TMCLOCK_FREQ_REAL == 1000); 2337 return cNanoSecs / 1000000; 2338 2339 default: 2340 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock)); 2341 return 0; 2342 } 2343 } 2344 2345 2346 /** 2347 * Converts the specified microsecond timestamp to timer clock ticks. 2348 * 2349 * @returns timer clock ticks. 2350 * @param pTimer Timer handle as returned by one of the create functions. 2351 * @param cMicroSecs The microsecond value ticks to convert. 2352 * @remark There could be rounding and overflow errors here. 2353 */ 2354 VMMDECL(uint64_t) TMTimerFromMicro(PTMTIMER pTimer, uint64_t cMicroSecs) 2355 { 2356 switch (pTimer->enmClock) 2357 { 2358 case TMCLOCK_VIRTUAL: 2359 case TMCLOCK_VIRTUAL_SYNC: 2360 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2361 return cMicroSecs * 1000; 2362 2363 case TMCLOCK_REAL: 2364 AssertCompile(TMCLOCK_FREQ_REAL == 1000); 2365 return cMicroSecs / 1000; 2366 2367 default: 2368 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock)); 2369 return 0; 2370 } 2371 } 2372 2373 2374 /** 2375 * Converts the specified millisecond timestamp to timer clock ticks. 2376 * 2377 * @returns timer clock ticks. 2378 * @param pTimer Timer handle as returned by one of the create functions. 2379 * @param cMilliSecs The millisecond value ticks to convert. 2380 * @remark There could be rounding and overflow errors here. 2381 */ 2382 VMMDECL(uint64_t) TMTimerFromMilli(PTMTIMER pTimer, uint64_t cMilliSecs) 2383 { 2384 switch (pTimer->enmClock) 2385 { 2386 case TMCLOCK_VIRTUAL: 2387 case TMCLOCK_VIRTUAL_SYNC: 2388 AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000); 2389 return cMilliSecs * 1000000; 2390 2391 case TMCLOCK_REAL: 2392 AssertCompile(TMCLOCK_FREQ_REAL == 1000); 2393 return cMilliSecs; 2394 2395 default: 2396 AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock)); 2397 return 0; 2398 } 2483 2399 } 2484 2400 … … 2535 2451 if (RT_UNLIKELY(ASMAtomicReadBool(&pVM->tm.s.fHzHintNeedsUpdating))) 2536 2452 { 2537 if (RT_SUCCESS( tmTimerTryLock(pVM)))2453 if (RT_SUCCESS(TM_TRY_LOCK_TIMERS(pVM))) 2538 2454 { 2539 2455 ASMAtomicWriteBool(&pVM->tm.s.fHzHintNeedsUpdating, false); … … 2576 2492 ASMAtomicWriteU32(&pVM->tm.s.uMaxHzHint, uMaxHzHint); 2577 2493 Log(("tmGetFrequencyHint: New value %u Hz\n", uMaxHzHint)); 2578 tmTimerUnlock(pVM);2494 TM_UNLOCK_TIMERS(pVM); 2579 2495 } 2580 2496 } -
trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
r37517 r37527 488 488 *pcNsToDeadline = tmVirtualVirtToNsDeadline(pVM, cNsToDeadline); 489 489 } 490 tmVirtualSyncUnlock(pVM);490 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 491 491 } 492 492 else … … 501 501 Log5(("TMAllVirtual(%u): FF: %d -> 1\n", __LINE__, VMCPU_FF_ISPENDING(pVCpuDst, VMCPU_FF_TIMER))); 502 502 Log4(("TM: %'RU64/-%'8RU64: exp tmr=>ff [vsghcul]\n", u64, pVM->tm.s.offVirtualSync - pVM->tm.s.offVirtualSyncGivenUp)); 503 tmVirtualSyncUnlock(pVM);503 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 504 504 505 505 if (pcNsToDeadline) … … 538 538 { 539 539 u64 = ASMAtomicUoReadU64(&pVM->tm.s.u64VirtualSync); 540 tmVirtualSyncUnlock(pVM);540 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 541 541 if (pcNsToDeadline) 542 542 *pcNsToDeadline = 0; … … 572 572 { 573 573 ASMAtomicWriteU64(&pVM->tm.s.u64VirtualSync, u64); 574 tmVirtualSyncUnlock(pVM);574 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 575 575 if (pcNsToDeadline) 576 576 *pcNsToDeadline = tmVirtualVirtToNsDeadline(pVM, u64Expire - u64); … … 587 587 Log5(("TMAllVirtual(%u): FF: %d -> 1\n", __LINE__, !!VMCPU_FF_ISPENDING(pVCpuDst, VMCPU_FF_TIMER))); 588 588 Log4(("TM: %'RU64/-%'8RU64: exp tmr=>ff [vsgl]\n", u64, pVM->tm.s.offVirtualSync - pVM->tm.s.offVirtualSyncGivenUp)); 589 tmVirtualSyncUnlock(pVM);589 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 590 590 591 591 #ifdef IN_RING3 … … 658 658 * which is less picky or hasn't been adjusted yet 659 659 */ 660 if ( tmVirtualSyncTryLock(pVM) == VINF_SUCCESS)660 if (PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock) == VINF_SUCCESS) 661 661 return tmVirtualSyncGetLocked(pVM, u64, pcNsToDeadline); 662 662 … … 726 726 { 727 727 /* Try grab the lock, things get simpler when owning the lock. */ 728 int rcLock = tmVirtualSyncTryLock(pVM);728 int rcLock = PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock); 729 729 if (RT_SUCCESS_NP(rcLock)) 730 730 return tmVirtualSyncGetLocked(pVM, u64, pcNsToDeadline); -
trunk/src/VBox/VMM/VMMR3/TM.cpp
r37518 r37527 1038 1038 LogFlow(("TMR3Reset:\n")); 1039 1039 VM_ASSERT_EMT(pVM); 1040 tmTimerLock(pVM);1040 TM_LOCK_TIMERS(pVM); 1041 1041 1042 1042 /* … … 1073 1073 PVMCPU pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu]; 1074 1074 VMCPU_FF_CLEAR(pVCpuDst, VMCPU_FF_TIMER); /** @todo FIXME: this isn't right. */ 1075 tmTimerUnlock(pVM);1075 TM_UNLOCK_TIMERS(pVM); 1076 1076 } 1077 1077 … … 1302 1302 1303 1303 /* insert into the list of created timers. */ 1304 tmTimerLock(pVM);1304 TM_LOCK_TIMERS(pVM); 1305 1305 pTimer->pBigPrev = NULL; 1306 1306 pTimer->pBigNext = pVM->tm.s.pCreated; … … 1311 1311 tmTimerQueuesSanityChecks(pVM, "tmR3TimerCreate"); 1312 1312 #endif 1313 tmTimerUnlock(pVM);1313 TM_UNLOCK_TIMERS(pVM); 1314 1314 1315 1315 *ppTimer = pTimer; … … 1531 1531 * like create does. All the work is done here. 1532 1532 */ 1533 tmTimerLock(pVM);1533 TM_LOCK_TIMERS(pVM); 1534 1534 for (int cRetries = 1000;; cRetries--) 1535 1535 { … … 1569 1569 case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE: 1570 1570 AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc)); 1571 tmTimerUnlock(pVM);1571 TM_UNLOCK_TIMERS(pVM); 1572 1572 if (!RTThreadYield()) 1573 1573 RTThreadSleep(1); 1574 1574 AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc), 1575 1575 VERR_TM_UNSTABLE_STATE); 1576 tmTimerLock(pVM);1576 TM_LOCK_TIMERS(pVM); 1577 1577 continue; 1578 1578 … … 1582 1582 case TMTIMERSTATE_FREE: 1583 1583 case TMTIMERSTATE_DESTROY: 1584 tmTimerUnlock(pVM);1584 TM_UNLOCK_TIMERS(pVM); 1585 1585 AssertLogRelMsgFailedReturn(("pTimer=%p %s\n", pTimer, tmTimerState(enmState)), VERR_TM_INVALID_STATE); 1586 1586 1587 1587 default: 1588 1588 AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc))); 1589 tmTimerUnlock(pVM);1589 TM_UNLOCK_TIMERS(pVM); 1590 1590 return VERR_TM_UNKNOWN_STATE; 1591 1591 } … … 1600 1600 break; 1601 1601 AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc)); 1602 tmTimerUnlock(pVM);1602 TM_UNLOCK_TIMERS(pVM); 1603 1603 AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc), 1604 1604 VERR_TM_UNSTABLE_STATE); 1605 tmTimerLock(pVM);1605 TM_LOCK_TIMERS(pVM); 1606 1606 } 1607 1607 … … 1661 1661 tmTimerQueuesSanityChecks(pVM, "TMR3TimerDestroy"); 1662 1662 #endif 1663 tmTimerUnlock(pVM);1663 TM_UNLOCK_TIMERS(pVM); 1664 1664 return VINF_SUCCESS; 1665 1665 } … … 1679 1679 return VERR_INVALID_PARAMETER; 1680 1680 1681 tmTimerLock(pVM);1681 TM_LOCK_TIMERS(pVM); 1682 1682 PTMTIMER pCur = pVM->tm.s.pCreated; 1683 1683 while (pCur) … … 1692 1692 } 1693 1693 } 1694 tmTimerUnlock(pVM);1694 TM_UNLOCK_TIMERS(pVM); 1695 1695 1696 1696 LogFlow(("TMR3TimerDestroyDevice: returns VINF_SUCCESS\n")); … … 1712 1712 return VERR_INVALID_PARAMETER; 1713 1713 1714 tmTimerLock(pVM);1714 TM_LOCK_TIMERS(pVM); 1715 1715 PTMTIMER pCur = pVM->tm.s.pCreated; 1716 1716 while (pCur) … … 1725 1725 } 1726 1726 } 1727 tmTimerUnlock(pVM);1727 TM_UNLOCK_TIMERS(pVM); 1728 1728 1729 1729 LogFlow(("TMR3TimerDestroyUsb: returns VINF_SUCCESS\n")); … … 1745 1745 return VERR_INVALID_PARAMETER; 1746 1746 1747 tmTimerLock(pVM);1747 TM_LOCK_TIMERS(pVM); 1748 1748 PTMTIMER pCur = pVM->tm.s.pCreated; 1749 1749 while (pCur) … … 1758 1758 } 1759 1759 } 1760 tmTimerUnlock(pVM);1760 TM_UNLOCK_TIMERS(pVM); 1761 1761 1762 1762 LogFlow(("TMR3TimerDestroyDriver: returns VINF_SUCCESS\n")); … … 1902 1902 Assert(!pVM->tm.s.fRunningQueues); 1903 1903 ASMAtomicWriteBool(&pVM->tm.s.fRunningQueues, true); 1904 tmTimerLock(pVM);1904 TM_LOCK_TIMERS(pVM); 1905 1905 1906 1906 /* … … 1911 1911 /* TMCLOCK_VIRTUAL_SYNC (see also TMR3VirtualSyncFF) */ 1912 1912 STAM_PROFILE_ADV_START(&pVM->tm.s.aStatDoQueues[TMCLOCK_VIRTUAL_SYNC], s1); 1913 tmVirtualSyncLock(pVM);1913 PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED); 1914 1914 ASMAtomicWriteBool(&pVM->tm.s.fRunningVirtualSyncQueue, true); 1915 1915 VMCPU_FF_CLEAR(pVCpuDst, VMCPU_FF_TIMER); /* Clear the FF once we started working for real. */ … … 1921 1921 1922 1922 ASMAtomicWriteBool(&pVM->tm.s.fRunningVirtualSyncQueue, false); 1923 tmVirtualSyncUnlock(pVM);1923 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 1924 1924 STAM_PROFILE_ADV_STOP(&pVM->tm.s.aStatDoQueues[TMCLOCK_VIRTUAL_SYNC], s1); 1925 1925 … … 1949 1949 Log2(("TMR3TimerQueuesDo: returns void\n")); 1950 1950 ASMAtomicWriteBool(&pVM->tm.s.fRunningQueues, false); 1951 tmTimerUnlock(pVM);1951 TM_UNLOCK_TIMERS(pVM); 1952 1952 STAM_PROFILE_STOP(&pVM->tm.s.StatDoQueues, a); 1953 1953 } … … 2379 2379 { 2380 2380 STAM_PROFILE_START(&pVM->tm.s.StatVirtualSyncFF, a); 2381 tmVirtualSyncLock(pVM);2381 PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED); 2382 2382 if (pVM->tm.s.fVirtualSyncTicking) 2383 2383 { 2384 2384 STAM_PROFILE_STOP(&pVM->tm.s.StatVirtualSyncFF, a); /* before the unlock! */ 2385 tmVirtualSyncUnlock(pVM);2385 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 2386 2386 Log2(("TMR3VirtualSyncFF: ticking\n")); 2387 2387 } 2388 2388 else 2389 2389 { 2390 tmVirtualSyncUnlock(pVM);2390 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 2391 2391 2392 2392 /* try run it. */ 2393 tmTimerLock(pVM);2394 tmVirtualSyncLock(pVM);2393 TM_LOCK_TIMERS(pVM); 2394 PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED); 2395 2395 if (pVM->tm.s.fVirtualSyncTicking) 2396 2396 Log2(("TMR3VirtualSyncFF: ticking (2)\n")); … … 2408 2408 } 2409 2409 STAM_PROFILE_STOP(&pVM->tm.s.StatVirtualSyncFF, a); /* before the unlock! */ 2410 tmVirtualSyncUnlock(pVM);2411 tmTimerUnlock(pVM);2410 PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock); 2411 TM_UNLOCK_TIMERS(pVM); 2412 2412 } 2413 2413 } … … 2495 2495 } 2496 2496 2497 /* Enter the critical section to make TMTimerSet/Stop happy. */ 2497 /* Enter the critical sections to make TMTimerSet/Stop happy. */ 2498 if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC) 2499 PDMCritSectEnter(&pTimer->pVMR3->tm.s.VirtualSyncLock, VERR_IGNORED); 2498 2500 PPDMCRITSECT pCritSect = pTimer->pCritSect; 2499 2501 if (pCritSect) 2500 PDMCritSectEnter(pCritSect, VERR_I NTERNAL_ERROR);2502 PDMCritSectEnter(pCritSect, VERR_IGNORED); 2501 2503 2502 2504 if (u8State == TMTIMERSTATE_SAVED_PENDING_SCHEDULE) … … 2527 2529 if (pCritSect) 2528 2530 PDMCritSectLeave(pCritSect); 2531 if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC) 2532 PDMCritSectLeave(&pTimer->pVMR3->tm.s.VirtualSyncLock); 2529 2533 2530 2534 /* … … 2611 2615 * The shared virtual clock (includes virtual sync which is tied to it). 2612 2616 */ 2613 tmTimerLock(pVM);/* Paranoia: Exploiting the timer lock here. */2617 TM_LOCK_TIMERS(pVM); /* Paranoia: Exploiting the timer lock here. */ 2614 2618 int rc = tmVirtualPauseLocked(pVM); 2615 tmTimerUnlock(pVM);2619 TM_UNLOCK_TIMERS(pVM); 2616 2620 if (RT_FAILURE(rc)) 2617 2621 return rc; … … 2675 2679 * The shared virtual clock (includes virtual sync which is tied to it). 2676 2680 */ 2677 tmTimerLock(pVM);/* Paranoia: Exploiting the timer lock here. */2681 TM_LOCK_TIMERS(pVM); /* Paranoia: Exploiting the timer lock here. */ 2678 2682 rc = tmVirtualResumeLocked(pVM); 2679 tmTimerUnlock(pVM);2683 TM_UNLOCK_TIMERS(pVM); 2680 2684 2681 2685 return rc; … … 2722 2726 * the warp drive settings. 2723 2727 */ 2724 tmTimerLock(pVM);/* Paranoia: Exploiting the timer lock here. */2728 TM_LOCK_TIMERS(pVM); /* Paranoia: Exploiting the timer lock here. */ 2725 2729 bool fPaused = !!pVM->tm.s.cVirtualTicking; 2726 2730 if (fPaused) /** @todo this isn't really working, but wtf. */ … … 2734 2738 if (fPaused) 2735 2739 TMR3NotifyResume(pVM, pVCpu); 2736 tmTimerUnlock(pVM);2740 TM_UNLOCK_TIMERS(pVM); 2737 2741 return VINF_SUCCESS; 2738 2742 } … … 2963 2967 "HzHint", 2964 2968 "State"); 2965 tmTimerLock(pVM);2969 TM_LOCK_TIMERS(pVM); 2966 2970 for (PTMTIMERR3 pTimer = pVM->tm.s.pCreated; pTimer; pTimer = pTimer->pBigNext) 2967 2971 { … … 2979 2983 pTimer->pszDesc); 2980 2984 } 2981 tmTimerUnlock(pVM);2985 TM_UNLOCK_TIMERS(pVM); 2982 2986 } 2983 2987 … … 3007 3011 for (unsigned iQueue = 0; iQueue < TMCLOCK_MAX; iQueue++) 3008 3012 { 3009 tmTimerLock(pVM);3013 TM_LOCK_TIMERS(pVM); 3010 3014 for (PTMTIMERR3 pTimer = TMTIMER_GET_HEAD(&pVM->tm.s.paTimerQueuesR3[iQueue]); 3011 3015 pTimer; … … 3025 3029 pTimer->pszDesc); 3026 3030 } 3027 tmTimerUnlock(pVM);3031 TM_UNLOCK_TIMERS(pVM); 3028 3032 } 3029 3033 } -
trunk/src/VBox/VMM/include/TMInternal.h
r37517 r37527 722 722 typedef TMCPU *PTMCPU; 723 723 724 #if 0 /* enable this to rule out locking bugs on single cpu guests. */725 # define tmTimerLock(pVM) VINF_SUCCESS726 # define tmTimerTryLock(pVM) VINF_SUCCESS727 # define tmTimerUnlock(pVM) ((void)0)728 # define tmVirtualSyncLock(pVM) VINF_SUCCESS729 # define tmVirtualSyncTryLock(pVM) VINF_SUCCESS730 # define tmVirtualSyncUnlock(pVM) ((void)0)731 # define TM_ASSERT_LOCK(pVM) VM_ASSERT_EMT(pVM)732 #else733 int tmTimerLock(PVM pVM);734 int tmTimerTryLock(PVM pVM);735 void tmTimerUnlock(PVM pVM);736 /** Checks that the caller owns the timer lock. */737 #define TM_ASSERT_LOCK(pVM) Assert(PDMCritSectIsOwner(&pVM->tm.s.TimerCritSect))738 int tmVirtualSyncLock(PVM pVM);739 int tmVirtualSyncTryLock(PVM pVM);740 void tmVirtualSyncUnlock(PVM pVM);741 #endif742 743 724 const char *tmTimerState(TMTIMERSTATE enmState); 744 725 void tmTimerQueueSchedule(PVM pVM, PTMTIMERQUEUE pQueue); … … 756 737 757 738 739 /** 740 * Try take the timer lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC. 741 * 742 * @retval VINF_SUCCESS on success (always in ring-3). 743 * @retval VERR_SEM_BUSY in RC and R0 if the semaphore is busy. 744 * 745 * @param a_pVM The VM handle. 746 * 747 * @remarks The virtual sync timer queue requires the virtual sync lock. 748 */ 749 #define TM_LOCK_TIMERS(a_pVM) PDMCritSectEnter(&(a_pVM)->tm.s.TimerCritSect, VERR_SEM_BUSY) 750 751 /** 752 * Try take the timer lock, no waiting. 753 * 754 * @retval VINF_SUCCESS on success. 755 * @retval VERR_SEM_BUSY if busy. 756 * 757 * @param a_pVM The VM handle. 758 * 759 * @remarks The virtual sync timer queue requires the virtual sync lock. 760 */ 761 #define TM_TRY_LOCK_TIMERS(a_pVM) PDMCritSectTryEnter(&(a_pVM)->tm.s.TimerCritSect) 762 763 /** Lock the timers (sans the virtual sync queue). */ 764 #define TM_UNLOCK_TIMERS(a_pVM) do { PDMCritSectLeave(&(a_pVM)->tm.s.TimerCritSect); } while (0) 765 766 /** Checks that the caller owns the timer lock. */ 767 #define TM_ASSERT_TIMER_LOCK_OWNERSHIP(a_pVM) \ 768 Assert(PDMCritSectIsOwner(&(a_pVM)->tm.s.TimerCritSect)) 769 770 758 771 /** @} */ 759 772
Note:
See TracChangeset
for help on using the changeset viewer.