Changeset 5167 in vbox for trunk/src/VBox/VMM/VMMAll/TMAll.cpp
- Timestamp:
- Oct 5, 2007 1:33:36 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 25066
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/TMAll.cpp
r4977 r5167 139 139 * 140 140 * @returns Virtual timer ticks to the next event. 141 * @param pVM Pointer to the shared VM structure. 141 142 * @thread The emulation thread. 142 143 */ … … 220 221 STAM_COUNTER_INC(&pVM->tm.s.StatPollMiss); 221 222 return RT_MIN(i64Delta1, i64Delta2); 223 } 224 225 226 /** 227 * Set FF if we've passed the next virtual event. 228 * 229 * This function is called before FFs are checked in the inner execution EM loops. 230 * 231 * @returns The GIP timestamp of the next event. 232 * 0 if the next event has already expired. 233 * @param pVM Pointer to the shared VM structure. 234 * @param pVM Pointer to the shared VM structure. 235 * @param pu64Delta Where to store the delta. 236 * @thread The emulation thread. 237 */ 238 TMDECL(uint64_t) TMTimerPollGIP(PVM pVM, uint64_t *pu64Delta) 239 { 240 /* 241 * Return straight away if the timer FF is already set. 242 */ 243 if (VM_FF_ISSET(pVM, VM_FF_TIMER)) 244 { 245 STAM_COUNTER_INC(&pVM->tm.s.StatPollAlreadySet); 246 *pu64Delta = 0; 247 return 0; 248 } 249 250 /* 251 * Get current time and check the expire times of the two relevant queues. 252 */ 253 const uint64_t u64Now = TMVirtualGet(pVM); 254 255 /* 256 * TMCLOCK_VIRTUAL 257 */ 258 const uint64_t u64Expire1 = pVM->tm.s.CTXALLSUFF(paTimerQueues)[TMCLOCK_VIRTUAL].u64Expire; 259 const int64_t i64Delta1 = u64Expire1 - u64Now; 260 if (i64Delta1 <= 0) 261 { 262 LogFlow(("TMTimerPoll: expire1=%RU64 <= now=%RU64\n", u64Expire1, u64Now)); 263 STAM_COUNTER_INC(&pVM->tm.s.StatPollVirtual); 264 VM_FF_SET(pVM, VM_FF_TIMER); 265 #ifdef IN_RING3 266 REMR3NotifyTimerPending(pVM); 267 #endif 268 *pu64Delta = 0; 269 return 0; 270 } 271 272 /* 273 * TMCLOCK_VIRTUAL_SYNC 274 * This isn't quite as stright forward if in a catch-up, not only do 275 * we have to adjust the 'now' but when have to adjust the delta as well. 276 */ 277 const uint64_t u64Expire2 = pVM->tm.s.CTXALLSUFF(paTimerQueues)[TMCLOCK_VIRTUAL_SYNC].u64Expire; 278 uint64_t u64VirtualSyncNow; 279 if (!pVM->tm.s.fVirtualSyncTicking) 280 u64VirtualSyncNow = pVM->tm.s.u64VirtualSync; 281 else 282 { 283 if (!pVM->tm.s.fVirtualSyncCatchUp) 284 u64VirtualSyncNow = u64Now - pVM->tm.s.offVirtualSync; 285 else 286 { 287 uint64_t off = pVM->tm.s.offVirtualSync; 288 uint64_t u64Delta = u64Now - pVM->tm.s.u64VirtualSyncCatchUpPrev; 289 if (RT_LIKELY(!(u64Delta >> 32))) 290 { 291 uint64_t u64Sub = ASMMultU64ByU32DivByU32(u64Delta, pVM->tm.s.u32VirtualSyncCatchUpPercentage, 100); 292 if (off > u64Sub + pVM->tm.s.offVirtualSyncGivenUp) 293 off -= u64Sub; 294 else 295 off = pVM->tm.s.offVirtualSyncGivenUp; 296 } 297 u64VirtualSyncNow = u64Now - off; 298 } 299 } 300 int64_t i64Delta2 = u64Expire2 - u64VirtualSyncNow; 301 if (i64Delta2 <= 0) 302 { 303 LogFlow(("TMTimerPoll: expire2=%RU64 <= now=%RU64\n", u64Expire2, u64Now)); 304 STAM_COUNTER_INC(&pVM->tm.s.StatPollVirtualSync); 305 VM_FF_SET(pVM, VM_FF_TIMER); 306 #ifdef IN_RING3 307 REMR3NotifyTimerPending(pVM); 308 #endif 309 *pu64Delta = 0; 310 return 0; 311 } 312 if (pVM->tm.s.fVirtualSyncCatchUp) 313 i64Delta2 = ASMMultU64ByU32DivByU32(i64Delta2, 100, pVM->tm.s.u32VirtualSyncCatchUpPercentage + 100); 314 315 /* 316 * Return the GIP time of the next event. 317 * This is the reverse of what tmVirtualGetRaw is doing. 318 */ 319 STAM_COUNTER_INC(&pVM->tm.s.StatPollMiss); 320 uint64_t u64GipTime = RT_MIN(i64Delta1, i64Delta2); 321 *pu64Delta = u64GipTime; 322 u64GipTime += u64Now + pVM->tm.s.u64VirtualOffset; 323 if (RT_UNLIKELY(!pVM->tm.s.fVirtualWarpDrive)) 324 { 325 u64GipTime -= pVM->tm.s.u64VirtualWarpDriveStart; /* the start is GIP time. */ 326 u64GipTime *= 100; 327 u64GipTime /= pVM->tm.s.u32VirtualWarpDrivePercentage; 328 u64GipTime += pVM->tm.s.u64VirtualWarpDriveStart; 329 } 330 return u64GipTime; 222 331 } 223 332 #endif
Note:
See TracChangeset
for help on using the changeset viewer.