From 4c76fd500c59f0fb38027f6c602641b1b79ae505 Mon Sep 17 00:00:00 2001 From: Joel Cunningham Date: Fri, 17 Feb 2017 13:26:16 -0600 Subject: [PATCH] Move write_offset from struct netconn to struct api_msg This moves the write_offset variable from struct netconn to struct api_msg This optimizes the storage by only having the space claimed when it is needed (during a netconn_write_partly() call) and not throughout the lifetime of the netconn This also reduces code space/execution by not having to separately manage clearing/checking write_offset from the current_msg pointer Lastly, we also save execution by using msg.w.offset as the output rather than marshaling the result to msg.w.len. Previously, len was used as input length of dataptr and output for the write operation. netconn_write_partly() also has access to msg.w.offset, so we can use that --- src/api/api_lib.c | 3 ++- src/api/api_msg.c | 45 +++++++++++++-------------------- src/include/lwip/api.h | 3 --- src/include/lwip/priv/api_msg.h | 3 +++ 4 files changed, 22 insertions(+), 32 deletions(-) diff --git a/src/api/api_lib.c b/src/api/api_lib.c index 89de39d1..1a40e994 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -784,6 +784,7 @@ netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, API_MSG_VAR_REF(msg).msg.w.dataptr = dataptr; API_MSG_VAR_REF(msg).msg.w.apiflags = apiflags; API_MSG_VAR_REF(msg).msg.w.len = size; + API_MSG_VAR_REF(msg).msg.w.offset = 0; #if LWIP_SO_SNDTIMEO if (conn->send_timeout != 0) { /* get the time we started, which is later compared to @@ -801,7 +802,7 @@ netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, if ((err == ERR_OK) && (bytes_written != NULL)) { if (dontblock) { /* nonblocking write: maybe the data has been sent partly */ - *bytes_written = API_MSG_VAR_REF(msg).msg.w.len; + *bytes_written = API_MSG_VAR_REF(msg).msg.w.offset; } else { /* blocking call succeeded: all data has been sent if it */ *bytes_written = size; diff --git a/src/api/api_msg.c b/src/api/api_msg.c index dd99c1e0..fcdade1c 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -696,7 +696,6 @@ netconn_alloc(enum netconn_type t, netconn_callback callback) conn->callback = callback; #if LWIP_TCP conn->current_msg = NULL; - conn->write_offset = 0; #endif /* LWIP_TCP */ #if LWIP_SO_SNDTIMEO conn->send_timeout = 0; @@ -1028,7 +1027,6 @@ lwip_netconn_do_delconn(void *m) op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); msg->conn->current_msg->err = ERR_CLSD; msg->conn->current_msg = NULL; - msg->conn->write_offset = 0; msg->conn->state = NETCONN_NONE; NETCONN_SET_SAFE_ERR(msg->conn, ERR_CLSD); sys_sem_signal(op_completed_sem); @@ -1067,8 +1065,7 @@ lwip_netconn_do_delconn(void *m) #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && - msg->conn->write_offset == 0); + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); msg->conn->state = NETCONN_CLOSE; msg->msg.sd.shut = NETCONN_SHUT_RDWR; msg->conn->current_msg = msg; @@ -1502,8 +1499,8 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); - LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len", - conn->write_offset < conn->current_msg->msg.w.len); + LWIP_ASSERT("conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len", + conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len); apiflags = conn->current_msg->msg.w.apiflags; dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); @@ -1512,21 +1509,18 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) if ((conn->send_timeout != 0) && ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { write_finished = 1; - if (conn->write_offset == 0) { + if (conn->current_msg->msg.w.offset == 0) { /* nothing has been written */ err = ERR_WOULDBLOCK; - conn->current_msg->msg.w.len = 0; } else { /* partial write */ err = ERR_OK; - conn->current_msg->msg.w.len = conn->write_offset; - conn->write_offset = 0; } } else #endif /* LWIP_SO_SNDTIMEO */ { - dataptr = (const u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset; - diff = conn->current_msg->msg.w.len - conn->write_offset; + dataptr = (const u8_t*)conn->current_msg->msg.w.dataptr + conn->current_msg->msg.w.offset; + diff = conn->current_msg->msg.w.len - conn->current_msg->msg.w.offset; if (diff > 0xffffUL) { /* max_u16_t */ len = 0xffff; apiflags |= TCP_WRITE_FLAG_MORE; @@ -1546,7 +1540,8 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) apiflags |= TCP_WRITE_FLAG_MORE; } } - LWIP_ASSERT("lwip_netconn_do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len)); + LWIP_ASSERT("lwip_netconn_do_writemore: invalid length!", + ((conn->current_msg->msg.w.offset + len) <= conn->current_msg->msg.w.len)); err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); /* if OK or memory error, check available space */ if ((err == ERR_OK) || (err == ERR_MEM)) { @@ -1566,10 +1561,9 @@ err_mem: if (err == ERR_OK) { err_t out_err; - conn->write_offset += len; - if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) { - /* return sent length */ - conn->current_msg->msg.w.len = conn->write_offset; + conn->current_msg->msg.w.offset += len; + if ((conn->current_msg->msg.w.offset == conn->current_msg->msg.w.len) || dontblock) { + /* return sent length (caller reads length from msg.w.offset) */ /* everything was written */ write_finished = 1; } @@ -1580,7 +1574,7 @@ err_mem: to the application thread. */ err = out_err; write_finished = 1; - conn->current_msg->msg.w.len = 0; + conn->current_msg->msg.w.offset = 0; } } else if (err == ERR_MEM) { /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called. @@ -1596,18 +1590,18 @@ err_mem: to the application thread. */ err = out_err; write_finished = 1; - conn->current_msg->msg.w.len = 0; + conn->current_msg->msg.w.offset = 0; } else if (dontblock) { /* non-blocking write is done on ERR_MEM */ err = ERR_WOULDBLOCK; write_finished = 1; - conn->current_msg->msg.w.len = 0; + conn->current_msg->msg.w.offset = 0; } } else { /* On errors != ERR_MEM, we don't try writing any more but return the error to the application thread. */ write_finished = 1; - conn->current_msg->msg.w.len = 0; + conn->current_msg->msg.w.offset = 0; } } if (write_finished) { @@ -1616,7 +1610,6 @@ err_mem: sys_sem_t* op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); conn->current_msg->err = err; conn->current_msg = NULL; - conn->write_offset = 0; conn->state = NETCONN_NONE; NETCONN_SET_SAFE_ERR(conn, err); #if LWIP_TCPIP_CORE_LOCKING @@ -1657,11 +1650,9 @@ lwip_netconn_do_write(void *m) } else if (msg->conn->pcb.tcp != NULL) { msg->conn->state = NETCONN_WRITE; /* set all the variables used by lwip_netconn_do_writemore */ - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && - msg->conn->write_offset == 0); + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); msg->conn->current_msg = msg; - msg->conn->write_offset = 0; #if LWIP_TCPIP_CORE_LOCKING if (lwip_netconn_do_writemore(msg->conn, 0) != ERR_OK) { LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); @@ -1789,7 +1780,6 @@ lwip_netconn_do_close(void *m) write_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); msg->conn->current_msg->err = ERR_CLSD; msg->conn->current_msg = NULL; - msg->conn->write_offset = 0; msg->conn->state = NETCONN_NONE; state = NETCONN_NONE; NETCONN_SET_SAFE_ERR(msg->conn, ERR_CLSD); @@ -1810,8 +1800,7 @@ lwip_netconn_do_close(void *m) /* Drain and delete mboxes */ netconn_drain(msg->conn); } - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && - msg->conn->write_offset == 0); + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); msg->conn->state = NETCONN_CLOSE; msg->conn->current_msg = msg; #if LWIP_TCPIP_CORE_LOCKING diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index 798c29ae..23aa774e 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -258,9 +258,6 @@ struct netconn { /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ u8_t flags; #if LWIP_TCP - /** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores how much is already sent. */ - size_t write_offset; /** TCP: when data passed to netconn_write doesn't fit into the send buffer, this temporarily stores the message. Also used during connect and close. */ diff --git a/src/include/lwip/priv/api_msg.h b/src/include/lwip/priv/api_msg.h index f12b8b7d..65b6aec5 100644 --- a/src/include/lwip/priv/api_msg.h +++ b/src/include/lwip/priv/api_msg.h @@ -104,7 +104,10 @@ struct api_msg { /** used for lwip_netconn_do_write */ struct { const void *dataptr; + /** total length of dataptr */ size_t len; + /** offset into dataptr/output of bytes written */ + size_t offset; u8_t apiflags; #if LWIP_SO_SNDTIMEO u32_t time_started;