aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-08-04 10:18:42 +0000
committerJason A. Donenfeld <Jason@zx2c4.com>2019-08-04 11:13:39 +0000
commit5b872e8cf9f5b6800512005abb310596dc9ea771 (patch)
tree977e1b5e115db83b20357b90d63b54eb83b148b7
parentSpin less and more efficiently (diff)
downloadwintun-5b872e8cf9f5b6800512005abb310596dc9ea771.tar.xz
wintun-5b872e8cf9f5b6800512005abb310596dc9ea771.zip
Use performance counter for less spinning
Previously we had to spin for a minimum of 15ms because the tick interval is 156250 on NT. On linux, usually trips to the high performance timers are discouraged because if they don't hit the RDTSC path (due to being unstable or the like), they hit more expensive hardware. I assume that's probably the same on NT, but all of tcpip.sys and ndis.sys uses the performance counters too, so what are we going to do? Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--wintun.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/wintun.c b/wintun.c
index 9486457..1bc0769 100644
--- a/wintun.c
+++ b/wintun.c
@@ -406,7 +406,9 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
TUN_RING *Ring = Ctx->Device.Receive.Ring;
ULONG RingCapacity = Ctx->Device.Receive.Capacity;
- const ULONG SpinMax = 10000 * 20 / KeQueryTimeIncrement(); /* 20 ms */
+ LARGE_INTEGER Frequency;
+ KeQueryPerformanceCounter(&Frequency);
+ ULONG64 SpinMax = Frequency.QuadPart / 1000 / 10; /* 1/10 ms */
VOID *Events[] = { &Ctx->Device.Disconnected, Ctx->Device.Receive.TailMoved };
ASSERT(RTL_NUMBER_OF(Events) <= THREAD_WAIT_OBJECTS);
@@ -420,8 +422,7 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
ULONG RingTail = InterlockedGetU(&Ring->Tail);
if (RingHead == RingTail)
{
- LARGE_INTEGER SpinStart;
- KeQueryTickCount(&SpinStart);
+ LARGE_INTEGER SpinStart = KeQueryPerformanceCounter(NULL);
for (;;)
{
RingTail = InterlockedGetU(&Ring->Tail);
@@ -429,8 +430,7 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
break;
if (KeReadStateEvent(&Ctx->Device.Disconnected))
break;
- LARGE_INTEGER SpinNow;
- KeQueryTickCount(&SpinNow);
+ LARGE_INTEGER SpinNow = KeQueryPerformanceCounter(NULL);
if ((ULONG64)SpinNow.QuadPart - (ULONG64)SpinStart.QuadPart >= SpinMax)
break;
ZwYieldExecution();