Search code examples
cwinapitimersleep

64bit precision Sleep function?


Currently Sleep takes a single DWORD (32bit) for time. Is there any alternative which takes DWORDLONG (64bit)?

I'm using RNG in which with every additional byte added the overall wait time increases. With 32bit integer the overall time is 5 minutes and I want to increase it.


Solution

  • Sleep[Ex] internal call NtDelayExecution - undocumented but exist in all windows nt versions (from nt 4 to win 10) - exported by ntdll.dll - use ntdll.lib or ntdllp.lib from wdk. as result of this call in kernel will be called documented function KeDelayExecutionThread

    //extern "C"
    NTSYSAPI 
    NTSTATUS
    NTAPI
    NtDelayExecution(
      IN BOOLEAN              Alertable,
      IN PLARGE_INTEGER       Interval );
    
    • Alertable

    Specifies TRUE if the wait is alertable. Lower-level drivers should specify FALSE.

    • Interval

    Specifies the absolute or relative time, in units of 100 nanoseconds, for which the wait is to occur. A negative value indicates relative time. Absolute expiration times track any changes in system time; relative expiration times are not affected by system time changes.

    Sleep[Ex] is win32 shell, over this native api, which restrict interval value (from 64 to 32 bit) can not set absolute time (possible with NtDelayExecution) and ignore alerts (we can exit from NtDelayExecution via alert thread if wait alertable)

    so you can direct call this api instead indirect via Sleep[Ex]

    so Sleep(dwMilliseconds) is call SleepEx(dwMilliseconds, false)

    SleepEx(dwMilliseconds, bAlertable) 
    

    call

    LARGE_INTEGER  Interval;
    Interval.QuadPart = -(dwMilliseconds * 10000);
    NtDelayExecution(bALertable, &Interval);
    

    note that in case alertable wait it can be broken via apc (api return STATUS_USER_APC) or via alert ( STATUS_ALERTED will be returned. we can alert thread via NtAlertThread). the SleepEx check returned status and in case STATUS_ALERTED - again begin wait with updated interval. so SleepEx wait can not be broken via alert (NtAlertThread) but NtDelayExecution can