Changeset 19032 in vbox for trunk/src/VBox/VMM/TM.cpp
- Timestamp:
- Apr 20, 2009 3:03:08 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/TM.cpp
r15844 r19032 91 91 * Each clock has its own scheduling facility, or timer queue if you like. 92 92 * There are a few factors which makes it a bit complex. First, there is the 93 * usual R0 vs R3 vs. RC thing. Then there ismultiple threads, and then there93 * usual R0 vs R3 vs. RC thing. Then there are multiple threads, and then there 94 94 * is the timer thread that periodically checks whether any timers has expired 95 95 * without EMT noticing. On the API level, all but the create and save APIs … … 98 98 * The design is using a doubly linked list of active timers which is ordered 99 99 * by expire date. This list is only modified by the EMT thread. Updates to 100 * the list are batched in a singly linked list, which is then process by the100 * the list are batched in a singly linked list, which is then processed by the 101 101 * EMT thread at the first opportunity (immediately, next time EMT modifies a 102 102 * timer on that clock, or next timer timeout). Both lists are offset based and … … 310 310 { 311 311 if (!pVM->tm.s.fTSCUseRealTSC) 312 pVM->tm.s.fMaybeUseOffsettedHostTSC = tmR3HasFixedTSC(pVM); 312 { 313 /* @todo simple case for guest SMP; always emulate RDTSC */ 314 if (pVM->cCPUs == 1) 315 pVM->tm.s.fMaybeUseOffsettedHostTSC = tmR3HasFixedTSC(pVM); 316 } 313 317 else 314 318 pVM->tm.s.fMaybeUseOffsettedHostTSC = true; … … 346 350 /** @cfgm{TM/TSCTiedToExecution, bool, false} 347 351 * Whether the TSC should be tied to execution. This will exclude most of the 348 * virtualization overhead, but will by default include the time spen din the352 * virtualization overhead, but will by default include the time spent in the 349 353 * halt state (see TM/TSCNotTiedToHalt). This setting will override all other 350 354 * TSC settings except for TSCTicksPerSecond and TSCNotTiedToHalt, which should … … 984 988 static DECLCALLBACK(int) tmR3Save(PVM pVM, PSSMHANDLE pSSM) 985 989 { 990 unsigned i; 991 986 992 LogFlow(("tmR3Save:\n")); 987 Assert(!pVM->tm.s.fTSCTicking); 993 #ifdef VBOX_STRICT 994 for (i=0;i<pVM->cCPUs;i++) 995 { 996 PVMCPU pVCpu = &pVM->aCpus[i]; 997 Assert(!pVCpu->tm.s.fTSCTicking); 998 } 988 999 Assert(!pVM->tm.s.fVirtualTicking); 989 1000 Assert(!pVM->tm.s.fVirtualSyncTicking); 1001 #endif 990 1002 991 1003 /* … … 1006 1018 SSMR3PutU64(pSSM, TMCLOCK_FREQ_REAL); 1007 1019 1008 /* the cpu tick clock. */ 1009 SSMR3PutU64(pSSM, TMCpuTickGet(pVM)); 1020 for (i=0;i<pVM->cCPUs;i++) 1021 { 1022 PVMCPU pVCpu = &pVM->aCpus[i]; 1023 1024 /* the cpu tick clock. */ 1025 SSMR3PutU64(pSSM, TMCpuTickGet(pVCpu)); 1026 } 1010 1027 return SSMR3PutU64(pSSM, pVM->tm.s.cTSCTicksPerSecond); 1011 1028 } … … 1022 1039 static DECLCALLBACK(int) tmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version) 1023 1040 { 1041 unsigned i; 1024 1042 LogFlow(("tmR3Load:\n")); 1025 Assert(!pVM->tm.s.fTSCTicking); 1043 1044 #ifdef VBOX_STRICT 1045 for (i=0;i<pVM->cCPUs;i++) 1046 { 1047 PVMCPU pVCpu = &pVM->aCpus[i]; 1048 Assert(!pVCpu->tm.s.fTSCTicking); 1049 } 1026 1050 Assert(!pVM->tm.s.fVirtualTicking); 1027 1051 Assert(!pVM->tm.s.fVirtualSyncTicking); 1052 #endif 1028 1053 1029 1054 /* … … 1081 1106 1082 1107 /* the cpu tick clock. */ 1083 pVM->tm.s.fTSCTicking = false; 1084 SSMR3GetU64(pSSM, &pVM->tm.s.u64TSC); 1108 for (i=0;i<pVM->cCPUs;i++) 1109 { 1110 PVMCPU pVCpu = &pVM->aCpus[i]; 1111 1112 pVCpu->tm.s.fTSCTicking = false; 1113 SSMR3GetU64(pSSM, &pVCpu->tm.s.u64TSC); 1114 1115 if (pVM->tm.s.fTSCUseRealTSC) 1116 pVCpu->tm.s.u64TSCOffset = 0; /** @todo TSC restore stuff and HWACC. */ 1117 } 1118 1085 1119 rc = SSMR3GetU64(pSSM, &u64Hz); 1086 1120 if (RT_FAILURE(rc)) 1087 1121 return rc; 1088 if (pVM->tm.s.fTSCUseRealTSC) 1089 pVM->tm.s.u64TSCOffset = 0; /** @todo TSC restore stuff and HWACC. */ 1090 else 1122 if (!pVM->tm.s.fTSCUseRealTSC) 1091 1123 pVM->tm.s.cTSCTicksPerSecond = u64Hz; 1124 1092 1125 LogRel(("TM: cTSCTicksPerSecond=%#RX64 (%RU64) fTSCVirtualized=%RTbool fTSCUseRealTSC=%RTbool (state load)\n", 1093 1126 pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.fTSCVirtualized, pVM->tm.s.fTSCUseRealTSC)); … … 1360 1393 case TMCLOCK_VIRTUAL_SYNC: return TMVirtualSyncGet(pVM); 1361 1394 case TMCLOCK_REAL: return TMRealGet(pVM); 1362 case TMCLOCK_TSC: return TMCpuTickGet( pVM);1395 case TMCLOCK_TSC: return TMCpuTickGet(&pVM->aCpus[0] /* just take VCPU 0 */); 1363 1396 default: 1364 1397 AssertMsgFailed(("enmClock=%d\n", enmClock)); … … 2083 2116 * Read the times first to avoid more than necessary time variation. 2084 2117 */ 2085 const uint64_t u64TSC = TMCpuTickGet(pVM);2086 2118 const uint64_t u64Virtual = TMVirtualGet(pVM); 2087 2119 const uint64_t u64VirtualSync = TMVirtualSyncGet(pVM); 2088 2120 const uint64_t u64Real = TMRealGet(pVM); 2089 2121 2090 /* 2091 * TSC 2092 */ 2093 pHlp->pfnPrintf(pHlp, 2094 "Cpu Tick: %18RU64 (%#016RX64) %RU64Hz %s%s", 2095 u64TSC, u64TSC, TMCpuTicksPerSecond(pVM), 2096 pVM->tm.s.fTSCTicking ? "ticking" : "paused", 2097 pVM->tm.s.fTSCVirtualized ? " - virtualized" : ""); 2098 if (pVM->tm.s.fTSCUseRealTSC) 2099 { 2100 pHlp->pfnPrintf(pHlp, " - real tsc"); 2101 if (pVM->tm.s.u64TSCOffset) 2102 pHlp->pfnPrintf(pHlp, "\n offset %RU64", pVM->tm.s.u64TSCOffset); 2103 } 2104 else 2105 pHlp->pfnPrintf(pHlp, " - virtual clock"); 2106 pHlp->pfnPrintf(pHlp, "\n"); 2122 for (unsigned i=0;i<pVM->cCPUs;i++) 2123 { 2124 PVMCPU pVCpu = &pVM->aCpus[i]; 2125 2126 uint64_t u64TSC = TMCpuTickGet(pVCpu); 2127 /* 2128 * TSC 2129 */ 2130 pHlp->pfnPrintf(pHlp, 2131 "Cpu Tick: %18RU64 (%#016RX64) %RU64Hz %s%s", 2132 u64TSC, u64TSC, TMCpuTicksPerSecond(pVM), 2133 pVCpu->tm.s.fTSCTicking ? "ticking" : "paused", 2134 pVM->tm.s.fTSCVirtualized ? " - virtualized" : ""); 2135 if (pVM->tm.s.fTSCUseRealTSC) 2136 { 2137 pHlp->pfnPrintf(pHlp, " - real tsc"); 2138 if (pVCpu->tm.s.u64TSCOffset) 2139 pHlp->pfnPrintf(pHlp, "\n offset %RU64", pVCpu->tm.s.u64TSCOffset); 2140 } 2141 else 2142 pHlp->pfnPrintf(pHlp, " - virtual clock"); 2143 pHlp->pfnPrintf(pHlp, "\n"); 2144 } 2107 2145 2108 2146 /*
Note:
See TracChangeset
for help on using the changeset viewer.