Changeset 54345 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Feb 20, 2015 8:27:23 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp
r54342 r54345 111 111 /** The TSC delta value for the initial GIP master - 0 in regular builds. 112 112 * To test the delta code this can be set to a non-zero value. */ 113 #if 1113 #if 0 114 114 # define GIP_TSC_DELTA_INITIAL_MASTER_VALUE INT64_C(170139095182512) /* 0x00009abd9854acb0 */ 115 115 #else … … 2301 2301 PSUPDRVTSCDELTAMETHOD2 pWorkerData; 2302 2302 uint32_t cHits; 2303 /*uint32_t cOffByOne;*/2304 2303 bool fLagMaster; 2305 2304 bool fLagWorker; 2305 bool volatile fQuitEarly; 2306 2306 } M2; 2307 2307 #endif … … 2525 2525 * TSC delta measurement algorithm \#2 configuration and code - Experimental!! 2526 2526 */ 2527 # undef GIP_TSC_DELTA_LOOPS 2528 # undef GIP_TSC_DELTA_READ_TIME_LOOPS 2529 # undef GIP_TSC_DELTA_PRIMER_LOOPS 2530 # define GIP_TSC_DELTA_LOOPS 17 2531 # define GIP_TSC_DELTA_PRIMER_LOOPS 1 2532 # define GIP_TSC_DELTA_READ_TIME_LOOPS GIP_TSC_DELTA_PRIMER_LOOPS /* no read-time-loops necessary */ 2533 2534 2535 static void supdrvTscDeltaMethod2ProcessDataSet(PSUPDRVGIPTSCDELTARGS pArgs, PSUPDRVTSCDELTAMETHOD2 pMyData, 2536 bool fIsMaster, uint32_t cResults, 2537 PSUPDRVTSCDELTAMETHOD2 pOtherData, int64_t iMasterTscDelta, 2538 int64_t volatile *piWorkerTscDelta) 2539 { 2540 uint32_t cHits = 0; 2541 #if 0 2542 uint32_t cOffByOne = 0; 2543 #endif 2544 uint32_t idxResult = 0; 2545 int64_t iBestDelta = *piWorkerTscDelta; 2546 2547 if (cResults > RT_ELEMENTS(pMyData->aResults)) 2548 cResults = RT_ELEMENTS(pMyData->aResults); 2549 2550 for (idxResult = 0; idxResult < cResults; idxResult++) 2551 { 2552 uint32_t idxOther = pMyData->aResults[idxResult].iSeqOther; 2527 2528 # define GIP_TSC_DELTA_M2_LOOPS (12 + GIP_TSC_DELTA_M2_PRIMER_LOOPS) 2529 # define GIP_TSC_DELTA_M2_PRIMER_LOOPS 1 2530 2531 2532 static void supdrvTscDeltaMethod2ProcessDataOnMaster(PSUPDRVGIPTSCDELTARGS pArgs, uint32_t iLoop) 2533 { 2534 PSUPDRVTSCDELTAMETHOD2 pMasterData = pArgs->M2.pMasterData; 2535 PSUPDRVTSCDELTAMETHOD2 pOtherData = pArgs->M2.pWorkerData; 2536 int64_t iMasterTscDelta = pArgs->pMaster->i64TSCDelta; 2537 int64_t iBestDelta = pArgs->pWorker->i64TSCDelta; 2538 uint32_t idxResult; 2539 uint32_t cHits = 0; 2540 2541 /* 2542 * Look for matching entries in the master and worker tables. 2543 */ 2544 for (idxResult = 0; idxResult < RT_ELEMENTS(pMasterData->aResults); idxResult++) 2545 { 2546 uint32_t idxOther = pMasterData->aResults[idxResult].iSeqOther; 2553 2547 if (idxOther & 1) 2554 2548 { … … 2556 2550 if (idxOther < RT_ELEMENTS(pOtherData->aResults)) 2557 2551 { 2558 if (pOtherData->aResults[idxOther].iSeqOther == pM yData->aResults[idxResult].iSeqMine)2552 if (pOtherData->aResults[idxOther].iSeqOther == pMasterData->aResults[idxResult].iSeqMine) 2559 2553 { 2560 2554 int64_t iDelta; 2561 if (fIsMaster) 2562 iDelta = pOtherData->aResults[idxOther].uTsc 2563 - (pMyData->aResults[idxResult].uTsc - iMasterTscDelta); 2564 else 2565 iDelta = (pOtherData->aResults[idxResult].uTsc - iMasterTscDelta) 2566 - pMyData->aResults[idxOther].uTsc; 2555 iDelta = pOtherData->aResults[idxOther].uTsc 2556 - (pMasterData->aResults[idxResult].uTsc - iMasterTscDelta); 2567 2557 if ( iDelta >= GIP_TSC_DELTA_INITIAL_MASTER_VALUE 2568 2558 ? iDelta < iBestDelta … … 2573 2563 } 2574 2564 } 2575 #if 0 /* Can be used to detect battles between threads on the same core. Decided to change the master instead. */ 2576 else 2577 { 2578 idxOther >>= 1; 2579 if ( idxOther < RT_ELEMENTS(pOtherData->aResults) 2580 && pOtherData->aResults[idxOther].iSeqOther == pMyData->aResults[idxResult].iSeqMine) 2581 cOffByOne++; 2582 } 2583 #endif 2584 } 2585 2586 if (cHits > 0) 2587 *piWorkerTscDelta = iBestDelta; 2565 } 2566 2567 /* 2568 * Save the results. 2569 */ 2570 if (cHits > 2) 2571 pArgs->pWorker->i64TSCDelta = iBestDelta; 2588 2572 pArgs->M2.cHits += cHits; 2589 #if 0 2590 pArgs->M2.cOffByOne += cOffByOne; 2591 #endif 2592 } 2593 2594 2595 static void supdrvTscDeltaMethod2ProcessDataOnMaster(PSUPDRVGIPTSCDELTARGS pArgs) 2596 { 2597 supdrvTscDeltaMethod2ProcessDataSet(pArgs, 2598 pArgs->M2.pMasterData, 2599 true /*fIsMaster*/, 2600 RT_ELEMENTS(pArgs->M2.pMasterData->aResults), 2601 pArgs->M2.pWorkerData, 2602 pArgs->pMaster->i64TSCDelta, 2603 &pArgs->pWorker->i64TSCDelta); 2604 2605 supdrvTscDeltaMethod2ProcessDataSet(pArgs, 2606 pArgs->M2.pWorkerData, 2607 false /*fIsMaster*/, 2608 ASMAtomicReadU32(&pArgs->M2.pWorkerData->iCurSeqNo) >> 1, 2609 pArgs->M2.pMasterData, 2610 pArgs->pMaster->i64TSCDelta, 2611 &pArgs->pWorker->i64TSCDelta); 2612 } 2613 2573 2574 /* 2575 * Check and see if we can quit a little early. If the result is already 2576 * extremely good (+/-16 ticks seems reasonable), just stop. 2577 */ 2578 if ( iBestDelta >= 0 + GIP_TSC_DELTA_INITIAL_MASTER_VALUE 2579 ? iBestDelta <= 16 + GIP_TSC_DELTA_INITIAL_MASTER_VALUE 2580 : iBestDelta >= -16 + GIP_TSC_DELTA_INITIAL_MASTER_VALUE) 2581 { 2582 /*SUPR0Printf("quitting early #1: hits=%#x iLoop=%d iBestDelta=%lld\n", cHits, iLoop, iBestDelta);*/ 2583 ASMAtomicWriteBool(&pArgs->M2.fQuitEarly, true); 2584 } 2585 /* 2586 * After a while, just stop if we get sufficent hits. 2587 */ 2588 else if ( iLoop >= GIP_TSC_DELTA_M2_LOOPS / 3 2589 && cHits > 8) 2590 { 2591 uint32_t const cHitsNeeded = GIP_TSC_DELTA_M2_LOOPS * RT_ELEMENTS(pArgs->M2.pMasterData->aResults) / 4; /* 25% */ 2592 if ( pArgs->M2.cHits >= cHitsNeeded 2593 && ( iBestDelta >= 0 + GIP_TSC_DELTA_INITIAL_MASTER_VALUE 2594 ? iBestDelta <= GIP_TSC_DELTA_THRESHOLD_PRACTICALLY_ZERO + GIP_TSC_DELTA_INITIAL_MASTER_VALUE 2595 : iBestDelta >= -GIP_TSC_DELTA_THRESHOLD_PRACTICALLY_ZERO + GIP_TSC_DELTA_INITIAL_MASTER_VALUE) ) 2596 { 2597 /*SUPR0Printf("quitting early hits=%#x (%#x) needed=%#x iLoop=%d iBestDelta=%lld\n", 2598 pArgs->M2.cHits, cHits, cHitsNeeded, iLoop, iBestDelta);*/ 2599 ASMAtomicWriteBool(&pArgs->M2.fQuitEarly, true); 2600 } 2601 } 2602 } 2614 2603 2615 2604 … … 2670 2659 { 2671 2660 unsigned iLoop; 2672 for (iLoop = 0; iLoop < GIP_TSC_DELTA_LOOPS; iLoop++) 2661 2662 if (fIsMaster) 2663 ASMAtomicWriteBool(&pArgs->M2.fQuitEarly, false); 2664 2665 for (iLoop = 0; iLoop < GIP_TSC_DELTA_M2_LOOPS; iLoop++) 2673 2666 { 2674 2667 if (fIsMaster) … … 2679 2672 * Adjust the loop lag fudge. 2680 2673 */ 2681 if (iLoop < GIP_TSC_DELTA_PRIMER_LOOPS) 2674 # if GIP_TSC_DELTA_M2_PRIMER_LOOPS > 0 2675 if (iLoop < GIP_TSC_DELTA_M2_PRIMER_LOOPS) 2682 2676 { 2683 2677 /* Lag during the priming to be nice to everyone.. */ … … 2685 2679 pArgs->M2.fLagWorker = true; 2686 2680 } 2687 else if (iLoop < (GIP_TSC_DELTA_LOOPS - GIP_TSC_DELTA_PRIMER_LOOPS) / 4) 2681 else 2682 # endif 2683 if (iLoop < (GIP_TSC_DELTA_M2_LOOPS - GIP_TSC_DELTA_M2_PRIMER_LOOPS) / 4) 2688 2684 { 2689 2685 /* 25 % of the body without lagging. */ … … 2691 2687 pArgs->M2.fLagWorker = false; 2692 2688 } 2693 else if (iLoop < (GIP_TSC_DELTA_ LOOPS - GIP_TSC_DELTA_PRIMER_LOOPS) / 4 * 2)2689 else if (iLoop < (GIP_TSC_DELTA_M2_LOOPS - GIP_TSC_DELTA_M2_PRIMER_LOOPS) / 4 * 2) 2694 2690 { 2695 2691 /* 25 % of the body with both lagging. */ … … 2714 2710 * Process the data. 2715 2711 */ 2716 if (iLoop > GIP_TSC_DELTA_PRIMER_LOOPS) 2717 supdrvTscDeltaMethod2ProcessDataOnMaster(pArgs); 2712 # if GIP_TSC_DELTA_M2_PRIMER_LOOPS > 0 2713 if (iLoop >= GIP_TSC_DELTA_M2_PRIMER_LOOPS) 2714 # endif 2715 supdrvTscDeltaMethod2ProcessDataOnMaster(pArgs, iLoop); 2718 2716 2719 2717 TSCDELTA_MASTER_KICK_OTHER_OUT_OF_AFTER(pSync); … … 2728 2726 TSCDELTA_OTHER_SYNC_AFTER(pSync); 2729 2727 } 2728 2729 if (ASMAtomicReadBool(&pArgs->M2.fQuitEarly)) 2730 break; 2731 2730 2732 } 2731 2733 } … … 2760 2762 RTMemFreeEx(pArgs->M2.pMasterData, sizeof(*pArgs->M2.pMasterData)); 2761 2763 RTMemFreeEx(pArgs->M2.pWorkerData, sizeof(*pArgs->M2.pWorkerData)); 2762 /*SUPR0Printf("cHits=%d cOffByOne=%d m=%d w=%d\n", pArgs->M2.cHits, pArgs->M2.cOffByOne, pArgs->pMaster->idApic, pArgs->pWorker->idApic);*/ 2764 # if 0 2765 SUPR0Printf("cHits=%d m=%d w=%d\n", pArgs->M2.cHits, pArgs->pMaster->idApic, pArgs->pWorker->idApic); 2766 # endif 2763 2767 } 2764 2768
Note:
See TracChangeset
for help on using the changeset viewer.