Changes to correct TCP write buffereing build errors

This commit is contained in:
Gregory Nutt 2014-01-14 09:43:59 -06:00
parent f034d84ea1
commit a4e3fabee6
16 changed files with 134 additions and 110 deletions

View File

@ -90,19 +90,23 @@ struct socket
int s_crefs; /* Reference count on the socket */
uint8_t s_type; /* Protocol type: Only SOCK_STREAM or SOCK_DGRAM */
uint8_t s_flags; /* See _SF_* definitions */
/* Socket options */
#ifdef CONFIG_NET_SOCKOPTS
sockopt_t s_options; /* Selected socket options */
#ifndef CONFIG_DISABLE_CLOCK
socktimeo_t s_rcvtimeo; /* Receive timeout value (in deciseconds) */
socktimeo_t s_sndtimeo; /* Send timeout value (in deciseconds) */
#endif
#ifdef CONFIG_NET_SOLINGER
socktimeo_t s_linger; /* Linger timeout value (in deciseconds) */
#endif
#endif
#endif
FAR void *s_conn; /* Connection: struct uip_conn or uip_udp_conn */
#ifdef CONFIG_NET_TCP_WRBUFFER
#ifdef CONFIG_NET_NTCP_WRITE_BUFFERS
/* Callback instance for TCP send */
FAR struct uip_callback_s *s_sndcb;

View File

@ -162,7 +162,7 @@ struct uip_conn
uint16_t mss; /* Current maximum segment size for the
* connection */
uint16_t winsize; /* Current window size of the connection */
#ifdef CONFIG_NET_TCP_WRBUFFER
#ifdef CONFIG_NET_NTCP_WRITE_BUFFERS
uint32_t unacked; /* Number bytes sent but not yet ACKed */
#else
uint16_t unacked; /* Number bytes sent but not yet ACKed */
@ -431,16 +431,17 @@ int uip_unlisten(struct uip_conn *conn);
/* Access to TCP read-ahead buffers */
#ifdef CONFIG_NET_TCP_READAHEAD
struct uip_readahead_s *uip_tcpreadaheadalloc(void);
void uip_tcpreadaheadrelease(struct uip_readahead_s *buf);
FAR struct uip_readahead_s *uip_tcpreadahead_alloc(void);
void uip_tcpreadahead_release(FAR struct uip_readahead_s *readahead);
#endif /* CONFIG_NET_TCP_READAHEAD */
/* Access to TCP write buffers */
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
struct timespec;
FAR struct uip_wrbuffer_s *uip_tcpwrbuffer_alloc(FAR const struct timespec *abstime);
void uip_tcpwrbuffer_release(FAR struct uip_wrbuffer_s *buf);
#endif /* CONFIG_NET_NTCP_READAHEAD_BUFFERS */
void uip_tcpwrbuffer_release(FAR struct uip_wrbuffer_s *wrbuffer);
#endif /* CONFIG_NET_TCP_WRITE_BUFFERS */
/* Backlog support */

View File

@ -72,13 +72,16 @@ config NET_SOCKOPTS
---help---
Enable or disable support for socket options
if NET_SOCKOPTS
config NET_SOLINGER
bool "SO_LINGER socket option"
default n
depends on NET_SOCKOPTS && NET_TCP_WRITE_BUFFERS && !DISABLE_CLOCK
---help---
Enable or disable support for the SO_LINGER socket option.
endif # NET_SOCKOPTS
config NET_BUFSIZE
int "Network packet size"
default 562 if !NET_SLIP
@ -156,6 +159,7 @@ endif # NET_TCP_READAHEAD
config NET_TCP_WRITE_BUFFERS
bool "Enabled TCP/IP write buffering"
default n
depends on EXPERIMENTAL
---help---
Write buffers allows buffering of ongoing TCP/IP packets, providing
for higher performance, streamed output.

View File

@ -49,7 +49,7 @@ SOCK_CSRCS += net_clone.c net_vfcntl.c
ifeq ($(CONFIG_NET_TCP),y)
SOCK_CSRCS += send.c listen.c accept.c net_monitor.c
ifeq ($(CONFIG_NET_TCP_WRBUFFER),y)
ifeq ($(CONFIG_NET_TCP_WRITE_BUFFERS),y)
SOCK_CSRCS += net_send_buffered.c
else
SOCK_CSRCS += net_send_unbuffered.c

View File

@ -175,6 +175,8 @@ static uint16_t netclose_interrupt(FAR struct uip_driver_s *dev,
if (pstate)
{
/* Wake up the waiting thread with a successful result */
pstate->cl_result = OK;
goto end_wait;
}
@ -201,7 +203,7 @@ static uint16_t netclose_interrupt(FAR struct uip_driver_s *dev,
else if (pstate && close_timeout(pstate))
{
/* Yes.. report the timeout */
/* Yes.. Wake up the waiting thread and report the timeout */
nlldbg("CLOSE timeout\n");
pstate->cl_result = -ETIMEDOUT;
@ -213,7 +215,7 @@ static uint16_t netclose_interrupt(FAR struct uip_driver_s *dev,
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
/* Check if all outstanding bytes have been ACKed */
else if (pstate && conn->unacked != 0)
else if (conn->unacked != 0)
{
/* No... we are still waiting for ACKs. Drop any received data, but
* do not yet report UIP_CLOSE in the response.

View File

@ -84,21 +84,22 @@
* Function: send_insert_seqment
*
* Description:
* Inserted a new segment in a write buffer, keep the segment queue in
* ascending order of seqno
* Insert a new segment in a write buffer queue, keep the segment queue in
* ascending order of sequence number.
*
* Parameters:
* pstate send state structure
* segment The segment to be inserted
* q The write buffer queue in which to insert the segment
*
* Returned Value:
* TRUE:timeout FALSE:no timeout
* None
*
* Assumptions:
* Running at the interrupt level
*
****************************************************************************/
static void send_insert_seqment(FAR struct uip_write_s *segment,
static void send_insert_seqment(FAR struct uip_wrbuffer_s *segment,
FAR sq_queue_t *q)
{
sq_entry_t *entry = (sq_entry_t*)segment;
@ -107,7 +108,7 @@ static void send_insert_seqment(FAR struct uip_write_s *segment,
sq_entry_t *itr;
for (itr = sq_peek(q); itr; itr = sq_next(itr))
{
FAR struct uip_write_s *segment0 = (FAR struct uip_write_s*)itr;
FAR struct uip_wrbuffer_s *segment0 = (FAR struct uip_wrbuffer_s*)itr;
if (segment0->wb_seqno < segment->wb_seqno)
{
insert = itr;
@ -152,7 +153,7 @@ static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
FAR void *pvpriv, uint16_t flags)
{
FAR struct uip_conn *conn = (FAR struct uip_conn*)pvconn;
FAR struct send_s *pstate = (FAR struct send_s *)pvpriv;
FAR struct socket *psock = (FAR struct socket *)pvpriv;
nllvdbg("flags: %04x\n", flags);
@ -163,14 +164,14 @@ static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
if ((flags & UIP_ACKDATA) != 0)
{
FAR sq_entry_t *entry, *next;
FAR struct uip_write_s *segment;
FAR struct uip_wrbuffer_s *segment;
uint32_t ackno;
ackno = uip_tcpgetsequence(TCPBUF->ackno);
for (entry = sq_peek(&conn->unacked_q); entry; entry = next)
{
next = sq_next(entry);
segment = (FAR struct uip_write_s*)entry;
segment = (FAR struct uip_wrbuffer_s*)entry;
if (segment->wb_seqno < ackno)
{
@ -183,7 +184,7 @@ static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
/* Return the write buffer to the pool of free buffers */
uip_tcpwritebuffrelease(segment);
uip_tcpwrbuffer_release(segment);
}
}
}
@ -212,7 +213,7 @@ static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
while ((entry=sq_remlast(&conn->unacked_q)))
{
struct uip_write_s *segment = (struct uip_write_s*)entry;
struct uip_wrbuffer_s *segment = (struct uip_wrbuffer_s*)entry;
if (segment->wb_nrtx >= UIP_MAXRTX)
{
@ -220,7 +221,7 @@ static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
/* Return the write buffer */
uip_tcpwritebuffrelease(segment);
uip_tcpwrbuffer_release(segment);
/* NOTE expired is different from un-ACKed, it is designed to
* represent the number of segments that have been sent,
@ -277,13 +278,13 @@ static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
if (uip_arp_find(conn->ripaddr) != NULL)
#endif
{
FAR struct uip_write_s *segment;
FAR struct uip_wrbuffer_s *segment;
FAR void *sndbuf;
size_tsndlen;
size_t sndlen;
/* Get the amount of data that we can send in the next packet */
segment = (FAR struct uip_write_s*)sq_peek(&conn->write_q);
segment = (FAR struct uip_wrbuffer_s *)sq_remfirst(&conn->write_q);
if (segment)
{
sndbuf = segment->wb_buffer;
@ -291,68 +292,63 @@ static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
DEBUGASSERT(sndlen <= uip_mss(conn));
/* Check if we have "space" in the window */
/* REVISIT: There should be a check here to assure that we do
* not excced the window (conn->winsize).
*/
if ((pstate->snd_sent - pstate->snd_acked + sndlen) < conn->winsize)
/* Set the sequence number for this segment. NOTE: uIP
* updates sndseq on receipt of ACK *before* this function
* is called. In that case sndseq will point to the next
* unacknowledged byte (which might have already been
* sent). We will overwrite the value of sndseq here
* before the packet is sent.
*/
if (segment->wb_nrtx == 0 && segment->wb_seqno == (unsigned)-1)
{
/* We are committed.. remove the segment from the queue. */
(void)sq_remfirst(&conn->write_q);
/* Set the sequence number for this segment. NOTE: uIP
* updates sndseq on receipt of ACK *before* this function
* is called. In that case sndseq will point to the next
* unacknowledged byte (which might have already been
* sent). We will overwrite the value of sndseq here
* before the packet is sent.
*/
if (segment->wb_nrtx == 0 && segment->wb_seqno == (unsigned)-1)
{
segment->wb_seqno = conn->isn + conn->sent;
}
uip_tcpsetsequence(conn->sndseq, segment->wb_seqno);
/* Then set-up to send that amount of data. (this won't
* actually happen until the polling cycle completes).
*/
uip_send(dev, sndbuf, sndlen);
/* Remember how much data we send out now so that we know
* when everything has been acknowledged. Just increment
* the amount of data sent. This will be needed in
* sequence* number calculations and we know that this is
* not a re-transmission. Re-transmissions do not go through
* this path.
*/
if (segment->wb_nrtx == 0)
{
conn->unacked += sndlen;
conn->sent += sndlen;
}
/* Increment the retransmission counter before expiration.
* NOTE we will not calculate the retransmission timer
* (RTT) to save cpu cycles, each send_insert_seqment
* segment will be retransmitted UIP_MAXRTX times in halt-
* second interval before expiration.
*/
segment->wb_nrtx ++;
/* The segment is waiting for ACK again */
send_insert_seqment(segment, &conn->unacked_q);
/* Only one data can be sent by low level driver at once,
* tell the caller stop polling the other connection.
*/
flags &= ~UIP_POLL;
segment->wb_seqno = conn->isn + conn->sent;
}
uip_tcpsetsequence(conn->sndseq, segment->wb_seqno);
/* Then set-up to send that amount of data. (this won't
* actually happen until the polling cycle completes).
*/
uip_send(dev, sndbuf, sndlen);
/* Remember how much data we send out now so that we know
* when everything has been acknowledged. Just increment
* the amount of data sent. This will be needed in
* sequence* number calculations and we know that this is
* not a re-transmission. Re-transmissions do not go through
* this path.
*/
if (segment->wb_nrtx == 0)
{
conn->unacked += sndlen;
conn->sent += sndlen;
}
/* Increment the retransmission counter before expiration.
* NOTE we will not calculate the retransmission timer
* (RTT) to save cpu cycles, each send_insert_seqment
* segment will be retransmitted UIP_MAXRTX times in halt-
* second interval before expiration.
*/
segment->wb_nrtx ++;
/* The segment is waiting for ACK again */
send_insert_seqment(segment, &conn->unacked_q);
/* Only one data can be sent by low level driver at once,
* tell the caller stop polling the other connection.
*/
flags &= ~UIP_POLL;
}
}
}
@ -485,7 +481,7 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
while (completed < len)
{
struct uip_write_s *segment = uip_tcpwritebuffalloc(NULL);
struct uip_wrbuffer_s *segment = uip_tcpwrbuffer_alloc(NULL);
if (segment)
{
size_t cnt;
@ -512,9 +508,9 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
sq_addlast(&segment->wb_node, &conn->write_q);
/* Notify the device driver of the availaibilty of TX data */
/* Notify the device driver of the availability of TX data */
netdev_txnotify(&conn->ripaddr);
netdev_txnotify(conn->ripaddr);
}
}
}

View File

@ -324,7 +324,7 @@ static inline void recvfrom_readahead(struct recvfrom_s *pstate)
}
else
{
uip_tcpreadaheadrelease(readahead);
uip_tcpreadahead_release(readahead);
}
}
}

View File

@ -239,12 +239,16 @@ int psock_setsockopt(FAR struct socket *psock, int level, int option,
if (setting->l_onoff)
{
_SO_SETOPT(psock->s_options, option);
#ifndef CONFIG_DISABLE_CLOCK
psock->s_linger = 10 * setting->l_linger;
#endif
}
else
{
_SO_CLROPT(psock->s_options, option);
#ifndef CONFIG_DISABLE_CLOCK
psock->s_linger = 0;
#endif
}
uip_unlock(flags);

View File

@ -128,7 +128,7 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
psock->s_type = type;
psock->s_conn = NULL;
#ifdef CONFIG_NET_TCP_WRBUFFER
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
psock->s_sndcb = NULL;
#endif
@ -158,7 +158,7 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
DEBUGASSERT(conn->crefs == 0);
psock->s_conn = conn;
conn->crefs = 1;
#ifdef CONFIG_NET_TCP_WRBUFFER
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
psock->s_sndcb = NULL;
#endif
}

View File

@ -69,18 +69,18 @@ UIP_CSRCS += uip_tcpconn.c uip_tcpseqno.c uip_tcppoll.c uip_tcptimer.c
UIP_CSRCS += uip_tcpsend.c uip_tcpinput.c uip_tcpappsend.c uip_listen.c
UIP_CSRCS += uip_tcpcallback.c uip_tcpbacklog.c
endif
# Buffering
# TCP Buffering
ifeq ($(CONFIG_NET_TCP_READAHEAD),y)
UIP_CSRCS += uip_tcpreadahead.c
endif
ifeq ($(CONFIG_NET_TCP_WRBUFFER),y)
ifeq ($(CONFIG_NET_TCP_WRITE_BUFFERS),y)
UIP_CSRCS += uip_tcpwrbuffer.c
endif
endif
# UDP source files
ifeq ($(CONFIG_NET_UDP),y)

View File

@ -135,7 +135,7 @@ void uip_initialize(void)
/* Initialize the TCP/IP read-ahead buffering */
#ifdef CONFIG_NET_TCP_READAHEAD
uip_tcpreadaheadinit();
uip_tcpreadahead_init();
#endif
#endif /* CONFIG_NET_TCP */

View File

@ -164,11 +164,24 @@ uint16_t uip_datahandler(FAR struct uip_conn *conn,
/* Defined in uip_tcpreadahead.c ********************************************/
#ifdef CONFIG_NET_TCP_READAHEAD
void uip_tcpreadaheadinit(void);
struct uip_readahead_s *uip_tcpreadaheadalloc(void);
void uip_tcpreadaheadrelease(struct uip_readahead_s *buf);
void uip_tcpreadahead_init(void);
struct uip_readahead_s;
FAR struct uip_readahead_s *uip_tcpreadahead_alloc(void);
void uip_tcpreadahead_release(FAR struct uip_readahead_s *readahead);
#endif /* CONFIG_NET_TCP_READAHEAD */
/* Defined in uip_tcpwrbuffer.c *********************************************/
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
void uip_tcpwrbuffer_init(void);
struct uip_wrbuffer_s;
struct timespec;
FAR struct uip_wrbuffer_s *uip_tcpwrbuffer_alloc(FAR const struct timespec *abstime);
void uip_tcpwrbuffer_release(FAR struct uip_wrbuffer_s *wrbuffer);
#endif /* CONFIG_NET_TCP_WRITE_BUFFERS */
#endif /* CONFIG_NET_TCP */
#ifdef CONFIG_NET_UDP

View File

@ -297,7 +297,7 @@ uint16_t uip_datahandler(FAR struct uip_conn *conn, FAR uint8_t *buffer,
readahead1 = (FAR struct uip_readahead_s*)conn->readahead.tail;
if ((readahead1 &&
(CONFIG_NET_TCP_READAHEAD_BUFSIZE - readahead1->rh_nbytes) > buflen) ||
(readahead2 = uip_tcpreadaheadalloc()) != NULL)
(readahead2 = uip_tcpreadahead_alloc()) != NULL)
{
/* We have buffer space. Now try to append add as much data as possible
* to the last readahead buffer attached to this connection.

View File

@ -347,7 +347,7 @@ void uip_tcpfree(struct uip_conn *conn)
while ((readahead = (struct uip_readahead_s *)sq_remfirst(&conn->readahead)) != NULL)
{
uip_tcpreadaheadrelease(readahead);
uip_tcpreadahead_release(readahead);
}
#endif

View File

@ -81,7 +81,7 @@ static struct readahead_s g_readahead;
****************************************************************************/
/****************************************************************************
* Function: uip_tcpreadaheadinit
* Function: uip_tcpreadahead_init
*
* Description:
* Initialize the list of free read-ahead buffers
@ -91,7 +91,7 @@ static struct readahead_s g_readahead;
*
****************************************************************************/
void uip_tcpreadaheadinit(void)
void uip_tcpreadahead_init(void)
{
int i;
@ -103,7 +103,7 @@ void uip_tcpreadaheadinit(void)
}
/****************************************************************************
* Function: uip_tcpreadaheadalloc
* Function: uip_tcpreadahead_alloc
*
* Description:
* Allocate a TCP read-ahead buffer by taking a pre-allocated buffer from
@ -117,13 +117,13 @@ void uip_tcpreadaheadinit(void)
*
****************************************************************************/
struct uip_readahead_s *uip_tcpreadaheadalloc(void)
FAR struct uip_readahead_s *uip_tcpreadahead_alloc(void)
{
return (struct uip_readahead_s*)sq_remfirst(&g_readahead.freebuffers);
return (FAR struct uip_readahead_s*)sq_remfirst(&g_readahead.freebuffers);
}
/****************************************************************************
* Function: uip_tcpreadaheadrelease
* Function: uip_tcpreadahead_release
*
* Description:
* Release a TCP read-ahead buffer by returning the buffer to the free list.
@ -135,9 +135,9 @@ struct uip_readahead_s *uip_tcpreadaheadalloc(void)
*
****************************************************************************/
void uip_tcpreadaheadrelease(struct uip_readahead_s *buf)
void uip_tcpreadahead_release(FAR struct uip_readahead_s *readahead)
{
sq_addfirst(&buf->rh_node, &g_readahead.freebuffers);
sq_addfirst(&readahead->rh_node, &g_readahead.freebuffers);
}
#endif /* CONFIG_NET && CONFIG_NET_TCP && CONFIG_NET_TCP_READAHEAD */

View File

@ -162,4 +162,4 @@ void uip_tcpwrbuffer_release(FAR struct uip_wrbuffer_s *wrbuffer)
sem_post(&g_wrbuffer.sem);
}
#endif /* CONFIG_NET && CONFIG_NET_TCP && CONFIG_NET_NTCP_WRITE_BUFFERS*/
#endif /* CONFIG_NET && CONFIG_NET_TCP && CONFIG_NET_NTCP_WRITE_BUFFERS */