Changeset 54325 in vbox for trunk/src/VBox/HostDrivers/Support
- Timestamp:
- Feb 20, 2015 10:54:23 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r54321 r54325 6099 6099 PSUPGIPCPU pGipCpuWorker = &pGip->aCPUs[iCpu]; 6100 6100 if ( pGipCpuWorker->i64TSCDelta == INT64_MAX 6101 && RTCpuSetIsMember (&pDevExt->TscDeltaCpuSet, pGipCpuWorker->iCpuSet))6101 && RTCpuSetIsMemberByIndex(&pDevExt->TscDeltaCpuSet, pGipCpuWorker->iCpuSet)) 6102 6102 { 6103 6103 rc |= supdrvMeasureTscDeltaOne(pDevExt, iCpu); … … 7526 7526 * 7527 7527 * @remarks Measuring TSC deltas between the CPUs is tricky because we need to 7528 * read the TSC at exactly the same time on both the master and the worker 7529 * CPUs. Due to DMA, bus arbitration, cache locality, contention, SMI, 7530 * pipelining etc. there is no guaranteed way of doing this on x86 CPUs. We 7531 * try to minimize the measurement error by computing the minimum read time 7532 * of the compare statement in the worker by taking TSC measurements across 7533 * it. 7534 * 7535 * We ignore the first few runs of the loop in order to prime the cache. 7536 * Also, be careful about using 'pause' instruction in critical busy-wait 7537 * loops in this code - it can cause undesired behaviour with 7538 * hyperthreading. 7539 * 7540 * It must be noted that the computed minimum read time is mostly to 7541 * eliminate huge deltas when the worker is too early and doesn't by itself 7542 * help produce more accurate deltas. We allow two times the computed 7543 * minimum as an arbibtrary acceptable threshold. Therefore, it is still 7544 * possible to get negative deltas where there are none when the worker is 7545 * earlier. As long as these occasional negative deltas are lower than the 7546 * time it takes to exit guest-context and the OS to reschedule EMT on a 7547 * different CPU we won't expose a TSC that jumped backwards. It is because 7548 * of the existence of the negative deltas we don't recompute the delta with 7549 * the master and worker interchanged to eliminate the remaining measurement 7550 * error. 7528 * read the TSC at exactly the same time on both the master and the 7529 * worker CPUs. Due to DMA, bus arbitration, cache locality, 7530 * contention, SMI, pipelining etc. there is no guaranteed way of 7531 * doing this on x86 CPUs. 7532 * 7533 * GIP_TSC_DELTA_METHOD_1: 7534 * We ignore the first few runs of the loop in order to prime the 7535 * cache. Also, we need to be careful about using 'pause' instruction 7536 * in critical busy-wait loops in this code - it can cause undesired 7537 * behaviour with hyperthreading. 7538 * 7539 * We try to minimize the measurement error by computing the minimum 7540 * read time of the compare statement in the worker by taking TSC 7541 * measurements across it. 7542 * 7543 * It must be noted that the computed minimum read time is mostly to 7544 * eliminate huge deltas when the worker is too early and doesn't by 7545 * itself help produce more accurate deltas. We allow two times the 7546 * computed minimum as an arbibtrary acceptable threshold. Therefore, 7547 * it is still possible to get negative deltas where there are none 7548 * when the worker is earlier. As long as these occasional negative 7549 * deltas are lower than the time it takes to exit guest-context and 7550 * the OS to reschedule EMT on a different CPU we won't expose a TSC 7551 * that jumped backwards. It is because of the existence of the 7552 * negative deltas we don't recompute the delta with the master and 7553 * worker interchanged to eliminate the remaining measurement error. 7554 * 7555 * @todo document working of GIP_TSC_DELTA_METHOD_2. 7551 7556 */ 7552 7557 static DECLCALLBACK(void) supdrvMeasureTscDeltaCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2) … … 7818 7823 * CPUs. 7819 7824 * 7820 * @remarks This can be called with preemption disabled!7825 * @remarks This must be called with preemption enabled! 7821 7826 */ 7822 7827 static int supdrvMeasureTscDeltaOne(PSUPDRVDEVEXT pDevExt, uint32_t idxWorker) … … 7832 7837 AssertReturn(pGip, VERR_INVALID_PARAMETER); 7833 7838 Assert(pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED); 7839 Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD)); 7834 7840 7835 7841 /* … … 7885 7891 * being executed and that can take a good while to be done. 7886 7892 */ 7887 RTThreadSleep(1); /** @todo r=bird: This won't work with preemption disabled, not on real OSes anyway. */7893 RTThreadSleep(1); 7888 7894 } 7889 7895
Note:
See TracChangeset
for help on using the changeset viewer.