From a92d5f622e322230e71435431a23fc6f132b4b69 Mon Sep 17 00:00:00 2001 From: "chao.an" Date: Thu, 17 Feb 2022 12:42:35 +0800 Subject: [PATCH] net/ioballoc: add support of alloc with timeout net_iobtimedalloc() Signed-off-by: chao.an --- include/nuttx/net/net.h | 34 ++++++++++++++++-- net/utils/net_lock.c | 79 +++++++++++++++++++++++++++++------------ 2 files changed, 88 insertions(+), 25 deletions(-) diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 0543dc0ee9..8bdd5031a7 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -460,6 +460,36 @@ int net_timedwait_uninterruptible(sem_t *sem, unsigned int timeout); int net_lockedwait_uninterruptible(sem_t *sem); +#ifdef CONFIG_MM_IOB + +/**************************************************************************** + * Name: net_iobtimedalloc + * + * Description: + * Allocate an IOB. If no IOBs are available, then atomically wait for + * for the IOB while temporarily releasing the lock on the network. + * This function is wrapped version of net_ioballoc(), this wait will + * be terminated when the specified timeout expires. + * + * Caution should be utilized. Because the network lock is relinquished + * during the wait, there could be changes in the network state that occur + * before the lock is recovered. Your design should account for this + * possibility. + * + * Input Parameters: + * throttled - An indication of the IOB allocation is "throttled" + * timeout - The relative time to wait until a timeout is declared. + * consumerid - id representing who is consuming the IOB + * + * Returned Value: + * A pointer to the newly allocated IOB is returned on success. NULL is + * returned on any allocation failure. + * + ****************************************************************************/ + +FAR struct iob_s *net_iobtimedalloc(bool throttled, unsigned int timeout, + enum iob_user_e consumerid); + /**************************************************************************** * Name: net_ioballoc * @@ -473,7 +503,8 @@ int net_lockedwait_uninterruptible(sem_t *sem); * possibility. * * Input Parameters: - * throttled - An indication of the IOB allocation is "throttled" + * throttled - An indication of the IOB allocation is "throttled" + * consumerid - id representing who is consuming the IOB * * Returned Value: * A pointer to the newly allocated IOB is returned on success. NULL is @@ -481,7 +512,6 @@ int net_lockedwait_uninterruptible(sem_t *sem); * ****************************************************************************/ -#ifdef CONFIG_MM_IOB FAR struct iob_s *net_ioballoc(bool throttled, enum iob_user_e consumerid); #endif diff --git a/net/utils/net_lock.c b/net/utils/net_lock.c index 94b33851bf..91666c59d8 100644 --- a/net/utils/net_lock.c +++ b/net/utils/net_lock.c @@ -451,6 +451,59 @@ int net_lockedwait_uninterruptible(sem_t *sem) return net_timedwait_uninterruptible(sem, UINT_MAX); } +#ifdef CONFIG_MM_IOB + +/**************************************************************************** + * Name: net_timedalloc + * + * Description: + * Allocate an IOB. If no IOBs are available, then atomically wait for + * for the IOB while temporarily releasing the lock on the network. + * This function is wrapped version of nxsem_timedwait(), this wait will + * be terminated when the specified timeout expires. + * + * Caution should be utilized. Because the network lock is relinquished + * during the wait, there could be changes in the network state that occur + * before the lock is recovered. Your design should account for this + * possibility. + * + * Input Parameters: + * throttled - An indication of the IOB allocation is "throttled" + * timeout - The relative time to wait until a timeout is declared. + * consumerid - id representing who is consuming the IOB + * + * Returned Value: + * A pointer to the newly allocated IOB is returned on success. NULL is + * returned on any allocation failure. + * + ****************************************************************************/ + +FAR struct iob_s *net_iobtimedalloc(bool throttled, unsigned int timeout, + enum iob_user_e consumerid) +{ + FAR struct iob_s *iob; + + iob = iob_tryalloc(throttled, consumerid); + if (iob == NULL && timeout != 0) + { + unsigned int count; + int blresult; + + /* There are no buffers available now. We will have to wait for one to + * become available. But let's not do that with the network locked. + */ + + blresult = net_breaklock(&count); + iob = iob_timedalloc(throttled, timeout, consumerid); + if (blresult >= 0) + { + net_restorelock(count); + } + } + + return iob; +} + /**************************************************************************** * Name: net_ioballoc * @@ -464,7 +517,8 @@ int net_lockedwait_uninterruptible(sem_t *sem) * possibility. * * Input Parameters: - * throttled - An indication of the IOB allocation is "throttled" + * throttled - An indication of the IOB allocation is "throttled" + * consumerid - id representing who is consuming the IOB * * Returned Value: * A pointer to the newly allocated IOB is returned on success. NULL is @@ -472,29 +526,8 @@ int net_lockedwait_uninterruptible(sem_t *sem) * ****************************************************************************/ -#ifdef CONFIG_MM_IOB FAR struct iob_s *net_ioballoc(bool throttled, enum iob_user_e consumerid) { - FAR struct iob_s *iob; - - iob = iob_tryalloc(throttled, consumerid); - if (iob == NULL) - { - unsigned int count; - int blresult; - - /* There are no buffers available now. We will have to wait for one to - * become available. But let's not do that with the network locked. - */ - - blresult = net_breaklock(&count); - iob = iob_alloc(throttled, consumerid); - if (blresult >= 0) - { - net_restorelock(count); - } - } - - return iob; + return net_iobtimedalloc(throttled, UINT_MAX, consumerid); } #endif