Changeset 443 in vbox for trunk/src/VBox
- Timestamp:
- Jan 30, 2007 9:53:52 PM (18 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/TM.cpp
r23 r443 193 193 194 194 /* 195 * Start the timer. 195 * Setup the warp drive. 196 */ 197 rc = CFGMR3QueryU32(CFGMR3GetRoot(pVM), "WarpDrivePercentage", &pVM->tm.s.u32VirtualWarpDrivePercentage); 198 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 199 pVM->tm.s.u32VirtualWarpDrivePercentage = 100; 200 else if (VBOX_FAILURE(rc)) 201 return VMSetError(pVM, rc, RT_SRC_POS, 202 N_("Configuration error: Failed to querying uint32_t value \"WarpDrivePercent\". (%Vrc)"), rc); 203 else if ( pVM->tm.s.u32VirtualWarpDrivePercentage < 2 204 || pVM->tm.s.u32VirtualWarpDrivePercentage > 20000) 205 return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS, 206 N_("Configuration error: \"WarpDrivePercent\" = %RI32 is not in the range 2..20000!"), 207 pVM->tm.s.u32VirtualWarpDrivePercentage); 208 pVM->tm.s.fVirtualWarpDrive = pVM->tm.s.u32VirtualWarpDrivePercentage != 100; 209 if (pVM->tm.s.fVirtualWarpDrive) 210 LogRel(("TM: u32VirtualWarpDrivePercentage=%RI32\n", pVM->tm.s.u32VirtualWarpDrivePercentage)); 211 212 /* 213 * Start the timer (guard against REM not yielding). 196 214 */ 197 215 uint32_t u32Millies; … … 200 218 u32Millies = 10; 201 219 else if (VBOX_FAILURE(rc)) 202 { 203 AssertMsgFailed(("Configuration error: Failed to query uint32_t value \"TimerMillies\", rc=%Vrc.\n", rc)); 204 return rc; 205 } 220 return VMSetError(pVM, rc, RT_SRC_POS, 221 N_("Configuration error: Failed to query uint32_t value \"TimerMillies\", rc=%Vrc.\n"), rc); 206 222 rc = RTTimerCreate(&pVM->tm.s.pTimer, u32Millies, tmR3TimerCallback, pVM); 207 223 if (VBOX_FAILURE(rc)) -
trunk/src/VBox/VMM/TMInternal.h
r161 r443 297 297 uint64_t cTSCTicksPerSecond; 298 298 299 /** Padding to ensure that 64-bit values are equaly aligned everywhere. */300 uint32_t uReserved;301 299 /** Virtual time ticking enabled indicator (bool). (TMCLOCK_VIRTUAL) */ 302 300 bool fVirtualTicking; 301 /** Virtual time is not running at 100%. */ 302 bool fVirtualWarpDrive; 303 303 /** Virtual timer synchronous time ticking enabled indicator (bool). (TMCLOCK_VIRTUAL_SYNC) */ 304 304 bool fVirtualSyncTicking; 305 305 /** Virtual timer synchronous time catch-up active. */ 306 306 bool volatile fVirtualSyncCatchUp; 307 /** WarpDrive percentage. 308 * 100% is normal (fVirtualSyncNormal == true). When other than 100% we apply 309 * this percentage to the raw time source for the period it's been valid in, 310 * i.e. since u64VirtualWarpDriveStart. */ 311 uint32_t u32VirtualWarpDrivePercentage; 307 312 308 313 /** The offset of the virtual clock relative to it's timesource. … … 311 316 /** The guest virtual time when fVirtualTicking is cleared. */ 312 317 uint64_t u64Virtual; 318 /** When the Warp drive was started or last adjusted. 319 * Only valid when fVirtualWarpDrive is set. */ 320 uint64_t u64VirtualWarpDriveStart; 313 321 314 322 /** The offset of the virtual timer synchronous clock (TMCLOCK_VIRTUAL_SYNC) relative … … 319 327 /** The guest virtual timer synchronous time when fVirtualSyncTicking is cleared. */ 320 328 uint64_t u64VirtualSync; 321 /** How many p recent faster the clock should advance when catch-up is active. */322 uint32_t u32VirtualSyncCatchupP recentage;329 /** How many percent faster the clock should advance when catch-up is active. */ 330 uint32_t u32VirtualSyncCatchupPercentage; 323 331 /** When to stop catch-up. */ 324 332 uint32_t u32VirtualSyncCatchupStopThreashold; -
trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
r23 r443 40 40 41 41 42 /******************************************************************************* 43 * Internal Functions * 44 *******************************************************************************/ 45 static DECLCALLBACK(int) tmVirtualSetWarpDrive(PVM pVM, uint32_t u32Percent); 46 47 48 49 /** 50 * Get the time when we're not running at 100% 51 * 52 * @returns The timestamp. 53 * @param pVM The VM handle. 54 */ 55 uint64_t tmVirtualGetRawNonNormal(PVM pVM) 56 { 57 /* 58 * Recalculate the RTTimeNanoTS() value for the period where 59 * warp drive has been enabled. 60 */ 61 uint64_t u64 = RTTimeNanoTS(); 62 u64 -= pVM->tm.s.u64VirtualWarpDriveStart; 63 u64 *= pVM->tm.s.u32VirtualWarpDrivePercentage; 64 u64 /= 100; 65 u64 += pVM->tm.s.u64VirtualWarpDriveStart; 66 67 /* 68 * Now we apply the virtual time offset. 69 * (Which is the negate RTTimeNanoTS() value for when the virtual machine 70 * started if it had been running continuously without any suspends.) 71 */ 72 u64 -= pVM->tm.s.u64VirtualOffset; 73 return u64; 74 } 75 76 77 /** 78 * Get the raw virtual time. 79 * 80 * @returns The current time stamp. 81 * @param pVM The VM handle. 82 */ 83 DECLINLINE(uint64_t) tmVirtualGetRaw(PVM pVM) 84 { 85 if (RT_LIKELY(!pVM->tm.s.fVirtualWarpDrive)) 86 return RTTimeNanoTS() - pVM->tm.s.u64VirtualOffset; 87 return tmVirtualGetRawNonNormal(pVM); 88 } 42 89 43 90 … … 59 106 { 60 107 STAM_COUNTER_INC(&pVM->tm.s.StatVirtualGet); 61 u64 = RTTimeNanoTS() - pVM->tm.s.u64VirtualOffset;108 u64 = tmVirtualGetRaw(pVM); 62 109 63 110 /* … … 102 149 */ 103 150 Assert(pVM->tm.s.fVirtualTicking); 104 u64 = RTTimeNanoTS() - pVM->tm.s.u64VirtualOffset;151 u64 = tmVirtualGetRaw(pVM); 105 152 if ( !VM_FF_ISSET(pVM, VM_FF_TIMER) 106 153 && pVM->tm.s.CTXALLSUFF(paTimerQueues)[TMCLOCK_VIRTUAL].u64Expire <= u64) … … 145 192 if (!(u64Delta >> 32)) 146 193 { 147 uint32_t u32Sub = ASMDivU64ByU32RetU32(ASMMult2xU32RetU64((uint32_t)u64Delta, pVM->tm.s.u32VirtualSyncCatchupP recentage),194 uint32_t u32Sub = ASMDivU64ByU32RetU32(ASMMult2xU32RetU64((uint32_t)u64Delta, pVM->tm.s.u32VirtualSyncCatchupPercentage), 148 195 100); 149 196 if (u32Sub < (uint32_t)u64Delta) … … 223 270 { 224 271 STAM_COUNTER_INC(&pVM->tm.s.StatVirtualResume); 225 pVM->tm.s.u64VirtualOffset = RTTimeNanoTS() - pVM->tm.s.u64Virtual; 272 pVM->tm.s.u64VirtualWarpDriveStart = RTTimeNanoTS(); 273 pVM->tm.s.u64VirtualOffset = pVM->tm.s.u64VirtualWarpDriveStart - pVM->tm.s.u64Virtual; 226 274 pVM->tm.s.fVirtualTicking = true; 227 275 pVM->tm.s.fVirtualSyncTicking = true; … … 251 299 #ifndef TM_CONTINUOUS_TIME 252 300 STAM_COUNTER_INC(&pVM->tm.s.StatVirtualPause); 253 pVM->tm.s.u64Virtual = RTTimeNanoTS() - pVM->tm.s.u64VirtualOffset;301 pVM->tm.s.u64Virtual = tmVirtualGetRaw(pVM); 254 302 pVM->tm.s.fVirtualSyncTicking = false; 255 303 pVM->tm.s.fVirtualTicking = false; … … 260 308 AssertFailed(); 261 309 return VERR_INTERNAL_ERROR; 310 } 311 312 313 /** 314 * Gets the current warp drive percent. 315 * 316 * @returns The warp drive percent. 317 * @param pVM The VM handle. 318 */ 319 TMDECL(uint32_t) TMVirtualGetWarpDrive(PVM pVM) 320 { 321 return pVM->tm.s.u32VirtualWarpDrivePercentage; 322 } 323 324 325 /** 326 * Sets the warp drive percent of the virtual time. 327 * 328 * @returns VBox status code. 329 * @param pVM The VM handle. 330 * @param u32Percent The new percentage. 100 means normal operation. 331 */ 332 TMDECL(int) TMVirtualSetWarpDrive(PVM pVM, uint32_t u32Percent) 333 { 334 #ifdef IN_RING3 335 PVMREQ pReq; 336 int rc = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT, (PFNRT)tmVirtualSetWarpDrive, 2, pVM, u32Percent); 337 if (VBOX_SUCCESS(rc)) 338 rc = pReq->iStatus; 339 VMR3ReqFree(pReq); 340 return rc; 341 #else 342 343 return tmVirtualSetWarpDrive(pVM, u32Percent); 344 #endif 345 } 346 347 348 /** 349 * EMT worker for tmVirtualSetWarpDrive. 350 * 351 * @returns VBox status code. 352 * @param pVM The VM handle. 353 * @param u32Percent See TMVirtualSetWarpDrive(). 354 * @internal 355 */ 356 static DECLCALLBACK(int) tmVirtualSetWarpDrive(PVM pVM, uint32_t u32Percent) 357 { 358 /* 359 * Validate it. 360 */ 361 AssertMsgReturn(u32Percent >= 2 && u32Percent <= 20000, 362 ("%RX32 is not between 2 and 20000 (inclusive).\n", u32Percent), 363 VERR_INVALID_PARAMETER); 364 365 /* 366 * If the time is running we'll have to pause it before we can change 367 * the warp drive settings. 368 */ 369 bool fPaused = pVM->tm.s.fVirtualTicking; 370 if (fPaused) 371 { 372 int rc = TMVirtualPause(pVM); 373 AssertRCReturn(rc, rc); 374 } 375 376 pVM->tm.s.u32VirtualWarpDrivePercentage = u32Percent; 377 pVM->tm.s.fVirtualWarpDrive = u32Percent != 100; 378 LogRel(("TM: u32VirtualWarpDrivePercentage=%RI32 fVirtualWarpDrive=%RTbool\n", 379 pVM->tm.s.u32VirtualWarpDrivePercentage, pVM->tm.s.fVirtualWarpDrive)); 380 381 if (fPaused) 382 { 383 int rc = TMVirtualResume(pVM); 384 AssertRCReturn(rc, rc); 385 } 386 387 return VINF_SUCCESS; 262 388 } 263 389 -
trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp
r161 r443 408 408 GEN_CHECK_OFF(TM, u64TSC); 409 409 GEN_CHECK_OFF(TM, cTSCTicksPerSecond); 410 GEN_CHECK_OFF(TM, uReserved);411 410 GEN_CHECK_OFF(TM, fVirtualTicking); 411 GEN_CHECK_OFF(TM, fVirtualWarpDrive); 412 GEN_CHECK_OFF(TM, u32VirtualWarpDrivePercentage); 412 413 GEN_CHECK_OFF(TM, u64VirtualOffset); 413 414 GEN_CHECK_OFF(TM, u64Virtual); 415 GEN_CHECK_OFF(TM, u64VirtualWarpDriveStart); 414 416 GEN_CHECK_OFF(TM, u64VirtualSync); 415 GEN_CHECK_OFF(TM, u32VirtualSyncCatchupP recentage);417 GEN_CHECK_OFF(TM, u32VirtualSyncCatchupPercentage); 416 418 GEN_CHECK_OFF(TM, u32VirtualSyncCatchupStopThreashold); 417 419 GEN_CHECK_OFF(TM, u64VirtualSyncCatchupStartTreashold);
Note:
See TracChangeset
for help on using the changeset viewer.