Add LWIP_TCPIP_CORE_LOCKING option (0 as default value) to experiment "locking" as feature to communicate with tcpip_thread for sequential API (netconn & socket layers). Add a alternative code for lwip_sendto to how the code can be optimized with such feature....

This commit is contained in:
fbernon 2007-06-08 19:27:59 +00:00
parent 0b9c9f9ede
commit 090aaefb39
8 changed files with 95 additions and 25 deletions

View File

@ -220,7 +220,7 @@ netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto,
msg.function = do_newconn; msg.function = do_newconn;
msg.msg.msg.n.proto = proto; msg.msg.msg.n.proto = proto;
msg.msg.conn = conn; msg.msg.conn = conn;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
if ( conn->err != ERR_OK ) { if ( conn->err != ERR_OK ) {
sys_sem_free(conn->sem); sys_sem_free(conn->sem);
@ -258,7 +258,7 @@ netconn_delete(struct netconn *conn)
msg.function = do_delconn; msg.function = do_delconn;
msg.msg.conn = conn; msg.msg.conn = conn;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
/* Drain the recvmbox. */ /* Drain the recvmbox. */
if (conn->recvmbox != SYS_MBOX_NULL) { if (conn->recvmbox != SYS_MBOX_NULL) {
@ -362,7 +362,7 @@ netconn_bind(struct netconn *conn, struct ip_addr *addr, u16_t port)
msg.msg.conn = conn; msg.msg.conn = conn;
msg.msg.msg.bc.ipaddr = addr; msg.msg.msg.bc.ipaddr = addr;
msg.msg.msg.bc.port = port; msg.msg.msg.bc.port = port;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
return conn->err; return conn->err;
} }
@ -384,6 +384,7 @@ netconn_connect(struct netconn *conn, struct ip_addr *addr, u16_t port)
msg.msg.conn = conn; msg.msg.conn = conn;
msg.msg.msg.bc.ipaddr = addr; msg.msg.msg.bc.ipaddr = addr;
msg.msg.msg.bc.port = port; msg.msg.msg.bc.port = port;
/* This is the only function which need to not block tcpip_thread */
tcpip_apimsg(&msg); tcpip_apimsg(&msg);
return conn->err; return conn->err;
} }
@ -397,7 +398,7 @@ netconn_disconnect(struct netconn *conn)
msg.function = do_disconnect; msg.function = do_disconnect;
msg.msg.conn = conn; msg.msg.conn = conn;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
return conn->err; return conn->err;
} }
@ -411,7 +412,7 @@ netconn_listen(struct netconn *conn)
msg.function = do_listen; msg.function = do_listen;
msg.msg.conn = conn; msg.msg.conn = conn;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
return conn->err; return conn->err;
} }
@ -512,7 +513,7 @@ netconn_recv(struct netconn *conn)
} else { } else {
msg.msg.msg.r.len = 1; msg.msg.msg.r.len = 1;
} }
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
} else { } else {
#if (LWIP_UDP || LWIP_RAW) #if (LWIP_UDP || LWIP_RAW)
@ -562,7 +563,7 @@ netconn_send(struct netconn *conn, struct netbuf *buf)
msg.function = do_send; msg.function = do_send;
msg.msg.conn = conn; msg.msg.conn = conn;
msg.msg.msg.b = buf; msg.msg.msg.b = buf;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
return conn->err; return conn->err;
} }
@ -605,7 +606,7 @@ netconn_write(struct netconn *conn, const void *dataptr, u16_t size, u8_t copy)
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy)); LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));
msg.msg.msg.w.len = len; msg.msg.msg.w.len = len;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
if (conn->err == ERR_OK) { if (conn->err == ERR_OK) {
dataptr = (void *)((u8_t *)dataptr + len); dataptr = (void *)((u8_t *)dataptr + len);
size -= len; size -= len;
@ -633,7 +634,7 @@ netconn_close(struct netconn *conn)
again: again:
msg.function = do_close; msg.function = do_close;
msg.msg.conn = conn; msg.msg.conn = conn;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
if (conn->err == ERR_MEM && conn->sem != SYS_SEM_NULL) { if (conn->err == ERR_MEM && conn->sem != SYS_SEM_NULL) {
sys_sem_wait(conn->sem); sys_sem_wait(conn->sem);
goto again; goto again;
@ -662,7 +663,7 @@ netconn_join_leave_group (struct netconn *conn,
msg.msg.msg.jl.multiaddr = multiaddr; msg.msg.msg.jl.multiaddr = multiaddr;
msg.msg.msg.jl.interface = interface; msg.msg.msg.jl.interface = interface;
msg.msg.msg.jl.join_or_leave = join_or_leave; msg.msg.msg.jl.join_or_leave = join_or_leave;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
return conn->err; return conn->err;
} }
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */

View File

@ -340,7 +340,7 @@ do_newconn(struct api_msg_msg *msg)
/* Is this an error condition? Should it be deleted? */ /* Is this an error condition? Should it be deleted? */
/* We currently just are happy and return. */ /* We currently just are happy and return. */
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
void void
@ -388,7 +388,7 @@ do_delconn(struct api_msg_msg *msg)
} }
if (msg->conn->mbox != SYS_MBOX_NULL) { if (msg->conn->mbox != SYS_MBOX_NULL) {
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
} }
@ -422,7 +422,7 @@ do_bind(struct api_msg_msg *msg)
} }
} }
} }
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
#if LWIP_TCP #if LWIP_TCP
@ -493,7 +493,7 @@ do_disconnect(struct api_msg_msg *msg)
udp_disconnect(msg->conn->pcb.udp); udp_disconnect(msg->conn->pcb.udp);
} }
#endif /* LWIP_UDP */ #endif /* LWIP_UDP */
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
void void
@ -521,7 +521,7 @@ do_listen(struct api_msg_msg *msg)
} }
} }
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
void void
@ -553,7 +553,7 @@ do_send(struct api_msg_msg *msg)
} }
} }
} }
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
void void
@ -568,7 +568,7 @@ do_recv(struct api_msg_msg *msg)
} }
} }
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
void void
@ -606,7 +606,7 @@ do_write(struct api_msg_msg *msg)
} }
} }
} }
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
void void
@ -623,7 +623,7 @@ do_close(struct api_msg_msg *msg)
} }
} }
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
#if LWIP_IGMP #if LWIP_IGMP
@ -647,7 +647,7 @@ do_join_leave_group(struct api_msg_msg *msg)
} }
} }
} }
sys_mbox_post(msg->conn->mbox, NULL); TCPIP_APIMSG_ACK(msg);
} }
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */

View File

@ -56,7 +56,7 @@ netifapi_netif_add(struct netif *netif,
msg.msg.add.state = state; msg.msg.add.state = state;
msg.msg.add.init = init; msg.msg.add.init = init;
msg.msg.add.input = input; msg.msg.add.input = input;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
return msg.err; return msg.err;
} }
@ -72,7 +72,7 @@ netifapi_netif_remove(struct netif *netif)
struct netifapi_msg msg; struct netifapi_msg msg;
msg.type = NETIFAPI_MSG_NETIF_REMOVE; msg.type = NETIFAPI_MSG_NETIF_REMOVE;
msg.netif = netif; msg.netif = netif;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
return msg.err; return msg.err;
} }
@ -88,7 +88,7 @@ netifapi_dhcp_start(struct netif *netif)
struct netifapi_msg msg; struct netifapi_msg msg;
msg.type = NETIFAPI_MSG_DHCP_START; msg.type = NETIFAPI_MSG_DHCP_START;
msg.netif = netif; msg.netif = netif;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
return msg.err; return msg.err;
} }
@ -104,7 +104,7 @@ netifapi_dhcp_stop(struct netif *netif)
struct netifapi_msg msg; struct netifapi_msg msg;
msg.type = NETIFAPI_MSG_DHCP_STOP; msg.type = NETIFAPI_MSG_DHCP_STOP;
msg.netif = netif; msg.netif = netif;
tcpip_apimsg(&msg); TCPIP_APIMSG(&msg);
return msg.err; return msg.err;
} }

View File

@ -539,6 +539,26 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags,
((tolen == sizeof(struct sockaddr_in)) && ((tolen == sizeof(struct sockaddr_in)) &&
((((struct sockaddr_in *)to)->sin_family) == AF_INET)))); ((((struct sockaddr_in *)to)->sin_family) == AF_INET))));
#if LWIP_TCPIP_CORE_LOCKING
{ struct pbuf* p;
p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
if (p == NULL) {
err = ERR_MEM;
} else {
p->payload = (void*)data;
p->len = p->tot_len = size;
remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
LOCK_TCPIP_CORE();
err = sock->conn->err = udp_sendto(sock->conn->pcb.udp, p, &remote_addr, ntohs(((struct sockaddr_in *)to)->sin_port));
UNLOCK_TCPIP_CORE();
pbuf_free(p);
}
}
#else
/* initialize a buffer */ /* initialize a buffer */
buf.p = buf.ptr = NULL; buf.p = buf.ptr = NULL;
if (to) { if (to) {
@ -568,7 +588,7 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags,
if (buf.p != NULL) { if (buf.p != NULL) {
pbuf_free(buf.p); pbuf_free(buf.p);
} }
#endif /* LWIP_TCPIP_CORE_LOCKING */
sock_set_errno(sock, err_to_errno(err)); sock_set_errno(sock, err_to_errno(err));
return (err==ERR_OK?size:-1); return (err==ERR_OK?size:-1);
} }

View File

@ -53,6 +53,11 @@ static void (* tcpip_init_done)(void *arg) = NULL;
static void *tcpip_init_done_arg = NULL; static void *tcpip_init_done_arg = NULL;
static sys_mbox_t mbox = SYS_MBOX_NULL; static sys_mbox_t mbox = SYS_MBOX_NULL;
#if LWIP_TCPIP_CORE_LOCKING
/** The global semaphore to lock the stack. */
sys_sem_t lock_tcpip_core = 0;
#endif /* LWIP_TCPIP_CORE_LOCKING */
#if LWIP_TCP #if LWIP_TCP
static int tcpip_tcp_timer_active = 0; static int tcpip_tcp_timer_active = 0;
@ -206,6 +211,7 @@ tcpip_thread(void *arg)
sys_timeout( IGMP_TMR_INTERVAL, igmp_timer, NULL); sys_timeout( IGMP_TMR_INTERVAL, igmp_timer, NULL);
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
LOCK_TCPIP_CORE();
while (1) { /* MAIN Loop */ while (1) { /* MAIN Loop */
sys_mbox_fetch(mbox, (void *)&msg); sys_mbox_fetch(mbox, (void *)&msg);
switch (msg->type) { switch (msg->type) {
@ -327,6 +333,18 @@ tcpip_apimsg(struct api_msg *apimsg)
return ERR_VAL; return ERR_VAL;
} }
#if LWIP_TCPIP_CORE_LOCKING
err_t
tcpip_apimsg_lock(struct api_msg *apimsg)
{
LOCK_TCPIP_CORE();
apimsg->function(&(apimsg->msg));
UNLOCK_TCPIP_CORE();
return ERR_OK;
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
#if LWIP_NETIF_API #if LWIP_NETIF_API
err_t tcpip_netifapi(struct netifapi_msg* netifapimsg) err_t tcpip_netifapi(struct netifapi_msg* netifapimsg)
{ {
@ -367,6 +385,10 @@ tcpip_init(void (* initfunc)(void *), void *arg)
tcpip_init_done = initfunc; tcpip_init_done = initfunc;
tcpip_init_done_arg = arg; tcpip_init_done_arg = arg;
mbox = sys_mbox_new(); mbox = sys_mbox_new();
#if LWIP_TCPIP_CORE_LOCKING
lock_tcpip_core = sys_sem_new(1);
#endif /* LWIP_TCPIP_CORE_LOCKING */
sys_thread_new(tcpip_thread, NULL, TCPIP_THREAD_PRIO); sys_thread_new(tcpip_thread, NULL, TCPIP_THREAD_PRIO);
} }

View File

@ -34,6 +34,7 @@
#include "lwip/opt.h" #include "lwip/opt.h"
#include "lwip/def.h" #include "lwip/def.h"
#include "lwip/memp.h" #include "lwip/memp.h"
#include "lwip/tcpip.h"
#if (NO_SYS == 0) #if (NO_SYS == 0)
@ -67,10 +68,14 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg)
timeouts = sys_arch_timeouts(); timeouts = sys_arch_timeouts();
if (!timeouts || !timeouts->next) { if (!timeouts || !timeouts->next) {
UNLOCK_TCPIP_CORE();
time = sys_arch_mbox_fetch(mbox, msg, 0); time = sys_arch_mbox_fetch(mbox, msg, 0);
LOCK_TCPIP_CORE();
} else { } else {
if (timeouts->next->time > 0) { if (timeouts->next->time > 0) {
UNLOCK_TCPIP_CORE();
time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time); time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
LOCK_TCPIP_CORE();
} else { } else {
time = SYS_ARCH_TIMEOUT; time = SYS_ARCH_TIMEOUT;
} }

View File

@ -474,6 +474,11 @@ a lot of data that needs to be copied, this should be set high. */
#define DEFAULT_THREAD_PRIO 1 #define DEFAULT_THREAD_PRIO 1
#endif #endif
/* ---------- Sequential layer options */
/* EXPERIMENTAL, Don't use it if you're not an active lwIP project member */
#ifndef LWIP_TCPIP_CORE_LOCKING
#define LWIP_TCPIP_CORE_LOCKING 0
#endif
/* ---------- Socket options ---------- */ /* ---------- Socket options ---------- */
/* Enable BSD-style sockets functions names */ /* Enable BSD-style sockets functions names */

View File

@ -40,8 +40,25 @@
extern "C" { extern "C" {
#endif #endif
#if LWIP_TCPIP_CORE_LOCKING
/** The global semaphore to lock the stack. */
extern sys_sem_t lock_tcpip_core;
#define LOCK_TCPIP_CORE() sys_sem_wait(lock_tcpip_core)
#define UNLOCK_TCPIP_CORE() sys_sem_signal(lock_tcpip_core)
#define TCPIP_APIMSG(m) tcpip_apimsg_lock(m)
#define TCPIP_APIMSG_ACK(m)
#else
#define LOCK_TCPIP_CORE()
#define UNLOCK_TCPIP_CORE()
#define TCPIP_APIMSG(m) tcpip_apimsg(m)
#define TCPIP_APIMSG_ACK(m) sys_mbox_post(m->conn->mbox, NULL)
#endif /* LWIP_TCPIP_CORE_LOCKING */
void tcpip_init(void (* tcpip_init_done)(void *), void *arg); void tcpip_init(void (* tcpip_init_done)(void *), void *arg);
err_t tcpip_apimsg(struct api_msg *apimsg); err_t tcpip_apimsg(struct api_msg *apimsg);
#if LWIP_TCPIP_CORE_LOCKING
err_t tcpip_apimsg_lock(struct api_msg *apimsg);
#endif /* LWIP_TCPIP_CORE_LOCKING */
#if ETHARP_TCPIP_INPUT #if ETHARP_TCPIP_INPUT
err_t tcpip_input(struct pbuf *p, struct netif *inp); err_t tcpip_input(struct pbuf *p, struct netif *inp);
#endif /* ETHARP_TCPIP_INPUT */ #endif /* ETHARP_TCPIP_INPUT */