diff --git a/include/net/buf.h b/include/net/buf.h index b1a40bd50a0..c0ac1372837 100644 --- a/include/net/buf.h +++ b/include/net/buf.h @@ -127,10 +127,28 @@ struct net_buf { * * @warning If there are no available buffers and the function is * called from a task or fiber the call will block until a buffer - * becomes available in the pool. + * becomes available in the pool. If you want to make sure no blocking + * happens use net_buf_get_timeout() instead with TICKS_NONE. */ struct net_buf *net_buf_get(struct nano_fifo *fifo, size_t reserve_head); +/** @brief Get a new buffer from the pool. + * + * Get buffer from the available buffers pool with specified type and + * reserved headroom. + * + * @param fifo Which FIFO to take the buffer from. + * @param reserve_head How much headroom to reserve. + * @param timeout Affects the action taken should the pool (FIFO) be empty. + * If TICKS_NONE, then return immediately. If TICKS_UNLIMITED, then + * wait as long as necessary. Otherwise, wait up to the specified + * number of ticks before timing out. + * + * @return New buffer or NULL if out of buffers. + */ +struct net_buf *net_buf_get_timeout(struct nano_fifo *fifo, + size_t reserve_head, int32_t timeout); + /** @brief Decrements the reference count of a buffer. * * Decrements the reference count of a buffer and puts it back into the diff --git a/net/buf.c b/net/buf.c index ae38fddcf34..6d5b0c23988 100644 --- a/net/buf.c +++ b/net/buf.c @@ -43,21 +43,18 @@ #define NET_BUF_ASSERT(cond) #endif /* CONFIG_NET_BUF_DEBUG */ -struct net_buf *net_buf_get(struct nano_fifo *fifo, size_t reserve_head) +struct net_buf *net_buf_get_timeout(struct nano_fifo *fifo, + size_t reserve_head, int32_t timeout) { struct net_buf *buf; - NET_BUF_DBG("fifo %p reserve %u\n", fifo, reserve_head); + NET_BUF_DBG("fifo %p reserve %u timeout %d\n", fifo, reserve_head, + timeout); - buf = nano_fifo_get(fifo, TICKS_NONE); + buf = nano_fifo_get(fifo, timeout); if (!buf) { - if (sys_execution_context_type_get() == NANO_CTX_ISR) { - NET_BUF_ERR("Failed to get free buffer\n"); - return NULL; - } - - NET_BUF_WARN("Low on buffers. Waiting (fifo %p)\n", fifo); - buf = nano_fifo_get(fifo, TICKS_UNLIMITED); + NET_BUF_ERR("Failed to get free buffer\n"); + return NULL; } buf->ref = 1; @@ -69,6 +66,22 @@ struct net_buf *net_buf_get(struct nano_fifo *fifo, size_t reserve_head) return buf; } +struct net_buf *net_buf_get(struct nano_fifo *fifo, size_t reserve_head) +{ + struct net_buf *buf; + + NET_BUF_DBG("fifo %p reserve %u\n", fifo, reserve_head); + + buf = net_buf_get_timeout(fifo, reserve_head, TICKS_NONE); + if (buf || sys_execution_context_type_get() == NANO_CTX_ISR) { + return buf; + } + + NET_BUF_WARN("Low on buffers. Waiting (fifo %p)\n", fifo); + + return net_buf_get_timeout(fifo, reserve_head, TICKS_UNLIMITED); +} + void net_buf_unref(struct net_buf *buf) { NET_BUF_DBG("buf %p ref %u fifo %p\n", buf, buf->ref, buf->free);