コード例 #1
0
ファイル: System.cpp プロジェクト: Kangz/Unvanquished
void SleepFor(SteadyClock::duration time) {
#ifdef _WIN32
    static ULONG maxRes = 0;
    static NTSTATUS(WINAPI * pNtSetTimerResolution)(
            ULONG resolution, BOOLEAN set_resolution, ULONG * current_resolution);
    static NTSTATUS(WINAPI * pNtDelayExecution)(BOOLEAN alertable,
                                                const LARGE_INTEGER* timeout);
    if (maxRes == 0) {
        // Load ntdll.dll functions
        std::string errorString;
        DynamicLib ntdll = DynamicLib::Open("ntdll.dll", errorString);
        if (!ntdll)
            Sys::Error("Failed to load ntdll.dll: %s", errorString);
        auto pNtQueryTimerResolution =
                ntdll.LoadSym<NTSTATUS WINAPI(ULONG*, ULONG*, ULONG*) >(
                        "NtQueryTimerResolution", errorString);
        if (!pNtQueryTimerResolution)
            Sys::Error("Failed to load NtQueryTimerResolution from ntdll.dll: %s",
                       errorString);
        pNtSetTimerResolution =
                ntdll.LoadSym<NTSTATUS WINAPI(ULONG, BOOLEAN, ULONG*) >(
                        "NtSetTimerResolution", errorString);
        if (!pNtSetTimerResolution)
            Sys::Error("Failed to load NtSetTimerResolution from ntdll.dll: %s",
                       errorString);
        pNtDelayExecution =
                ntdll.LoadSym<NTSTATUS WINAPI(BOOLEAN, const LARGE_INTEGER*) >(
                        "NtDelayExecution", errorString);
        if (!pNtDelayExecution)
            Sys::Error("Failed to load NtDelayExecution from ntdll.dll: %s",
                       errorString);

        // Determine the maximum available timer resolution
        ULONG minRes, curRes;
        if (pNtQueryTimerResolution(&minRes, &maxRes, &curRes) != 0)
            maxRes = 10000; // Default to 1ms
    }

    // Increase the system timer resolution for the duration of the sleep
    ULONG curRes;
    pNtSetTimerResolution(maxRes, TRUE, &curRes);

    // Convert to NT units of 100ns
    typedef std::chrono::duration<int64_t, std::ratio<1, 10000000>> NTDuration;
    auto ntTime = std::chrono::duration_cast<NTDuration>(time);

    // Store the delay as a negative number to indicate a relative sleep
    LARGE_INTEGER duration;
    duration.QuadPart = -ntTime.count();
    pNtDelayExecution(FALSE, &duration);

    // Restore timer resolution after sleeping
    pNtSetTimerResolution(maxRes, FALSE, &curRes);
#else
    std::this_thread::sleep_for(time);
#endif
}
コード例 #2
0
ファイル: native.c プロジェクト: palaniyappanBala/monitor
void sleep(uint32_t milliseconds)
{
    // This should only be the case at the very beginning of execution.
    if(pNtDelayExecution == NULL) {
        Sleep(milliseconds);
        return;
    }

    assert(pNtDelayExecution != NULL, "pNtDelayExecution is NULL!", );
    LARGE_INTEGER li;
    li.QuadPart = -10000 * (uint64_t) milliseconds;

    pNtDelayExecution(FALSE, &li);
}