blob: d238e53e21761909b9cf32a1b079a3d27fdacf6c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
#include "stdafx.h"
#include "DelayExecution.h"
namespace
{
constexpr bool useHighRezTimer = false;
constexpr int64_t sleepMicroseconds = 200;
inline HRESULT sleepImpl( HANDLE timer )
{
constexpr int64_t sleepTicks = sleepMicroseconds * 10;
LARGE_INTEGER li;
// Negative values indicate relative time
li.QuadPart = -sleepTicks;
if( !SetWaitableTimerEx( timer, &li, 0, nullptr, nullptr, nullptr, 0 ) )
return getLastHr();
const DWORD res = WaitForSingleObject( timer, 50 );
if( res == WAIT_OBJECT_0 )
return S_OK;
if( res == WAIT_FAILED )
return getLastHr();
return E_FAIL;
}
}
void DelayExecution::sleepOnTheTimer( const DelayExecution& delay )
{
HRESULT hr = sleepImpl( delay.timer );
if( SUCCEEDED( hr ) )
return;
logWarningHr( hr, u8"DelayExecution.sleepOnTheTimer" );
}
void DelayExecution::spinWait( const DelayExecution& )
{
for( size_t i = 0; i < 1024; i++ )
_mm_pause();
}
void DelayExecution::sleep( const DelayExecution& )
{
Sleep( 0 );
}
DelayExecution::DelayExecution()
{
if constexpr( useHighRezTimer )
{
constexpr DWORD flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
HANDLE h = CreateWaitableTimerEx( nullptr, nullptr, flags, TIMER_ALL_ACCESS );
if( nullptr != h )
{
timer.Attach( h );
pfn = &sleepOnTheTimer;
return;
}
const HRESULT hr = getLastHr();
logWarningHr( hr, u8"CreateWaitableTimerEx" );
}
pfn = &spinWait;
// pfn = &sleep;
}
|