Author: cgutman Date: Fri Aug 5 20:55:57 2011 New Revision: 53089
URL: http://svn.reactos.org/svn/reactos?rev=53089&view=rev Log: [LWIP] - Use lookaside lists for allocating lwIP callback messages and packet queue entries for a small speed boost
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/include/rosip.h branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/include/rosip.h URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/include/rosip.h [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/include/rosip.h [iso-8859-1] Fri Aug 5 20:55:57 2011 @@ -17,6 +17,72 @@ struct pbuf *p; LIST_ENTRY ListEntry; } QUEUE_ENTRY, *PQUEUE_ENTRY; + +struct lwip_callback_msg +{ + /* Synchronization */ + KEVENT Event; + + /* Input */ + union { + struct { + PVOID Arg; + } Socket; + struct { + PCONNECTION_ENDPOINT Connection; + struct ip_addr *IpAddress; + u16_t Port; + } Bind; + struct { + PCONNECTION_ENDPOINT Connection; + u8_t Backlog; + } Listen; + struct { + PCONNECTION_ENDPOINT Connection; + void *Data; + u16_t DataLength; + } Send; + struct { + PCONNECTION_ENDPOINT Connection; + struct ip_addr *IpAddress; + u16_t Port; + } Connect; + struct { + PCONNECTION_ENDPOINT Connection; + int shut_rx; + int shut_tx; + } Shutdown; + struct { + PCONNECTION_ENDPOINT Connection; + int Callback; + } Close; + } Input; + + /* Output */ + union { + struct { + struct tcp_pcb *NewPcb; + } Socket; + struct { + err_t Error; + } Bind; + struct { + struct tcp_pcb *NewPcb; + } Listen; + struct { + err_t Error; + } Send; + struct { + err_t Error; + } Connect; + struct { + err_t Error; + } Shutdown; + struct { + err_t Error; + } Close; + } Output; +};
NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT Connection, PUCHAR RecvBuffer, UINT RecvLen, UINT *Received);
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/rostcp.c [iso-8859-1] Fri Aug 5 20:55:57 2011 @@ -28,6 +28,8 @@ * to going messing around in lwIP because I have no desire to create another mess like oskittcp */
extern KEVENT TerminationEvent; +extern NPAGED_LOOKASIDE_LIST MessageLookasideList; +extern NPAGED_LOOKASIDE_LIST QueueEntryLookasideList;
static void @@ -37,7 +39,6 @@ PQUEUE_ENTRY qp = NULL;
ReferenceObject(Connection); -
while (!IsListEmpty(&Connection->PacketQueue)) { @@ -47,7 +48,7 @@ /* We're in the tcpip thread here so this is safe */ pbuf_free(qp->p);
- ExFreePoolWithTag(qp, LWIP_TAG); + ExFreeToNPagedLookasideList(&QueueEntryLookasideList, qp); }
DereferenceObject(Connection); @@ -57,7 +58,7 @@ { PQUEUE_ENTRY qp;
- qp = (PQUEUE_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(QUEUE_ENTRY), LWIP_TAG); + qp = (PQUEUE_ENTRY)ExAllocateFromNPagedLookasideList(&QueueEntryLookasideList); qp->p = p;
ExInterlockedInsertTailList(&Connection->PacketQueue, &qp->ListEntry, &Connection->Lock); @@ -96,7 +97,7 @@ /* Use this special pbuf free callback function because we're outside tcpip thread */ pbuf_free_callback(qp->p);
- ExFreePoolWithTag(qp, LWIP_TAG); + ExFreeToNPagedLookasideList(&QueueEntryLookasideList, qp);
Status = STATUS_SUCCESS; } @@ -198,7 +199,7 @@ */ TCPFinEventHandler(arg, ERR_OK); } - + return ERR_OK; }
@@ -209,9 +210,9 @@ /* Make sure the socket didn't get closed */ if (!arg) return ERR_ABRT; - + TCPAcceptEventHandler(arg, newpcb); - + /* Set in LibTCPAccept (called from TCPAcceptEventHandler) */ if (newpcb->callback_arg) return ERR_OK; @@ -226,9 +227,9 @@ /* Make sure the socket didn't get closed */ if (!arg) return ERR_OK; - + TCPConnectEventHandler(arg, err); - + return ERR_OK; }
@@ -238,60 +239,48 @@ { /* Make sure the socket didn't get closed */ if (!arg) return; - + TCPFinEventHandler(arg, err); }
-struct socket_callback_msg -{ - /* Synchronization */ - KEVENT Event; - - /* Input */ - PVOID Arg; - - /* Output */ - struct tcp_pcb *NewPcb; -}; - static void LibTCPSocketCallback(void *arg) { - struct socket_callback_msg *msg = arg; - + struct lwip_callback_msg *msg = arg; + ASSERT(msg); - - msg->NewPcb = tcp_new(); - - if (msg->NewPcb) - { - tcp_arg(msg->NewPcb, msg->Arg); - tcp_err(msg->NewPcb, InternalErrorEventHandler); - } - + + msg->Output.Socket.NewPcb = tcp_new(); + + if (msg->Output.Socket.NewPcb) + { + tcp_arg(msg->Output.Socket.NewPcb, msg->Input.Socket.Arg); + tcp_err(msg->Output.Socket.NewPcb, InternalErrorEventHandler); + } + KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE); }
struct tcp_pcb * LibTCPSocket(void *arg) { - struct socket_callback_msg *msg = ExAllocatePool(NonPagedPool, sizeof(struct socket_callback_msg)); + struct lwip_callback_msg *msg = ExAllocateFromNPagedLookasideList(&MessageLookasideList); struct tcp_pcb *ret;
if (msg) { KeInitializeEvent(&msg->Event, NotificationEvent, FALSE); - msg->Arg = arg; - + msg->Input.Socket.Arg = arg; + tcpip_callback_with_block(LibTCPSocketCallback, msg, 1); - + if (WaitForEventSafely(&msg->Event)) - ret = msg->NewPcb; + ret = msg->Output.Socket.NewPcb; else ret = NULL;
- ExFreePool(msg); + ExFreeToNPagedLookasideList(&MessageLookasideList, msg);
return ret; } @@ -299,37 +288,23 @@ return NULL; }
-struct bind_callback_msg -{ - /* Synchronization */ - KEVENT Event; - - /* Input */ - PCONNECTION_ENDPOINT Connection; - struct ip_addr *IpAddress; - u16_t Port; - - /* Output */ - err_t Error; -}; - static void LibTCPBindCallback(void *arg) { - struct bind_callback_msg *msg = arg; - + struct lwip_callback_msg *msg = arg; + ASSERT(msg); - - if (!msg->Connection->SocketContext) - { - msg->Error = ERR_CLSD; + + if (!msg->Input.Bind.Connection->SocketContext) + { + msg->Output.Bind.Error = ERR_CLSD; goto done; } - - msg->Error = tcp_bind((PTCP_PCB)msg->Connection->SocketContext, - msg->IpAddress, - ntohs(msg->Port)); + + msg->Output.Bind.Error = tcp_bind((PTCP_PCB)msg->Input.Bind.Connection->SocketContext, + msg->Input.Bind.IpAddress, + ntohs(msg->Input.Bind.Port));
done: KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE); @@ -338,25 +313,25 @@ err_t LibTCPBind(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr, const u16_t port) { - struct bind_callback_msg *msg; + struct lwip_callback_msg *msg; err_t ret;
- msg = ExAllocatePool(NonPagedPool, sizeof(struct bind_callback_msg)); + msg = ExAllocateFromNPagedLookasideList(&MessageLookasideList); if (msg) { KeInitializeEvent(&msg->Event, NotificationEvent, FALSE); - msg->Connection = Connection; - msg->IpAddress = ipaddr; - msg->Port = port; + msg->Input.Bind.Connection = Connection; + msg->Input.Bind.IpAddress = ipaddr; + msg->Input.Bind.Port = port;
tcpip_callback_with_block(LibTCPBindCallback, msg, 1);
if (WaitForEventSafely(&msg->Event)) - ret = msg->Error; + ret = msg->Output.Bind.Error; else ret = ERR_CLSD;
- ExFreePool(msg); + ExFreeToNPagedLookasideList(&MessageLookasideList, msg);
return ret; } @@ -364,38 +339,25 @@ return ERR_MEM; }
-struct listen_callback_msg -{ - /* Synchronization */ - KEVENT Event; - - /* Input */ - PCONNECTION_ENDPOINT Connection; - u8_t Backlog; - - /* Output */ - PTCP_PCB NewPcb; -}; - static void LibTCPListenCallback(void *arg) { - struct listen_callback_msg *msg = arg; + struct lwip_callback_msg *msg = arg;
ASSERT(msg);
- if (!msg->Connection->SocketContext) - { - msg->NewPcb = NULL; + if (!msg->Input.Listen.Connection->SocketContext) + { + msg->Output.Listen.NewPcb = NULL; goto done; }
- msg->NewPcb = tcp_listen_with_backlog((PTCP_PCB)msg->Connection->SocketContext, msg->Backlog); - - if (msg->NewPcb) - { - tcp_accept(msg->NewPcb, InternalAcceptEventHandler); + msg->Output.Listen.NewPcb = tcp_listen_with_backlog((PTCP_PCB)msg->Input.Listen.Connection->SocketContext, msg->Input.Listen.Backlog); + + if (msg->Output.Listen.NewPcb) + { + tcp_accept(msg->Output.Listen.NewPcb, InternalAcceptEventHandler); }
done: @@ -405,24 +367,24 @@ PTCP_PCB LibTCPListen(PCONNECTION_ENDPOINT Connection, const u8_t backlog) { - struct listen_callback_msg *msg; + struct lwip_callback_msg *msg; PTCP_PCB ret;
- msg = ExAllocatePool(NonPagedPool, sizeof(struct listen_callback_msg)); + msg = ExAllocateFromNPagedLookasideList(&MessageLookasideList); if (msg) { KeInitializeEvent(&msg->Event, NotificationEvent, FALSE); - msg->Connection = Connection; - msg->Backlog = backlog; + msg->Input.Listen.Connection = Connection; + msg->Input.Listen.Backlog = backlog;
tcpip_callback_with_block(LibTCPListenCallback, msg, 1);
if (WaitForEventSafely(&msg->Event)) - ret = msg->NewPcb; + ret = msg->Output.Listen.NewPcb; else ret = NULL;
- ExFreePool(msg); + ExFreeToNPagedLookasideList(&MessageLookasideList, msg);
return ret; } @@ -430,46 +392,32 @@ return NULL; }
-struct send_callback_msg -{ - /* Synchronization */ - KEVENT Event; - - /* Input */ - PCONNECTION_ENDPOINT Connection; - void *Data; - u16_t DataLength; - - /* Output */ - err_t Error; -}; - static void LibTCPSendCallback(void *arg) { - struct send_callback_msg *msg = arg; + struct lwip_callback_msg *msg = arg;
ASSERT(msg);
- if (!msg->Connection->SocketContext) - { - msg->Error = ERR_CLSD; + if (!msg->Input.Send.Connection->SocketContext) + { + msg->Output.Send.Error = ERR_CLSD; goto done; }
- if (tcp_sndbuf((PTCP_PCB)msg->Connection->SocketContext) < msg->DataLength) - { - msg->Error = ERR_INPROGRESS; + if (tcp_sndbuf((PTCP_PCB)msg->Input.Send.Connection->SocketContext) < msg->Input.Send.DataLength) + { + msg->Output.Send.Error = ERR_INPROGRESS; } else { - msg->Error = tcp_write((PTCP_PCB)msg->Connection->SocketContext, - msg->Data, - msg->DataLength, - TCP_WRITE_FLAG_COPY); - - tcp_output((PTCP_PCB)msg->Connection->SocketContext); + msg->Output.Send.Error = tcp_write((PTCP_PCB)msg->Input.Send.Connection->SocketContext, + msg->Input.Send.Data, + msg->Input.Send.DataLength, + TCP_WRITE_FLAG_COPY); + + tcp_output((PTCP_PCB)msg->Input.Send.Connection->SocketContext); }
done: @@ -480,15 +428,15 @@ LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t len, const int safe) { err_t ret; - struct send_callback_msg *msg; - - msg = ExAllocatePool(NonPagedPool, sizeof(struct send_callback_msg)); + struct lwip_callback_msg *msg; + + msg = ExAllocateFromNPagedLookasideList(&MessageLookasideList); if (msg) { KeInitializeEvent(&msg->Event, NotificationEvent, FALSE); - msg->Connection = Connection; - msg->Data = dataptr; - msg->DataLength = len; + msg->Input.Send.Connection = Connection; + msg->Input.Send.Data = dataptr; + msg->Input.Send.DataLength = len;
if (safe) LibTCPSendCallback(msg); @@ -496,11 +444,11 @@ tcpip_callback_with_block(LibTCPSendCallback, msg, 1);
if (WaitForEventSafely(&msg->Event)) - ret = msg->Error; + ret = msg->Output.Send.Error; else ret = ERR_CLSD;
- ExFreePool(msg); + ExFreeToNPagedLookasideList(&MessageLookasideList, msg);
return ret; } @@ -508,42 +456,28 @@ return ERR_MEM; }
-struct connect_callback_msg -{ - /* Synchronization */ - KEVENT Event; - - /* Input */ - PCONNECTION_ENDPOINT Connection; - struct ip_addr *IpAddress; - u16_t Port; - - /* Output */ - err_t Error; -}; - static void LibTCPConnectCallback(void *arg) { - struct connect_callback_msg *msg = arg; + struct lwip_callback_msg *msg = arg;
ASSERT(arg);
- if (!msg->Connection->SocketContext) - { - msg->Error = ERR_CLSD; + if (!msg->Input.Connect.Connection->SocketContext) + { + msg->Output.Connect.Error = ERR_CLSD; goto done; }
- tcp_recv((PTCP_PCB)msg->Connection->SocketContext, InternalRecvEventHandler); - tcp_sent((PTCP_PCB)msg->Connection->SocketContext, InternalSendEventHandler); - - err_t Error = tcp_connect((PTCP_PCB)msg->Connection->SocketContext, - msg->IpAddress, ntohs(msg->Port), + tcp_recv((PTCP_PCB)msg->Input.Connect.Connection->SocketContext, InternalRecvEventHandler); + tcp_sent((PTCP_PCB)msg->Input.Connect.Connection->SocketContext, InternalSendEventHandler); + + err_t Error = tcp_connect((PTCP_PCB)msg->Input.Connect.Connection->SocketContext, + msg->Input.Connect.IpAddress, ntohs(msg->Input.Connect.Port), InternalConnectEventHandler);
- msg->Error = Error == ERR_OK ? ERR_INPROGRESS : Error; + msg->Output.Connect.Error = Error == ERR_OK ? ERR_INPROGRESS : Error;
done: KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE); @@ -552,27 +486,27 @@ err_t LibTCPConnect(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr, const u16_t port) { - struct connect_callback_msg *msg; + struct lwip_callback_msg *msg; err_t ret;
- msg = ExAllocatePool(NonPagedPool, sizeof(struct connect_callback_msg)); + msg = ExAllocateFromNPagedLookasideList(&MessageLookasideList); if (msg) { KeInitializeEvent(&msg->Event, NotificationEvent, FALSE); - msg->Connection = Connection; - msg->IpAddress = ipaddr; - msg->Port = port; + msg->Input.Connect.Connection = Connection; + msg->Input.Connect.IpAddress = ipaddr; + msg->Input.Connect.Port = port;
tcpip_callback_with_block(LibTCPConnectCallback, msg, 1);
if (WaitForEventSafely(&msg->Event)) { - ret = msg->Error; + ret = msg->Output.Connect.Error; } else ret = ERR_CLSD;
- ExFreePool(msg); + ExFreeToNPagedLookasideList(&MessageLookasideList, msg);
return ret; } @@ -580,43 +514,29 @@ return ERR_MEM; }
-struct shutdown_callback_msg -{ - /* Synchronization */ - KEVENT Event; - - /* Input */ - PCONNECTION_ENDPOINT Connection; - int shut_rx; - int shut_tx; - - /* Output */ - err_t Error; -}; - static void LibTCPShutdownCallback(void *arg) { - struct shutdown_callback_msg *msg = arg; - PTCP_PCB pcb = msg->Connection->SocketContext; - - if (!msg->Connection->SocketContext) - { - msg->Error = ERR_CLSD; + struct lwip_callback_msg *msg = arg; + PTCP_PCB pcb = msg->Input.Shutdown.Connection->SocketContext; + + if (!msg->Input.Shutdown.Connection->SocketContext) + { + msg->Output.Shutdown.Error = ERR_CLSD; goto done; }
if (pcb->state == CLOSE_WAIT) { /* This case actually results in a socket closure later (lwIP bug?) */ - msg->Connection->SocketContext = NULL; - } - - msg->Error = tcp_shutdown(pcb, msg->shut_rx, msg->shut_tx); - if (msg->Error) - { - msg->Connection->SocketContext = pcb; + msg->Input.Shutdown.Connection->SocketContext = NULL; + } + + msg->Output.Shutdown.Error = tcp_shutdown(pcb, msg->Input.Shutdown.shut_rx, msg->Input.Shutdown.shut_tx); + if (msg->Output.Shutdown.Error) + { + msg->Input.Shutdown.Connection->SocketContext = pcb; }
done: @@ -626,26 +546,26 @@ err_t LibTCPShutdown(PCONNECTION_ENDPOINT Connection, const int shut_rx, const int shut_tx) { - struct shutdown_callback_msg *msg; + struct lwip_callback_msg *msg; err_t ret;
- msg = ExAllocatePool(NonPagedPool, sizeof(struct shutdown_callback_msg)); + msg = ExAllocateFromNPagedLookasideList(&MessageLookasideList); if (msg) { KeInitializeEvent(&msg->Event, NotificationEvent, FALSE);
- msg->Connection = Connection; - msg->shut_rx = shut_rx; - msg->shut_tx = shut_tx; + msg->Input.Shutdown.Connection = Connection; + msg->Input.Shutdown.shut_rx = shut_rx; + msg->Input.Shutdown.shut_tx = shut_tx;
tcpip_callback_with_block(LibTCPShutdownCallback, msg, 1);
if (WaitForEventSafely(&msg->Event)) - ret = msg->Error; + ret = msg->Output.Shutdown.Error; else ret = ERR_CLSD;
- ExFreePool(msg); + ExFreeToNPagedLookasideList(&MessageLookasideList, msg);
return ret; } @@ -653,45 +573,32 @@ return ERR_MEM; }
-struct close_callback_msg -{ - /* Synchronization */ - KEVENT Event; - - /* Input */ - PCONNECTION_ENDPOINT Connection; - int Callback; - - /* Output */ - err_t Error; -}; - static void LibTCPCloseCallback(void *arg) { - struct close_callback_msg *msg = arg; - PTCP_PCB pcb = msg->Connection->SocketContext; + struct lwip_callback_msg *msg = arg; + PTCP_PCB pcb = msg->Input.Close.Connection->SocketContext; int state;
- if (!msg->Connection->SocketContext) - { - msg->Error = ERR_OK; + if (!msg->Input.Close.Connection->SocketContext) + { + msg->Output.Close.Error = ERR_OK; goto done; }
- LibTCPEmptyQueue(msg->Connection); + LibTCPEmptyQueue(msg->Input.Close.Connection);
/* Clear the PCB pointer */ - msg->Connection->SocketContext = NULL; + msg->Input.Close.Connection->SocketContext = NULL;
/* Save the old PCB state */ state = pcb->state;
- msg->Error = tcp_close(pcb); - if (!msg->Error) - { - if (msg->Callback) + msg->Output.Close.Error = tcp_close(pcb); + if (!msg->Output.Close.Error) + { + if (msg->Input.Close.Callback) { /* Call the FIN handler in the cases where it will not be called by lwIP */ switch (state) @@ -699,7 +606,7 @@ case CLOSED: case LISTEN: case SYN_SENT: - TCPFinEventHandler(msg->Connection, ERR_OK); + TCPFinEventHandler(msg->Input.Close.Connection, ERR_OK); break;
default: @@ -710,7 +617,7 @@ else { /* Restore the PCB pointer */ - msg->Connection->SocketContext = pcb; + msg->Input.Close.Connection->SocketContext = pcb; }
done: @@ -721,15 +628,15 @@ LibTCPClose(PCONNECTION_ENDPOINT Connection, const int safe, const int callback) { err_t ret; - struct close_callback_msg *msg; - - msg = ExAllocatePool(NonPagedPool, sizeof(struct close_callback_msg)); + struct lwip_callback_msg *msg; + + msg = ExAllocateFromNPagedLookasideList(&MessageLookasideList); if (msg) { KeInitializeEvent(&msg->Event, NotificationEvent, FALSE);
- msg->Connection = Connection; - msg->Callback = callback; + msg->Input.Close.Connection = Connection; + msg->Input.Close.Callback = callback;
if (safe) LibTCPCloseCallback(msg); @@ -737,11 +644,11 @@ tcpip_callback_with_block(LibTCPCloseCallback, msg, 1);
if (WaitForEventSafely(&msg->Event)) - ret = msg->Error; + ret = msg->Output.Close.Error; else ret = ERR_CLSD;
- ExFreePool(msg); + ExFreeToNPagedLookasideList(&MessageLookasideList, msg);
return ret; }
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c [iso-8859-1] Fri Aug 5 20:55:57 2011 @@ -10,6 +10,8 @@ static KSPIN_LOCK ThreadListLock;
KEVENT TerminationEvent; +NPAGED_LOOKASIDE_LIST MessageLookasideList; +NPAGED_LOOKASIDE_LIST QueueEntryLookasideList;
static LARGE_INTEGER StartTime;
@@ -311,6 +313,22 @@ KeQuerySystemTime(&StartTime);
KeInitializeEvent(&TerminationEvent, NotificationEvent, FALSE); + + ExInitializeNPagedLookasideList(&MessageLookasideList, + NULL, + NULL, + 0, + sizeof(struct lwip_callback_msg), + LWIP_TAG, + 0); + + ExInitializeNPagedLookasideList(&QueueEntryLookasideList, + NULL, + NULL, + 0, + sizeof(QUEUE_ENTRY), + LWIP_TAG, + 0); }
void @@ -338,4 +356,7 @@ ZwClose(Container->Handle); } } -} + + ExDeleteNPagedLookasideList(&MessageLookasideList); + ExDeleteNPagedLookasideList(&QueueEntryLookasideList); +}