RTDECL(int) RTTimerReleaseSystemGranularity(uint32_t u32Granted) { if (!g_pfnrtNtExSetTimerResolution) return VERR_NOT_SUPPORTED; g_pfnrtNtExSetTimerResolution(0 /* ignored */, FALSE); NOREF(u32Granted); return VINF_SUCCESS; }
RTDECL(int) RTTimerRequestSystemGranularity(uint32_t u32Request, uint32_t *pu32Granted) { if (!g_pfnrtNtExSetTimerResolution) return VERR_NOT_SUPPORTED; ULONG ulGranted = g_pfnrtNtExSetTimerResolution(u32Request / 100, TRUE); if (pu32Granted) *pu32Granted = ulGranted * 100; /* NT -> ns */ return VINF_SUCCESS; }
RTDECL(uint32_t) RTTimerGetSystemGranularity(void) { /* * Get the default/max timer increment value, return it if ExSetTimerResolution * isn't available. According to the sysinternals guys NtQueryTimerResolution * is only available in userland and they find it equally annoying. */ ULONG ulTimeInc = KeQueryTimeIncrement(); if (!g_pfnrtNtExSetTimerResolution) return ulTimeInc * 100; /* The value is in 100ns, the funny NT unit. */ /* * Use the value returned by ExSetTimerResolution. Since the kernel is keeping * count of these calls, we have to do two calls that cancel each other out. */ g_pfnrtNtExSetTimerResolution(ulTimeInc, TRUE); ULONG ulResolution = g_pfnrtNtExSetTimerResolution(0 /*ignored*/, FALSE); return ulResolution * 100; /* NT -> ns */ }