net/net_sendfile: High performance sendfile is now functional. From Max Holtzberg

This commit is contained in:
Gregory Nutt 2013-09-30 14:37:04 -06:00
parent 4cecf0b618
commit 3ea00af9aa
4 changed files with 43 additions and 20 deletions

View File

@ -5684,3 +5684,6 @@
* configs/freedom-kl25z/minnsh: A new configuration that is * configs/freedom-kl25z/minnsh: A new configuration that is
an experiement to see how small we can get the NuttX footprint. an experiement to see how small we can get the NuttX footprint.
From Carvalho de Assis. (2013-9-30). From Carvalho de Assis. (2013-9-30).
* net/net_sendfile: The high performance sendfile logic is
now functional. From Max Holtzberg (2013-9-30).

View File

@ -133,6 +133,7 @@ struct uip_conn
uint16_t unacked; /* Number bytes sent but not yet ACKed */ uint16_t unacked; /* Number bytes sent but not yet ACKed */
uint16_t mss; /* Current maximum segment size for the uint16_t mss; /* Current maximum segment size for the
* connection */ * connection */
uint16_t winsize; /* Current window size of the connection */
uint16_t initialmss; /* Initial maximum segment size for the uint16_t initialmss; /* Initial maximum segment size for the
* connection */ * connection */
uint8_t crefs; /* Reference counts on this instance */ uint8_t crefs; /* Reference counts on this instance */

View File

@ -148,6 +148,8 @@ static uint16_t ack_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
{ {
FAR struct sendfile_s *pstate = (FAR struct sendfile_s *)pvpriv; FAR struct sendfile_s *pstate = (FAR struct sendfile_s *)pvpriv;
nllvdbg("flags: %04x\n", flags);
if ((flags & UIP_ACKDATA) != 0) if ((flags & UIP_ACKDATA) != 0)
{ {
/* The current acknowledgement number number is the (relative) offset /* The current acknowledgement number number is the (relative) offset
@ -161,9 +163,29 @@ static uint16_t ack_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
pstate->snd_acked, pstate->snd_sent, pstate->snd_flen); pstate->snd_acked, pstate->snd_sent, pstate->snd_flen);
dev->d_sndlen = 0; dev->d_sndlen = 0;
/* Wake up the waiting thread */
sem_post(&pstate->snd_sem);
flags &= ~UIP_ACKDATA;
} }
return OK; /* Check for a loss of connection */
else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
{
/* Report not connected */
nlldbg("Lost connection\n");
net_lostconnection(pstate->snd_sock, flags);
pstate->snd_sent = -ENOTCONN;
sem_post(&pstate->snd_sem);
}
return flags;
} }
/**************************************************************************** /****************************************************************************
@ -240,10 +262,8 @@ static uint16_t sendfile_interrupt(FAR struct uip_driver_s *dev, FAR void *pvcon
} }
/* Check if we have "space" in the window */ /* Check if we have "space" in the window */
#warning REVISIT
#if 0 /* Where is wndsize defined? */ if ((pstate->snd_sent - pstate->snd_acked + sndlen) < conn->winsize)
if ((pstate->snd_sent - pstate->snd_acked + sndlen) < conn->wndsize)
#endif
{ {
uint32_t seqno; uint32_t seqno;
@ -314,14 +334,11 @@ static uint16_t sendfile_interrupt(FAR struct uip_driver_s *dev, FAR void *pvcon
#endif #endif
} }
} }
#warning REVISIT
#if 0 /* Where is wndsize defined? */
else else
{ {
nlldbg("window full, wait for ack\n"); nlldbg("Window full, wait for ack\n");
goto wait; goto wait;
} }
#endif
} }
/* All data has been send and we are just waiting for ACK or re-transmit /* All data has been send and we are just waiting for ACK or re-transmit
@ -432,8 +449,6 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
uip_lock_t save; uip_lock_t save;
int err; int err;
nlldbg("pid: %d\n", getpid());
/* Verify that the sockfd corresponds to valid, allocated socket */ /* Verify that the sockfd corresponds to valid, allocated socket */
if (!psock || psock->s_crefs <= 0) if (!psock || psock->s_crefs <= 0)
@ -490,33 +505,33 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
/* Get the initial sequence number that will be used */ /* Get the initial sequence number that will be used */
state.snd_isn = uip_tcpgetsequence(conn->sndseq); state.snd_isn = uip_tcpgetsequence(conn->sndseq);
/* There is no outstanding, unacknowledged data after this /* There is no outstanding, unacknowledged data after this
* initial sequence number. * initial sequence number.
*/ */
conn->unacked = 0; conn->unacked = 0;
/* Set the initial time for calculating timeouts */ /* Set the initial time for calculating timeouts */
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
state.snd_time = clock_systimer(); state.snd_time = clock_systimer();
#endif #endif
/* Set up the ACK callback in the connection */ /* Set up the ACK callback in the connection */
state.snd_ackcb->flags = UIP_ACKDATA; state.snd_ackcb->flags = UIP_ACKDATA|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT;
state.snd_ackcb->priv = (void*)&state; state.snd_ackcb->priv = (void*)&state;
state.snd_ackcb->event = ack_interrupt; state.snd_ackcb->event = ack_interrupt;
/* Perform the TCP send operation */ /* Perform the TCP send operation */
do do
{ {
state.snd_datacb->flags = UIP_REXMIT|UIP_POLL|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT; state.snd_datacb->flags = UIP_REXMIT|UIP_POLL;
state.snd_datacb->priv = (void*)&state; state.snd_datacb->priv = (void*)&state;
state.snd_datacb->event = sendfile_interrupt; state.snd_datacb->event = sendfile_interrupt;
/* Notify the device driver of the availaibilty of TX data */ /* Notify the device driver of the availaibilty of TX data */

View File

@ -298,6 +298,10 @@ reset:
found: found:
/* Update the connection's window size */
conn->winsize = BUF->wnd[0] << 8 | BUF->wnd[1];
flags = 0; flags = 0;
/* We do a very naive form of TCP reset processing; we just accept /* We do a very naive form of TCP reset processing; we just accept