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>
This commit is contained in:
parent
85a8076d08
commit
5b872e8cf9
10
wintun.c
10
wintun.c
@ -406,7 +406,9 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
|
|||||||
|
|
||||||
TUN_RING *Ring = Ctx->Device.Receive.Ring;
|
TUN_RING *Ring = Ctx->Device.Receive.Ring;
|
||||||
ULONG RingCapacity = Ctx->Device.Receive.Capacity;
|
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 };
|
VOID *Events[] = { &Ctx->Device.Disconnected, Ctx->Device.Receive.TailMoved };
|
||||||
ASSERT(RTL_NUMBER_OF(Events) <= THREAD_WAIT_OBJECTS);
|
ASSERT(RTL_NUMBER_OF(Events) <= THREAD_WAIT_OBJECTS);
|
||||||
|
|
||||||
@ -420,8 +422,7 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
|
|||||||
ULONG RingTail = InterlockedGetU(&Ring->Tail);
|
ULONG RingTail = InterlockedGetU(&Ring->Tail);
|
||||||
if (RingHead == RingTail)
|
if (RingHead == RingTail)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER SpinStart;
|
LARGE_INTEGER SpinStart = KeQueryPerformanceCounter(NULL);
|
||||||
KeQueryTickCount(&SpinStart);
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
RingTail = InterlockedGetU(&Ring->Tail);
|
RingTail = InterlockedGetU(&Ring->Tail);
|
||||||
@ -429,8 +430,7 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
|
|||||||
break;
|
break;
|
||||||
if (KeReadStateEvent(&Ctx->Device.Disconnected))
|
if (KeReadStateEvent(&Ctx->Device.Disconnected))
|
||||||
break;
|
break;
|
||||||
LARGE_INTEGER SpinNow;
|
LARGE_INTEGER SpinNow = KeQueryPerformanceCounter(NULL);
|
||||||
KeQueryTickCount(&SpinNow);
|
|
||||||
if ((ULONG64)SpinNow.QuadPart - (ULONG64)SpinStart.QuadPart >= SpinMax)
|
if ((ULONG64)SpinNow.QuadPart - (ULONG64)SpinStart.QuadPart >= SpinMax)
|
||||||
break;
|
break;
|
||||||
ZwYieldExecution();
|
ZwYieldExecution();
|
||||||
|
Loading…
Reference in New Issue
Block a user