VirtualBox

Changeset 89827 in vbox


Ignore:
Timestamp:
Jun 22, 2021 9:01:04 AM (4 years ago)
Author:
vboxsync
Message:

Runtime: Make use of CreateWaitableTimerEx and CREATE_WAITABLE_TIMER_HIGH_RESOLUTION available on newer Windwos 10 release to improve timer accuracy for sub tick intervals

Location:
trunk/src/VBox/Runtime/r3/win
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/init-win.cpp

    r85124 r89827  
    7777/** SystemTimeToTzSpecificLocalTime. */
    7878DECL_HIDDEN_DATA(decltype(SystemTimeToTzSpecificLocalTime) *) g_pfnSystemTimeToTzSpecificLocalTime = NULL;
     79/** CreateWaitableTimerEx . */
     80DECL_HIDDEN_DATA(PFNCREATEWAITABLETIMEREX)      g_pfnCreateWaitableTimerExW = NULL;
    7981
    8082/** The native ntdll.dll handle. */
     
    513515        g_pfnGetSystemWindowsDirectoryW = (PFNGETWINSYSDIR)GetProcAddress(g_hModKernel32, "GetWindowsDirectoryW");
    514516    g_pfnSystemTimeToTzSpecificLocalTime = (decltype(SystemTimeToTzSpecificLocalTime) *)GetProcAddress(g_hModKernel32, "SystemTimeToTzSpecificLocalTime");
     517    g_pfnCreateWaitableTimerExW = (PFNCREATEWAITABLETIMEREX)GetProcAddress(g_hModKernel32, "CreateWaitableTimerExW");
    515518
    516519    /*
  • trunk/src/VBox/Runtime/r3/win/internal-r3-win.h

    r85124 r89827  
    105105extern DECL_HIDDEN_DATA(PFNGETWINSYSDIR)                g_pfnGetSystemWindowsDirectoryW;
    106106extern DECL_HIDDEN_DATA(decltype(SystemTimeToTzSpecificLocalTime) *) g_pfnSystemTimeToTzSpecificLocalTime;
     107typedef HANDLE (WINAPI *PFNCREATEWAITABLETIMEREX)(LPSECURITY_ATTRIBUTES, LPCWSTR, DWORD, DWORD);
     108extern DECL_HIDDEN_DATA(PFNCREATEWAITABLETIMEREX)       g_pfnCreateWaitableTimerExW;
    107109
    108110extern DECL_HIDDEN_DATA(HMODULE)                        g_hModNtDll;
  • trunk/src/VBox/Runtime/r3/win/timer-win.cpp

    r89764 r89827  
    4545#include <iprt/err.h>
    4646#include "internal/magics.h"
     47#include "internal-r3-win.h"
     48
     49
     50/** Define the flag for creating a manual reset timer if not available in the SDK we are compiling with. */
     51#ifndef CREATE_WAITABLE_TIMER_MANUAL_RESET
     52# define CREATE_WAITABLE_TIMER_MANUAL_RESET    0x00000001
     53#endif
     54/** Define the flag for high resolution timers, available since Windows 10 RS4 if not available. */
     55#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
     56# define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002
     57#endif
     58
    4759
    4860RT_C_DECLS_BEGIN
     
    228240
    229241
    230 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    231 {
    232     /*
    233      * We don't support the fancy MP features.
    234      */
    235     if (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
    236         return VERR_NOT_SUPPORTED;
    237 
     242/**
     243 * Tries to set the NT timer resolution to a value matching the given timer interval.
     244 *
     245 * @returns IPRT status code.
     246 * @param   u64NanoInterval             The timer interval in nano seconds.
     247 */
     248static int rtTimerNtSetTimerResolution(uint64_t u64NanoInterval)
     249{
    238250    /*
    239251     * On windows we'll have to set the timer resolution before
     
    266278    }
    267279
     280    return VINF_SUCCESS;
     281}
     282
     283
     284RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
     285{
     286    /*
     287     * We don't support the fancy MP features.
     288     */
     289    if (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
     290        return VERR_NOT_SUPPORTED;
     291
    268292    /*
    269293     * Create new timer.
     
    286310        {
    287311            /*
    288              * Create Win32 event semaphore.
     312             * Create Win32 waitable timer.
     313             * We will first try the undocumented CREATE_WAITABLE_TIMER_HIGH_RESOLUTION which
     314             * exists since some Windows 10 version (RS4). If this fails we resort to the old
     315             * method of setting the timer resolution before creating a timer which will probably
     316             * not give us the accuracy for intervals below the system tick resolution.
    289317             */
    290318            pTimer->iError = 0;
    291             pTimer->hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
     319            if (g_pfnCreateWaitableTimerExW)
     320                pTimer->hTimer = g_pfnCreateWaitableTimerExW(NULL, NULL,
     321                                                             CREATE_WAITABLE_TIMER_MANUAL_RESET | CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,
     322                                                             TIMER_ALL_ACCESS);
     323            if (!pTimer->hTimer)
     324            {           
     325                rc = rtTimerNtSetTimerResolution(u64NanoInterval);
     326                if (RT_SUCCESS(rc))
     327                    pTimer->hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
     328            }
     329
    292330            if (pTimer->hTimer)
    293331            {
     
    321359                CloseHandle(pTimer->hTimer);
    322360            }
     361            else
     362                rc = RTErrConvertFromWin32(GetLastError());
    323363            RTSemEventDestroy(pTimer->Event);
    324364            pTimer->Event = NIL_RTSEMEVENT;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette