From 559f1ef82566bf421b656cf5ac459dd3df235e8e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 9 Feb 2015 07:50:10 -0600 Subject: [PATCH] Networking: Clean up and consolidate some clunky stuff by adding new net_timedwait() function --- include/nuttx/net/net.h | 27 ++++++++++++++++- net/arp/arp_notify.c | 7 +++-- net/arp/arp_send.c | 11 ------- net/icmpv6/icmpv6_autoconfig.c | 11 ------- net/icmpv6/icmpv6_neighbor.c | 11 ------- net/icmpv6/icmpv6_notify.c | 8 ++--- net/icmpv6/icmpv6_rnotify.c | 8 ++--- net/utils/net_lock.c | 54 +++++++++++++++++++++++++++------- 8 files changed, 82 insertions(+), 55 deletions(-) diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 2e3206de04..4b35f35d54 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -221,11 +221,36 @@ void net_unlock(net_lock_t flags); # define net_unlock(f) irqrestore(f) #endif +/**************************************************************************** + * Function: net_timedwait + * + * Description: + * Atomically wait for sem (or a timeout( while temporarily releasing + * the lock on the network. + * + * Input Parameters: + * sem - A reference to the semaphore to be taken. + * abstime - The absolute time to wait until a timeout is declared. + * + * Returned value: + * The returned value is the same as sem_timedwait(): Zero (OK) is + * returned on success; -1 (ERROR) is returned on a failure with the + * errno value set appropriately. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +struct timespec; +int net_timedwait(sem_t *sem, FAR const struct timespec *abstime); +#else +# define net_timedwait(s,t) sem_timedwait(s,t) +#endif + /**************************************************************************** * Function: net_lockedwait * * Description: - * Atomically wait for sem while temporarily releasing g_netlock. + * Atomically wait for sem while temporarily releasing lock on the network. * * Input Parameters: * sem - A reference to the semaphore to be taken. diff --git a/net/arp/arp_notify.c b/net/arp/arp_notify.c index 19e082f221..d2f4c06890 100644 --- a/net/arp/arp_notify.c +++ b/net/arp/arp_notify.c @@ -46,6 +46,7 @@ #include +#include #include #include "arp/arp.h" @@ -167,7 +168,7 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify) * * Assumptions: * This function is called from ARP send must execute with the network - * un-locked (interrupts may be disabled to keep the things stable). + * locked. * ****************************************************************************/ @@ -192,11 +193,11 @@ int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout) abstime.tv_nsec -= 1000000000; } - /* REVISIT: If sem_timedwait() is awakened with signal, we will return + /* REVISIT: If net_timedwait() is awakened with signal, we will return * the wrong error code. */ - (void)sem_timedwait(¬ify->nt_sem, &abstime); + (void)net_timedwait(¬ify->nt_sem, &abstime); ret = notify->nt_result; /* Remove our wait structure from the list (we may no longer be at the diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index 97485d8c70..e14513df75 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -190,9 +190,6 @@ int arp_send(in_addr_t ipaddr) struct arp_notify_s notify; struct timespec delay; struct arp_send_s state; -#ifdef CONFIG_NET_NOINTS - irqstate_t flags; -#endif net_lock_t save; int ret; @@ -367,15 +364,7 @@ int arp_send(in_addr_t ipaddr) delay.tv_sec = CONFIG_ARP_SEND_DELAYSEC; delay.tv_nsec = CONFIG_ARP_SEND_DELAYNSEC; -#ifdef CONFIG_NET_NOINTS - flags = irqsave(); /* Keep things stable */ - net_unlock(save); /* Unlock the network with interrupts disabled */ -#endif ret = arp_wait(¬ify, &delay); -#ifdef CONFIG_NET_NOINTS - save = net_lock(); /* Re-lock the network with interrupts disabled */ - irqrestore(flags); -#endif /* arp_wait will return OK if and only if the matching ARP response * is received. Otherwise, it will return -ETIMEDOUT. diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index 085775d35f..082e17ab18 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -278,9 +278,6 @@ static int icmpv6_wait_radvertise(FAR struct net_driver_s *dev, net_lock_t *save) { struct timespec delay; -#ifdef CONFIG_NET_NOINTS - irqstate_t flags; -#endif int ret; /* Wait for response to the Router Advertisement to be received. The @@ -291,15 +288,7 @@ static int icmpv6_wait_radvertise(FAR struct net_driver_s *dev, delay.tv_sec = CONFIG_ICMPv6_AUTOCONF_DELAYSEC; delay.tv_nsec = CONFIG_ICMPv6_AUTOCONF_DELAYNSEC; -#ifdef CONFIG_NET_NOINTS - flags = irqsave(); /* Keep things stable */ - net_unlock(*save); /* Unlock the network with interrupts disabled */ -#endif ret = icmpv6_rwait(notify, &delay); -#ifdef CONFIG_NET_NOINTS - *save = net_lock(); /* Re-lock the network with interrupts disabled */ - irqrestore(flags); -#endif /* icmpv6_wait will return OK if and only if the matching Router * Advertisement is received. Otherwise, it will return -ETIMEDOUT. diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c index 8c5d96180b..794b02d673 100644 --- a/net/icmpv6/icmpv6_neighbor.c +++ b/net/icmpv6/icmpv6_neighbor.c @@ -206,9 +206,6 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) struct timespec delay; struct icmpv6_neighbor_s state; FAR const uint16_t *lookup; -#ifdef CONFIG_NET_NOINTS - irqstate_t flags; -#endif net_lock_t save; int ret; @@ -381,15 +378,7 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) delay.tv_sec = CONFIG_ICMPv6_NEIGHBOR_DELAYSEC; delay.tv_nsec = CONFIG_ICMPv6_NEIGHBOR_DELAYNSEC; -#ifdef CONFIG_NET_NOINTS - flags = irqsave(); /* Keep things stable */ - net_unlock(save); /* Unlock the network with interrupts disabled */ -#endif ret = icmpv6_wait(¬ify, &delay); -#ifdef CONFIG_NET_NOINTS - save = net_lock(); /* Re-lock the network with interrupts disabled */ - irqrestore(flags); -#endif /* icmpv6_wait will return OK if and only if the matching Neighbor * Advertisement is received. Otherwise, it will return -ETIMEDOUT. diff --git a/net/icmpv6/icmpv6_notify.c b/net/icmpv6/icmpv6_notify.c index 692b9206c1..6c324d32df 100644 --- a/net/icmpv6/icmpv6_notify.c +++ b/net/icmpv6/icmpv6_notify.c @@ -47,6 +47,7 @@ #include +#include #include #include "icmpv6/icmpv6.h" @@ -170,8 +171,7 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify) * * Assumptions: * This function is called from icmpv6_neighbor() and must execute with - * the network un-locked (interrupts may be disabled to keep the things - * stable). + * the network locked. * ****************************************************************************/ @@ -197,11 +197,11 @@ int icmpv6_wait(FAR struct icmpv6_notify_s *notify, abstime.tv_nsec -= 1000000000; } - /* REVISIT: If sem_timedwait() is awakened with signal, we will return + /* REVISIT: If net_timedwait() is awakened with signal, we will return * the wrong error code. */ - (void)sem_timedwait(¬ify->nt_sem, &abstime); + (void)net_timedwait(¬ify->nt_sem, &abstime); ret = notify->nt_result; /* Remove our wait structure from the list (we may no longer be at the diff --git a/net/icmpv6/icmpv6_rnotify.c b/net/icmpv6/icmpv6_rnotify.c index 4515d1bd00..a605dc5772 100644 --- a/net/icmpv6/icmpv6_rnotify.c +++ b/net/icmpv6/icmpv6_rnotify.c @@ -47,6 +47,7 @@ #include +#include #include #include @@ -264,8 +265,7 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify) * * Assumptions: * This function is called from icmpv6_autoconfig() and must execute with - * the network un-locked (interrupts may be disabled to keep the things - * stable). + * the network locked. * ****************************************************************************/ @@ -293,11 +293,11 @@ int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, abstime.tv_nsec -= 1000000000; } - /* REVISIT: If sem_timedwait() is awakened with signal, we will return + /* REVISIT: If net_timedwait() is awakened with signal, we will return * the wrong error code. */ - (void)sem_timedwait(¬ify->rn_sem, &abstime); + (void)net_timedwait(¬ify->rn_sem, &abstime); ret = notify->rn_result; /* Remove our wait structure from the list (we may no longer be at the diff --git a/net/utils/net_lock.c b/net/utils/net_lock.c index 2569dca7f0..8c49cbf788 100644 --- a/net/utils/net_lock.c +++ b/net/utils/net_lock.c @@ -173,22 +173,24 @@ void net_unlock(net_lock_t flags) } /**************************************************************************** - * Function: net_lockedwait + * Function: net_timedwait * * Description: - * Atomically wait for sem while temporarily releasing g_netlock. + * Atomically wait for sem (or a timeout( while temporarily releasing + * the lock on the network. * * Input Parameters: - * sem - A reference to the semaphore to be taken. + * sem - A reference to the semaphore to be taken. + * abstime - The absolute time to wait until a timeout is declared. * * Returned value: - * The returned value is the same as sem_wait(): Zero (OK) is returned - * on success; -1 (ERROR) is returned on a failure with the errno value - * set appropriately. + * The returned value is the same as sem_wait() or sem_timedwait(): Zero + * (OK) is returned on success; -1 (ERROR) is returned on a failure with + * the errno value set appropriately. * ****************************************************************************/ -int net_lockedwait(sem_t *sem) +int net_timedwait(sem_t *sem, FAR const struct timespec *abstime) { pid_t me = getpid(); unsigned int count; @@ -206,9 +208,20 @@ int net_lockedwait(sem_t *sem) g_count = 0; sem_post(&g_netlock); - /* Now take the semaphore */ + /* Now take the semaphore, waiting if so requested. */ - ret = sem_wait(sem); + if (abstime) + { + /* Wait until we get the lock or until the timeout expires */ + + ret = sem_timedwait(sem, abstime); + } + else + { + /* Wait as long as necessary to get the lot */ + + ret = sem_wait(sem); + } /* Recover the network lock at the proper count */ @@ -224,6 +237,27 @@ int net_lockedwait(sem_t *sem) sched_unlock(); irqrestore(flags); return ret; - } +} + +/**************************************************************************** + * Function: net_lockedwait + * + * Description: + * Atomically wait for sem while temporarily releasing g_netlock. + * + * Input Parameters: + * sem - A reference to the semaphore to be taken. + * + * Returned value: + * The returned value is the same as sem_wait(): Zero (OK) is returned + * on success; -1 (ERROR) is returned on a failure with the errno value + * set appropriately. + * + ****************************************************************************/ + +int net_lockedwait(sem_t *sem) +{ + return net_timedwait(sem, NULL); +} #endif /* CONFIG_NET */