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.msg.msg.n.proto = proto;
msg.msg.conn = conn;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
if ( conn->err != ERR_OK ) {
sys_sem_free(conn->sem);
@ -258,7 +258,7 @@ netconn_delete(struct netconn *conn)
msg.function = do_delconn;
msg.msg.conn = conn;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
/* Drain the recvmbox. */
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.msg.bc.ipaddr = addr;
msg.msg.msg.bc.port = port;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
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.msg.bc.ipaddr = addr;
msg.msg.msg.bc.port = port;
/* This is the only function which need to not block tcpip_thread */
tcpip_apimsg(&msg);
return conn->err;
}
@ -397,7 +398,7 @@ netconn_disconnect(struct netconn *conn)
msg.function = do_disconnect;
msg.msg.conn = conn;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
return conn->err;
}
@ -411,7 +412,7 @@ netconn_listen(struct netconn *conn)
msg.function = do_listen;
msg.msg.conn = conn;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
return conn->err;
}
@ -512,7 +513,7 @@ netconn_recv(struct netconn *conn)
} else {
msg.msg.msg.r.len = 1;
}
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
#endif /* LWIP_TCP */
} else {
#if (LWIP_UDP || LWIP_RAW)
@ -562,7 +563,7 @@ netconn_send(struct netconn *conn, struct netbuf *buf)
msg.function = do_send;
msg.msg.conn = conn;
msg.msg.msg.b = buf;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
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));
msg.msg.msg.w.len = len;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
if (conn->err == ERR_OK) {
dataptr = (void *)((u8_t *)dataptr + len);
size -= len;
@ -633,7 +634,7 @@ netconn_close(struct netconn *conn)
again:
msg.function = do_close;
msg.msg.conn = conn;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
if (conn->err == ERR_MEM && conn->sem != SYS_SEM_NULL) {
sys_sem_wait(conn->sem);
goto again;
@ -662,7 +663,7 @@ netconn_join_leave_group (struct netconn *conn,
msg.msg.msg.jl.multiaddr = multiaddr;
msg.msg.msg.jl.interface = interface;
msg.msg.msg.jl.join_or_leave = join_or_leave;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
return conn->err;
}
#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? */
/* We currently just are happy and return. */
sys_mbox_post(msg->conn->mbox, NULL);
TCPIP_APIMSG_ACK(msg);
}
void
@ -388,7 +388,7 @@ do_delconn(struct api_msg_msg *msg)
}
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
@ -493,7 +493,7 @@ do_disconnect(struct api_msg_msg *msg)
udp_disconnect(msg->conn->pcb.udp);
}
#endif /* LWIP_UDP */
sys_mbox_post(msg->conn->mbox, NULL);
TCPIP_APIMSG_ACK(msg);
}
void
@ -521,7 +521,7 @@ do_listen(struct api_msg_msg *msg)
}
}
#endif /* LWIP_TCP */
sys_mbox_post(msg->conn->mbox, NULL);
TCPIP_APIMSG_ACK(msg);
}
void
@ -553,7 +553,7 @@ do_send(struct api_msg_msg *msg)
}
}
}
sys_mbox_post(msg->conn->mbox, NULL);
TCPIP_APIMSG_ACK(msg);
}
void
@ -568,7 +568,7 @@ do_recv(struct api_msg_msg *msg)
}
}
#endif /* LWIP_TCP */
sys_mbox_post(msg->conn->mbox, NULL);
TCPIP_APIMSG_ACK(msg);
}
void
@ -606,7 +606,7 @@ do_write(struct api_msg_msg *msg)
}
}
}
sys_mbox_post(msg->conn->mbox, NULL);
TCPIP_APIMSG_ACK(msg);
}
void
@ -623,7 +623,7 @@ do_close(struct api_msg_msg *msg)
}
}
#endif /* LWIP_TCP */
sys_mbox_post(msg->conn->mbox, NULL);
TCPIP_APIMSG_ACK(msg);
}
#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 */

View File

@ -56,7 +56,7 @@ netifapi_netif_add(struct netif *netif,
msg.msg.add.state = state;
msg.msg.add.init = init;
msg.msg.add.input = input;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
return msg.err;
}
@ -72,7 +72,7 @@ netifapi_netif_remove(struct netif *netif)
struct netifapi_msg msg;
msg.type = NETIFAPI_MSG_NETIF_REMOVE;
msg.netif = netif;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
return msg.err;
}
@ -88,7 +88,7 @@ netifapi_dhcp_start(struct netif *netif)
struct netifapi_msg msg;
msg.type = NETIFAPI_MSG_DHCP_START;
msg.netif = netif;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
return msg.err;
}
@ -104,7 +104,7 @@ netifapi_dhcp_stop(struct netif *netif)
struct netifapi_msg msg;
msg.type = NETIFAPI_MSG_DHCP_STOP;
msg.netif = netif;
tcpip_apimsg(&msg);
TCPIP_APIMSG(&msg);
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)) &&
((((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 */
buf.p = buf.ptr = NULL;
if (to) {
@ -568,7 +588,7 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags,
if (buf.p != NULL) {
pbuf_free(buf.p);
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
sock_set_errno(sock, err_to_errno(err));
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 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
static int tcpip_tcp_timer_active = 0;
@ -206,6 +211,7 @@ tcpip_thread(void *arg)
sys_timeout( IGMP_TMR_INTERVAL, igmp_timer, NULL);
#endif /* LWIP_IGMP */
LOCK_TCPIP_CORE();
while (1) { /* MAIN Loop */
sys_mbox_fetch(mbox, (void *)&msg);
switch (msg->type) {
@ -327,6 +333,18 @@ tcpip_apimsg(struct api_msg *apimsg)
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
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_arg = arg;
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);
}

View File

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

View File

@ -40,8 +40,25 @@
extern "C" {
#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);
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
err_t tcpip_input(struct pbuf *p, struct netif *inp);
#endif /* ETHARP_TCPIP_INPUT */