Changeset 81061 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Sep 27, 2019 4:38:54 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 133665
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
r80290 r81061 117 117 * This is used to calculate when the timer ought to fire the next time. */ 118 118 uint64_t u64NextTS; 119 /** When the timer was started. */ 120 uint64_t nsStartTS; 119 121 /** The u64NextTS in jiffies. */ 120 122 unsigned long ulNextJiffies; … … 345 347 uint64_t u64NextTS = u64Now + u64First; 346 348 if (!fHighRes) 349 { 347 350 pSubTimer->u.Std.u64NextTS = u64NextTS; 351 pSubTimer->u.Std.nsStartTS = u64NextTS; 352 } 348 353 RTTIMERLNX_LOG(("startsubtimer %p\n", pSubTimer->pParent)); 349 354 … … 766 771 * try prevent some jittering if we were started at a bad time. 767 772 */ 768 const uint64_t iTick = ++pSubTimer->iTick; 773 const uint64_t iTick = ++pSubTimer->iTick; 774 unsigned long uCurJiffies = jiffies; 775 unsigned long ulNextJiffies; 769 776 uint64_t u64NanoInterval; 770 777 unsigned long cJiffies; … … 778 785 pSubTimer->u.Std.fFirstAfterChg = false; 779 786 pSubTimer->u.Std.u64NextTS = RTTimeSystemNanoTS(); 780 pSubTimer->u.Std.ulNextJiffies = jiffies; 787 pSubTimer->u.Std.nsStartTS = pSubTimer->u.Std.u64NextTS - u64NanoInterval * (iTick - 1); 788 pSubTimer->u.Std.ulNextJiffies = uCurJiffies = jiffies; 781 789 } 782 790 spin_unlock_irqrestore(&pTimer->ChgIntLock, flFlags); … … 785 793 if (cJiffies) 786 794 { 787 pSubTimer->u.Std.ulNextJiffies += cJiffies; 788 /* Prevent overflows when the jiffies counter wraps around. 789 * Special thanks to Ken Preslan for helping debugging! */ 790 while (time_before(pSubTimer->u.Std.ulNextJiffies, jiffies)) 795 ulNextJiffies = pSubTimer->u.Std.ulNextJiffies + cJiffies; 796 pSubTimer->u.Std.ulNextJiffies = ulNextJiffies; 797 if (time_after(ulNextJiffies, uCurJiffies)) 798 { /* likely */ } 799 else 791 800 { 792 pSubTimer->u.Std.ulNextJiffies += cJiffies; 793 pSubTimer->u.Std.u64NextTS += u64NanoInterval; 801 unsigned long cJiffiesBehind = uCurJiffies - ulNextJiffies; 802 if (cJiffies >= 2) 803 ulNextJiffies = uCurJiffies + cJiffies / 2; 804 else 805 ulNextJiffies = uCurJiffies + 1; 806 if (cJiffiesBehind >= HZ / 4) /* Conside if we're lagging too far behind. Screw the u64NextTS member. */ 807 pSubTimer->u.Std.ulNextJiffies = ulNextJiffies; 808 /*else: Don't update u.Std.ulNextJiffies so we can continue catching up in the next tick. */ 794 809 } 795 810 } … … 797 812 { 798 813 const uint64_t u64NanoTS = RTTimeSystemNanoTS(); 799 while (pSubTimer->u.Std.u64NextTS < u64NanoTS) 800 pSubTimer->u.Std.u64NextTS += u64NanoInterval; 801 pSubTimer->u.Std.ulNextJiffies = jiffies + rtTimerLnxNanoToJiffies(pSubTimer->u.Std.u64NextTS - u64NanoTS); 814 const int64_t cNsBehind = u64NanoTS - pSubTimer->u.Std.u64NextTS; 815 if (cNsBehind < 0) 816 ulNextJiffies = uCurJiffies + rtTimerLnxNanoToJiffies(pSubTimer->u.Std.u64NextTS - u64NanoTS); 817 else if (u64NanoInterval >= RT_NS_1SEC_64 * 2 / HZ) 818 { 819 ulNextJiffies = uCurJiffies + rtTimerLnxNanoToJiffies(u64NanoInterval / 2); 820 if (cNsBehind >= RT_NS_1SEC_64 / HZ / 4) /* Conside if we're lagging too far behind. */ 821 pSubTimer->u.Std.u64NextTS = u64NanoTS + u64NanoInterval / 2; 822 } 823 else 824 { 825 ulNextJiffies = uCurJiffies + 1; 826 if (cNsBehind >= RT_NS_1SEC_64 / HZ / 4) /* Conside if we're lagging too far behind. */ 827 pSubTimer->u.Std.u64NextTS = u64NanoTS + RT_NS_1SEC_64 / HZ; 828 } 829 pSubTimer->u.Std.ulNextJiffies = ulNextJiffies; 802 830 } 803 831 … … 816 844 { 817 845 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) 818 mod_timer(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);846 mod_timer(&pSubTimer->u.Std.LnxTimer, ulNextJiffies); 819 847 # else 820 mod_timer_pinned(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);848 mod_timer_pinned(&pSubTimer->u.Std.LnxTimer, ulNextJiffies); 821 849 # endif 822 850 } 823 851 else 824 852 #endif 825 mod_timer(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);853 mod_timer(&pSubTimer->u.Std.LnxTimer, ulNextJiffies); 826 854 return; 827 855 } … … 1419 1447 return VERR_NOT_SUPPORTED; 1420 1448 1421 cJiffies = u64NanoInterval / RTTimerGetSystemGranularity();1422 if (cJiffies * RTTimerGetSystemGranularity() != u64NanoInterval)1449 cJiffies = u64NanoInterval / (RT_NS_1SEC / HZ); 1450 if (cJiffies * (RT_NS_1SEC / HZ) != u64NanoInterval) 1423 1451 cJiffies = 0; 1424 1452 … … 1580 1608 pTimer->pvUser = pvUser; 1581 1609 pTimer->u64NanoInterval = u64NanoInterval; 1582 pTimer->cJiffies = u64NanoInterval / RTTimerGetSystemGranularity();1583 if (pTimer->cJiffies * RTTimerGetSystemGranularity() != u64NanoInterval)1610 pTimer->cJiffies = u64NanoInterval / (RT_NS_1SEC / HZ); 1611 if (pTimer->cJiffies * (RT_NS_1SEC / HZ) != u64NanoInterval) 1584 1612 pTimer->cJiffies = 0; 1585 1613 spin_lock_init(&pTimer->ChgIntLock);
Note:
See TracChangeset
for help on using the changeset viewer.