From 63d0bb53e43ceac065f995ab5ecb258f754a0eca Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 26 Aug 2012 22:31:18 +0000 Subject: [PATCH] [AFD] - Change AFD to a very aggressive buffering policy - It now attempts to keep its 64K receive buffer completely full at all times - This increases network performance significantly svn path=/trunk/; revision=57170 --- reactos/drivers/network/afd/afd/read.c | 112 ++++++++++++++----------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/reactos/drivers/network/afd/afd/read.c b/reactos/drivers/network/afd/afd/read.c index 7435c7c1efb..b45a96e51f8 100644 --- a/reactos/drivers/network/afd/afd/read.c +++ b/reactos/drivers/network/afd/afd/read.c @@ -6,52 +6,83 @@ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net) * UPDATE HISTORY: * 20040708 Created - * - * Improve buffering code - * - * We're keeping data receiving in one of two states: - * A) Some data available in the FCB - * FCB->Recv.BytesUsed != FCB->Recv.Content - * FCB->ReceiveIrp.InFlightRequest == NULL - * AFD_EVENT_RECEIVE set in FCB->PollState - * B) No data available in the FCB - * FCB->Recv.BytesUsed == FCB->Recv.Content (== 0) - * FCB->RecieveIrp.InFlightRequest != NULL - * AFD_EVENT_RECEIVED not set in FCB->PollState - * So basically we either have data available or a TDI receive - * in flight. */ #include "afd.h" +static VOID RefillSocketBuffer( PAFD_FCB FCB ) +{ + /* Make sure nothing's in flight first */ + if (FCB->ReceiveIrp.InFlightRequest) return; + + /* Now ensure that receive is still allowed */ + if (FCB->TdiReceiveClosed) return; + + /* Check if the buffer is full */ + if (FCB->Recv.Content == FCB->Recv.Size) + { + /* If there are bytes used, we can solve this problem */ + if (FCB->Recv.BytesUsed != 0) + { + /* Reposition the unused portion to the beginning of the receive window */ + RtlMoveMemory(FCB->Recv.Window, + FCB->Recv.Window + FCB->Recv.BytesUsed, + FCB->Recv.Content - FCB->Recv.BytesUsed); + + FCB->Recv.Content -= FCB->Recv.BytesUsed; + FCB->Recv.BytesUsed = 0; + } + else + { + /* No space in the buffer to receive */ + return; + } + } + + AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n")); + + TdiReceive( &FCB->ReceiveIrp.InFlightRequest, + FCB->Connection.Object, + TDI_RECEIVE_NORMAL, + FCB->Recv.Window + FCB->Recv.Content, + FCB->Recv.Size - FCB->Recv.Content, + &FCB->ReceiveIrp.Iosb, + ReceiveComplete, + FCB ); +} + static VOID HandleReceiveComplete( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information ) { - FCB->Recv.BytesUsed = 0; - /* We got closed while the receive was in progress */ if (FCB->TdiReceiveClosed) { FCB->Recv.Content = 0; + FCB->Recv.BytesUsed = 0; } - /* Receive successful with new data */ - else if (Status == STATUS_SUCCESS && Information) - { - FCB->Recv.Content = Information; - } - /* Receive successful with no data (graceful closure) */ + /* Receive successful */ else if (Status == STATUS_SUCCESS) { - FCB->Recv.Content = 0; - FCB->TdiReceiveClosed = TRUE; + FCB->Recv.Content += Information; + ASSERT(FCB->Recv.Content <= FCB->Recv.Size); - /* Signal graceful receive shutdown */ - FCB->PollState |= AFD_EVENT_DISCONNECT; - FCB->PollStatus[FD_CLOSE_BIT] = Status; + /* Check for graceful closure */ + if (Information == 0) + { + FCB->TdiReceiveClosed = TRUE; - PollReeval( FCB->DeviceExt, FCB->FileObject ); + /* Signal graceful receive shutdown */ + FCB->PollState |= AFD_EVENT_DISCONNECT; + FCB->PollStatus[FD_CLOSE_BIT] = Status; + + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } + + /* Issue another receive IRP to keep the buffer well stocked */ + RefillSocketBuffer(FCB); } /* Receive failed with no data (unexpected closure) */ else { + FCB->Recv.BytesUsed = 0; FCB->Recv.Content = 0; FCB->TdiReceiveClosed = TRUE; @@ -69,22 +100,6 @@ static BOOLEAN CantReadMore( PAFD_FCB FCB ) { return !BytesAvailable && FCB->TdiReceiveClosed; } -static VOID RefillSocketBuffer( PAFD_FCB FCB ) { - if( !FCB->ReceiveIrp.InFlightRequest && - !FCB->TdiReceiveClosed ) { - AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n")); - - TdiReceive( &FCB->ReceiveIrp.InFlightRequest, - FCB->Connection.Object, - TDI_RECEIVE_NORMAL, - FCB->Recv.Window, - FCB->Recv.Size, - &FCB->ReceiveIrp.Iosb, - ReceiveComplete, - FCB ); - } -} - static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, PAFD_RECV_INFO RecvReq, PUINT TotalBytesCopied ) { @@ -137,13 +152,8 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, } } - /* If there's nothing left in our buffer start a new request */ - if( FCB->Recv.BytesUsed == FCB->Recv.Content ) { - FCB->Recv.BytesUsed = FCB->Recv.Content = 0; - FCB->PollState &= ~AFD_EVENT_RECEIVE; - - RefillSocketBuffer( FCB ); - } + /* Issue another receive IRP to keep the buffer well stocked */ + RefillSocketBuffer(FCB); return STATUS_SUCCESS; }