added option LWIP_NETCONN_SEM_PER_THREAD to use a semaphore per thread instead of using one per netconn and per select call

This commit is contained in:
sg
2014-12-10 20:45:01 +01:00
parent 35729f0870
commit cacdbb5262
10 changed files with 187 additions and 48 deletions

View File

@@ -172,8 +172,10 @@ struct netconn {
} pcb;
/** the last error this netconn had */
err_t last_err;
#if !LWIP_NETCONN_SEM_PER_THREAD
/** sem that is used to synchronously execute functions in the core context */
sys_sem_t op_completed;
#endif
/** mbox where received packets are stored until they are fetched
by the netconn application thread (can grow quite big) */
sys_mbox_t recvmbox;
@@ -188,11 +190,11 @@ struct netconn {
#endif /* LWIP_SOCKET */
#if LWIP_SO_SNDTIMEO
/** timeout to wait for sending data (which means enqueueing data for sending
in internal buffers) */
in internal buffers) in milliseconds */
s32_t send_timeout;
#endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVTIMEO
/** timeout to wait for new data to be received
/** timeout in milliseconds to wait for new data to be received
(or connections to arrive for listening netconns) */
int recv_timeout;
#endif /* LWIP_SO_RCVTIMEO */
@@ -329,6 +331,14 @@ err_t netconn_gethostbyname(const char *name, ip_addr_t *addr);
#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize)
#endif /* LWIP_SO_RCVBUF*/
#if LWIP_NETCONN_SEM_PER_THREAD
void netconn_thread_init(void);
void netconn_thread_cleanup(void);
#else /* LWIP_NETCONN_SEM_PER_THREAD */
#define netconn_thread_init()
#define netconn_thread_cleanup()
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
#ifdef __cplusplus
}
#endif

View File

@@ -121,8 +121,18 @@ struct api_msg_msg {
} lb;
#endif /* TCP_LISTEN_BACKLOG */
} msg;
#if LWIP_NETCONN_SEM_PER_THREAD
sys_sem_t* op_completed_sem;
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
};
#if LWIP_NETCONN_SEM_PER_THREAD
#define LWIP_API_MSG_SEM(msg) ((msg)->op_completed_sem)
#else /* LWIP_NETCONN_SEM_PER_THREAD */
#define LWIP_API_MSG_SEM(msg) (&(msg)->conn->op_completed)
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
/** This struct contains a function to execute in another thread context and
a struct api_msg_msg that serves as an argument for this function.
This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */

View File

@@ -1473,6 +1473,20 @@
#define LWIP_TCPIP_TIMEOUT 1
#endif
/** LWIP_NETCONN_SEM_PER_THREAD==1: Use one (thread-local) semaphore per
* thread calling socket/netconn functions instead of allocating one
* semaphore per netconn (and per select etc.)
* ATTENTION: a thread-local semaphore for API calls is needed:
* - LWIP_NETCONN_THREAD_SEM_GET() returning a sys_sem_t*
* - LWIP_NETCONN_THREAD_SEM_ALLOC() creating the semaphore
* - LWIP_NETCONN_THREAD_SEM_FREE() freeing the semaphore
* The latter 2 can be invoked up by calling netconn_thread_init()/netconn_thread_cleanup().
* Ports may call these for threads created with sys_thread_new().
*/
#ifndef LWIP_NETCONN_SEM_PER_THREAD
#define LWIP_NETCONN_SEM_PER_THREAD 0
#endif
/*
------------------------------------
---------- Socket options ----------

View File

@@ -128,6 +128,10 @@ struct lwip_setgetsockopt_data {
socklen_t *optlen;
/** if an error occurs, it is temporarily stored here */
err_t err;
#if !LWIP_TCPIP_CORE_LOCKING
/** semaphore to wake up the calling task */
void* completed_sem;
#endif /* !LWIP_TCPIP_CORE_LOCKING */
};
/* Socket protocol types (TCP/UDP/RAW) */

View File

@@ -65,8 +65,14 @@ extern sys_mutex_t lock_tcpip_core;
#else
#define TCIP_APIMSG_SET_ERR(m, e)
#endif
#if LWIP_NETCONN_SEM_PER_THREAD
#define TCPIP_APIMSG_SET_SEM(m) ((m)->msg.op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET())
#else
#define TCPIP_APIMSG_SET_SEM(m)
#endif
#define TCPIP_APIMSG_NOERR(m,f) do { \
TCIP_APIMSG_SET_ERR(m, ERR_VAL); \
TCPIP_APIMSG_SET_SEM(m); \
LOCK_TCPIP_CORE(); \
f(&((m)->msg)); \
UNLOCK_TCPIP_CORE(); \
@@ -85,7 +91,7 @@ extern sys_mutex_t lock_tcpip_core;
#define UNLOCK_TCPIP_CORE()
#define TCPIP_APIMSG_NOERR(m,f) do { (m)->function = f; tcpip_apimsg(m); } while(0)
#define TCPIP_APIMSG(m,f,e) do { (m)->function = f; (e) = tcpip_apimsg(m); } while(0)
#define TCPIP_APIMSG_ACK(m) sys_sem_signal(&m->conn->op_completed)
#define TCPIP_APIMSG_ACK(m) sys_sem_signal(LWIP_API_MSG_SEM(m))
#define TCPIP_NETIFAPI(m) tcpip_netifapi(m)
#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem)
#define TCPIP_PPPAPI(m) tcpip_pppapi(m)