Skip to content

Commit 20facbc

Browse files
committed
spl-time: Use KeQueryPerformanceCounter instead of KeQueryTickCount
`KeQueryTickCount` seems to only have a 15.625ms resolution unless the interrupt timer frequency is increased, which should be avoided due to power usage. Instead, this switches the `zfs_lbolt`, `gethrtime` and `random_get_bytes` to use `KeQueryPerformanceCounter`. On my system this gives a 100ns resolution. Signed-off-by: Axel Gembe <axel@gembe.net>
1 parent 516c987 commit 20facbc

File tree

1 file changed

+9
-18
lines changed

1 file changed

+9
-18
lines changed

module/os/windows/spl/spl-time.c

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,12 @@
3737
* origin. Hence its primary use is to specify intervals.
3838
*/
3939

40-
static hrtime_t
41-
zfs_abs_to_nano(uint64_t elapsed)
42-
{
43-
return (elapsed * KeQueryTimeIncrement() * 100);
44-
}
45-
4640
/* Open Solaris lbolt is in hz */
4741
uint64_t
4842
zfs_lbolt(void)
4943
{
5044
uint64_t lbolt_hz;
51-
LARGE_INTEGER ticks;
52-
KeQueryTickCount(&ticks);
53-
lbolt_hz = ticks.QuadPart * KeQueryTimeIncrement();
45+
lbolt_hz = gethrtime() / 100;
5446
lbolt_hz /= (10000000 / 119); // Solaris hz ?
5547
return (lbolt_hz);
5648
}
@@ -59,14 +51,13 @@ hrtime_t
5951
gethrtime(void)
6052
{
6153
static LARGE_INTEGER start = { 0 };
54+
static LARGE_INTEGER freq = { 0 };
6255
LARGE_INTEGER now;
6356
if (start.QuadPart == 0) {
64-
KeQueryTickCount(&start);
65-
start.QuadPart--;
57+
start = KeQueryPerformanceCounter(&freq);
6658
}
67-
KeQueryTickCount(&now);
68-
ASSERT((now.QuadPart != start.QuadPart));
69-
return (zfs_abs_to_nano(now.QuadPart - start.QuadPart));
59+
now = KeQueryPerformanceCounter(NULL);
60+
return (now.QuadPart - start.QuadPart) * (NANOSEC / freq.QuadPart);
7061
}
7162

7263
/*
@@ -76,21 +67,21 @@ gethrtime(void)
7667
int
7768
random_get_bytes(uint8_t *ptr, uint32_t len)
7869
{
79-
LARGE_INTEGER TickCount;
70+
LARGE_INTEGER PerfCounter;
8071
ULONG r;
8172
PULONG b;
8273
int i;
8374

84-
KeQueryTickCount(&TickCount);
75+
PerfCounter = KeQueryPerformanceCounter(NULL);
8576

8677
b = (PULONG) ptr;
8778

8879
for (i = 0; i < len / sizeof (ULONG); i++)
89-
b[i] = RtlRandomEx(&TickCount.LowPart);
80+
b[i] = RtlRandomEx(&PerfCounter.LowPart);
9081

9182
len &= (sizeof (ULONG) - 1);
9283
if (len > 0) {
93-
r = RtlRandomEx(&TickCount.LowPart);
84+
r = RtlRandomEx(&PerfCounter.LowPart);
9485
RtlCopyMemory(&b[i], &r, len);
9586
}
9687
return (0);

0 commit comments

Comments
 (0)