net: buf: Support allocation of a net_buf pointing to external buffer
Difference being that the data is not, then, allocated from the pool. Only the net_buf is. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
5c464b1bcc
commit
47e45c52a1
|
@ -445,6 +445,15 @@ static inline void net_buf_simple_restore(struct net_buf_simple *buf,
|
|||
* should be used instead.
|
||||
*/
|
||||
#define NET_BUF_FRAGS BIT(0)
|
||||
/** Flag indicating that the buffer's associated data pointer, points to
|
||||
* externally allocated memory. Therefore once ref goes down to zero, the
|
||||
* pointed data will not need to be deallocated. This never needs to be
|
||||
* explicitely set or unet by the net_buf API user. Such net_buf is
|
||||
* exclusively instanciated via net_buf_alloc_with_data() function.
|
||||
* Reference count mechanism however will behave the same way, and ref
|
||||
* count going to 0 will free the net_buf but no the data pointer in it.
|
||||
*/
|
||||
#define NET_BUF_EXTERNAL_DATA BIT(1)
|
||||
|
||||
/** @brief Network buffer representation.
|
||||
*
|
||||
|
@ -787,6 +796,39 @@ struct net_buf *net_buf_alloc_len(struct net_buf_pool *pool, size_t size,
|
|||
s32_t timeout);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Allocate a new buffer from a pool but with external data pointer.
|
||||
*
|
||||
* Allocate a new buffer from a pool, where the data pointer comes from the
|
||||
* user and not from the pool.
|
||||
*
|
||||
* @param pool Which pool to allocate the buffer from.
|
||||
* @param data External data pointer
|
||||
* @param size Amount of data the pointed data buffer if able to fit.
|
||||
* @param timeout Affects the action taken should the pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out. Note that some types
|
||||
* of data allocators do not support blocking (such as the HEAP
|
||||
* type). In this case it's still possible for net_buf_alloc() to
|
||||
* fail (return NULL) even if it was given K_FOREVER.
|
||||
*
|
||||
* @return New buffer or NULL if out of buffers.
|
||||
*/
|
||||
#if defined(CONFIG_NET_BUF_LOG)
|
||||
struct net_buf *net_buf_alloc_with_data_debug(struct net_buf_pool *pool,
|
||||
void *data, size_t size,
|
||||
s32_t timeout, const char *func,
|
||||
int line);
|
||||
#define net_buf_alloc_with_data(_pool, _data_, _size, _timeout) \
|
||||
net_buf_alloc_with_data_debug(_pool, _data_, _size, _timeout, \
|
||||
__func__, __LINE__)
|
||||
#else
|
||||
struct net_buf *net_buf_alloc_with_data(struct net_buf_pool *pool,
|
||||
void *data, size_t size,
|
||||
s32_t timeout);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get a buffer from a FIFO.
|
||||
*
|
||||
|
|
|
@ -216,6 +216,10 @@ static void data_unref(struct net_buf *buf, u8_t *data)
|
|||
{
|
||||
struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id);
|
||||
|
||||
if (buf->flags & NET_BUF_EXTERNAL_DATA) {
|
||||
return;
|
||||
}
|
||||
|
||||
pool->alloc->cb->unref(buf, data);
|
||||
}
|
||||
|
||||
|
@ -357,6 +361,37 @@ struct net_buf *net_buf_alloc_fixed(struct net_buf_pool *pool, s32_t timeout)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET_BUF_LOG)
|
||||
struct net_buf *net_buf_alloc_with_data_debug(struct net_buf_pool *pool,
|
||||
void *data, size_t size,
|
||||
s32_t timeout, const char *func,
|
||||
int line)
|
||||
#else
|
||||
struct net_buf *net_buf_alloc_with_data(struct net_buf_pool *pool,
|
||||
void *data, size_t size,
|
||||
s32_t timeout)
|
||||
#endif
|
||||
{
|
||||
struct net_buf *buf;
|
||||
|
||||
#if defined(CONFIG_NET_BUF_LOG)
|
||||
buf = net_buf_alloc_len_debug(pool, 0, timeout, func, line);
|
||||
#else
|
||||
buf = net_buf_alloc_len(pool, 0, timeout);
|
||||
#endif
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf->__buf = data;
|
||||
buf->data = data;
|
||||
buf->size = size;
|
||||
buf->len = size;
|
||||
buf->flags = NET_BUF_EXTERNAL_DATA;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_BUF_LOG)
|
||||
struct net_buf *net_buf_get_debug(struct k_fifo *fifo, s32_t timeout,
|
||||
const char *func, int line)
|
||||
|
@ -542,7 +577,7 @@ struct net_buf *net_buf_clone(struct net_buf *buf, s32_t timeout)
|
|||
/* If the pool supports data referencing use that. Otherwise
|
||||
* we need to allocate new data and make a copy.
|
||||
*/
|
||||
if (pool->alloc->cb->ref) {
|
||||
if (pool->alloc->cb->ref && !(buf->flags & NET_BUF_EXTERNAL_DATA)) {
|
||||
clone->__buf = data_ref(buf, buf->__buf);
|
||||
clone->data = buf->data;
|
||||
clone->len = buf->len;
|
||||
|
|
Loading…
Reference in a new issue