net: Add net_buf_get_timeout() API

With this API it's possible for the caller to force specific behavior
when it comes to waiting (or not waiting) on the FIFO.

Change-Id: Ib66e2f767c26c82abf1ba3b80bd15aec2383542e
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2016-05-04 20:27:48 +03:00
parent 2b456dd120
commit 6e4d2a9e0e
2 changed files with 42 additions and 11 deletions

View file

@ -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

View file

@ -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);