Credits go to deltarho (https://www.freebasic.net/forum/viewtopic.php?f=2&t=27371&p=257539#p257534) 8)
include \masm32\MasmBasic\MasmBasic.inc ; the macro works also with pure Masm32
VeryHiResSleep MACRO msSleep ; milliseconds
pushad
rdtsc
xchg eax, ebx
mov edi, edx
push eax
push edx
invoke QueryPerformanceFrequency, esp
fld FP4(msSleep)
fild qword ptr [esp]
fmul
fmul FP4(1.023986) ; magic to compensate whatever
fistp qword ptr [esp]
pop eax
pop edx
add ebx, eax
add edi, edx
.Repeat
rdtsc
.Until eax>ebx && edx>=edi
popad
exitm <>
ENDM
Init
Delay 100
For_ ecx=1 To 100
Delay 1
NanoTimer()
VeryHiResSleep(123.456789)
void NanoTimer(µs)
.if eax>127
PrintLine Str$("%6f\t\t", eax/1000), Str$(ecx)
.endif
Next
Inkey "ok?"
EndOfCode
Expected result:
123.456 1
123.456 2
123.456 3
123.456 4
123.456 5
123.456 6
123.456 7
123.456 8
123.456 9
What do you see?
What do I see? This
351.264 1
351.263 2
351.263 6
351.263 7
351.263 8
351.264 17
351.263 18
351.263 19
351.263 34
351.264 35
351.264 36
351.263 43
351.264 44
351.264 45
351.263 53
351.263 54
351.263 55
351.263 65
351.263 66
351.264 67
351.264 88
351.264 89
351.263 90
Oops, so the "magic" is not a constant. A calibration would be needed then. Thanks :icon14:
532.052 1
532.053 2
532.052 84
532.052 85
ok?
It looks more like a timed stalling than a timed sleep....
Maybe this is an option:
IReferenceClock::GetTime
IReferenceClock::AdviseTime
https://docs.microsoft.com/en-us/windows/desktop/wmformat/ireferenceclock
It's an event driven 100-nanosecond units resolution timer.
I've used it succesful in creating a Timer-Interrupt routine to get the lowest possible latency in DirectSound without wasting system resources.
Quote from: Siekmanski on January 23, 2019, 07:28:00 PMIt looks more like a timed stalling than a timed sleep....
Yes, it's more a joke.
QuoteIReferenceClock::GetTime
IReferenceClock::AdviseTime
https://docs.microsoft.com/en-us/windows/desktop/wmformat/ireferenceclock
It's an event driven 100-nanosecond units resolution timer.
Looks interesting, but I wouldn't be surprised to find NtDelayExecution under the hood. And that one is already used in
Delay until fTime$(s:1, "HH:mm:ss.123") ; use time$(current plus one second).
Don't know exactly, worth investigating. :biggrin:
I'll write something tonight so we can test it further.
Silly small test project with PDB for debugging.
int main(void)
{
CoInitialize( NULL );
IReferenceClock* pRefClock;
HRESULT hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (void**)&pRefClock );
if (pRefClock) {
long long llTime1, llTime2;
DWORD dwCookie;
hr = pRefClock->lpVtbl->GetTime(pRefClock, &llTime1);
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("MyEvent"));
hr = pRefClock->lpVtbl->AdviseTime(pRefClock, llTime1, 10000000, hEvent, &dwCookie);
if (!hr) {
printf("wait...");
WaitForSingleObject(hEvent, INFINITE);
} else printf("error");
hr = pRefClock->lpVtbl->GetTime(pRefClock, &llTime2);
printf("time: %lld\n", llTime2 - llTime1);
pRefClock->lpVtbl->Release(pRefClock);
}
CoUninitialize();
return 0;
}
IReferenceClock Sleep test.
The results are a bit disappointing for small resolutions....
Resolution: 1.0 second
0.999471650726559 seconds
1.000116704776725 seconds
1.000111326998264 seconds
1.000117542872069 seconds
Resolution: 0.1 seconds
0.099520679304213 seconds
0.099822114263126 seconds
0.099843834900804 seconds
0.099841250773492 seconds
Resolution: 0.01 seconds
0.009674832974582 seconds
0.009806623467508 seconds
0.010794737878697 seconds
0.009871436174151 seconds
Resolution: 0.001 seconds
0.000068374611857 seconds
0.000069771437431 seconds
0.000074450803105 seconds
0.000027447622533 seconds
Resolution: 0.0001 seconds
0.000060063499691 seconds
0.000067326992676 seconds
0.000069352389759 seconds
0.000068234929300 seconds
Resolution: 0.00001 seconds
0.000039320639914 seconds
0.000040088893980 seconds
0.000059853975854 seconds
0.000068095246742 seconds
I think you will always have limitations due to ring 0 task switching.
Yep, it's a bit of a problem with the timers in windows.
We have to accept it. :biggrin:
At least we can delay the execution with ~0.00005 seconds which is 20 times shorter than invoke Sleep,1
It can be useful in high performance apps.
123.457 1
123.457 2
123.457 3
123.458 4
123.457 5
123.459 6
123.457 7
123.457 8
123.457 9
123.457 10
123.457 11
123.457 12
123.456 13
123.457 14
123.457 15
123.457 16
123.457 17
123.458 18
123.457 19
123.457 20
123.457 29
123.456 30
123.457 31
123.457 32
123.457 33
123.457 34
123.456 35
123.456 36
123.457 37
123.459 38
123.457 39
123.457 40
123.457 41
123.457 42
123.457 43
123.457 44
123.457 45
123.457 46
123.456 47
123.457 48
123.457 49
123.457 54
123.457 55
123.457 56
123.459 57
123.457 58
123.457 59
123.458 60
123.457 61
123.457 62
123.457 63
123.457 64
123.457 65
123.457 66
123.457 67
123.458 68
123.457 69
123.456 70
123.457 71
123.459 72
123.457 73
123.457 74
123.457 78
123.457 79
123.457 80
123.457 81
123.457 82
123.456 83
123.457 84
123.458 85
123.458 86
123.458 87
123.458 88
123.457 89
123.457 90
123.457 91
123.458 92
123.457 93
123.457 94
123.457 95
123.458 96
123.457 97
123.455 98
ok?
And I thought 'High Resolution Sleep' meant that you slept well, and your dreams were so vivid you thought they were real life in real time. :P