net/net_sendfile: High performance sendfile is now functional. From Max Holtzberg
This commit is contained in:
parent
4cecf0b618
commit
3ea00af9aa
|
@ -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).
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue