mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 02:48:37 +08:00
net: Add buffer pool to replace connection allocation
Our net socket connection allocations are powerful but redundant because they're implemented once in each protocol. This is not good for further optimizing and extending to other allocations, so maybe we can add a common implementation for the usage. Impact: 1. We add a `struct net_bufpool_s` as pool descriptor, which may use a little bit more memory than previous implementation (~28Bytes). 2. We share same functions between pools, so code size may shrink under some scenarios. Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
badb5c5ac6
commit
1fe07d0838
15 changed files with 437 additions and 724 deletions
|
@ -42,10 +42,19 @@
|
|||
#include <nuttx/net/bluetooth.h>
|
||||
|
||||
#include "devif/devif.h"
|
||||
#include "utils/utils.h"
|
||||
#include "bluetooth/bluetooth.h"
|
||||
|
||||
#ifdef CONFIG_NET_BLUETOOTH
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NET_BLUETOOTH_MAX_CONNS
|
||||
# define CONFIG_NET_BLUETOOTH_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
@ -54,14 +63,10 @@
|
|||
* network lock.
|
||||
*/
|
||||
|
||||
#if CONFIG_NET_BLUETOOTH_PREALLOC_CONNS > 0
|
||||
static struct bluetooth_conn_s
|
||||
g_bluetooth_connections[CONFIG_NET_BLUETOOTH_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free packet socket connections */
|
||||
|
||||
static dq_queue_t g_free_bluetooth_connections;
|
||||
NET_BUFPOOL_DECLARE(g_bluetooth_connections, sizeof(struct bluetooth_conn_s),
|
||||
CONFIG_NET_BLUETOOTH_PREALLOC_CONNS,
|
||||
CONFIG_NET_BLUETOOTH_ALLOC_CONNS,
|
||||
CONFIG_NET_BLUETOOTH_MAX_CONNS);
|
||||
|
||||
/* A list of all allocated packet socket connections */
|
||||
|
||||
|
@ -90,17 +95,7 @@ static const bt_addr_t g_any_addr =
|
|||
|
||||
void bluetooth_conn_initialize(void)
|
||||
{
|
||||
#if CONFIG_NET_BLUETOOTH_PREALLOC_CONNS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_BLUETOOTH_PREALLOC_CONNS; i++)
|
||||
{
|
||||
/* Link each pre-allocated connection structure into the free list. */
|
||||
|
||||
dq_addlast(&g_bluetooth_connections[i].bc_conn.node,
|
||||
&g_free_bluetooth_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_bluetooth_connections);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -115,39 +110,12 @@ void bluetooth_conn_initialize(void)
|
|||
FAR struct bluetooth_conn_s *bluetooth_conn_alloc(void)
|
||||
{
|
||||
FAR struct bluetooth_conn_s *conn;
|
||||
#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS > 0
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* The free list is protected by the network lock */
|
||||
|
||||
net_lock();
|
||||
#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS > 0
|
||||
if (dq_peek(&g_active_bluetooth_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_NET_BLUETOOTH_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_bluetooth_connections) +
|
||||
CONFIG_NET_BLUETOOTH_ALLOC_CONNS > CONFIG_NET_BLUETOOTH_MAX_CONNS)
|
||||
{
|
||||
net_unlock();
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(*conn) * CONFIG_NET_BLUETOOTH_ALLOC_CONNS);
|
||||
if (conn != NULL)
|
||||
{
|
||||
for (i = 0; i < CONFIG_NET_BLUETOOTH_ALLOC_CONNS; i++)
|
||||
{
|
||||
dq_addlast(&conn[i].bc_conn.node,
|
||||
&g_active_bluetooth_connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = (FAR struct bluetooth_conn_s *)
|
||||
dq_remfirst(&g_free_bluetooth_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_bluetooth_connections);
|
||||
if (conn)
|
||||
{
|
||||
/* Mark as unbound */
|
||||
|
@ -207,22 +175,9 @@ void bluetooth_conn_free(FAR struct bluetooth_conn_s *conn)
|
|||
bluetooth_container_free(container);
|
||||
}
|
||||
|
||||
/* If this is a preallocated or a batch allocated connection store it in
|
||||
* the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection structure */
|
||||
|
||||
#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS == 1
|
||||
if (conn < g_bluetooth_connections || conn >= (g_bluetooth_connections +
|
||||
CONFIG_NET_BLUETOOTH_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
dq_addlast(&conn->bc_conn.node, &g_free_bluetooth_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_bluetooth_connections, conn);
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
|
|
|
@ -45,19 +45,23 @@
|
|||
|
||||
#ifdef CONFIG_NET_CAN
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_CAN_MAX_CONNS
|
||||
# define CONFIG_CAN_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The array containing all NetLink connections. */
|
||||
|
||||
#if CONFIG_CAN_PREALLOC_CONNS > 0
|
||||
static struct can_conn_s g_can_connections[CONFIG_CAN_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free NetLink connections */
|
||||
|
||||
static dq_queue_t g_free_can_connections;
|
||||
NET_BUFPOOL_DECLARE(g_can_connections, sizeof(struct can_conn_s),
|
||||
CONFIG_CAN_PREALLOC_CONNS, CONFIG_CAN_ALLOC_CONNS,
|
||||
CONFIG_CAN_MAX_CONNS);
|
||||
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
|
||||
|
||||
/* A list of all allocated NetLink connections */
|
||||
|
@ -79,16 +83,7 @@ static dq_queue_t g_active_can_connections;
|
|||
|
||||
void can_initialize(void)
|
||||
{
|
||||
#if CONFIG_CAN_PREALLOC_CONNS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_CAN_PREALLOC_CONNS; i++)
|
||||
{
|
||||
/* Mark the connection closed and move it to the free list */
|
||||
|
||||
dq_addlast(&g_can_connections[i].sconn.node, &g_free_can_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_can_connections);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -103,37 +98,12 @@ void can_initialize(void)
|
|||
FAR struct can_conn_s *can_alloc(void)
|
||||
{
|
||||
FAR struct can_conn_s *conn;
|
||||
#if CONFIG_CAN_ALLOC_CONNS > 0
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* The free list is protected by a a mutex. */
|
||||
|
||||
nxmutex_lock(&g_free_lock);
|
||||
#if CONFIG_CAN_ALLOC_CONNS > 0
|
||||
if (dq_peek(&g_free_can_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_CAN_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_can_connections) +
|
||||
CONFIG_CAN_ALLOC_CONNS > CONFIG_CAN_MAX_CONNS)
|
||||
{
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(*conn) * CONFIG_CAN_ALLOC_CONNS);
|
||||
if (conn != NULL)
|
||||
{
|
||||
for (i = 0; i < CONFIG_CAN_ALLOC_CONNS; i++)
|
||||
{
|
||||
dq_addlast(&conn[i].sconn.node, &g_free_can_connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = (FAR struct can_conn_s *)dq_remfirst(&g_free_can_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_can_connections);
|
||||
if (conn != NULL)
|
||||
{
|
||||
/* FIXME SocketCAN default behavior enables loopback */
|
||||
|
@ -184,22 +154,9 @@ void can_free(FAR struct can_conn_s *conn)
|
|||
|
||||
dq_rem(&conn->sconn.node, &g_active_can_connections);
|
||||
|
||||
/* If this is a preallocated or a batch allocated connection store it in
|
||||
* the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection. */
|
||||
|
||||
#if CONFIG_CAN_ALLOC_CONNS == 1
|
||||
if (conn < g_can_connections || conn >= (g_can_connections +
|
||||
CONFIG_CAN_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
dq_addlast(&conn->sconn.node, &g_free_can_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_can_connections, conn);
|
||||
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#include "netdev/netdev.h"
|
||||
#include "utils/utils.h"
|
||||
#include "devif/devif.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -52,11 +53,9 @@
|
|||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_PREALLOC_DEVIF_CALLBACKS > 0
|
||||
static struct devif_callback_s
|
||||
g_cbprealloc[CONFIG_NET_PREALLOC_DEVIF_CALLBACKS];
|
||||
#endif
|
||||
static FAR struct devif_callback_s *g_cbfreelist = NULL;
|
||||
NET_BUFPOOL_DECLARE(g_cbprealloc, sizeof(struct devif_callback_s),
|
||||
CONFIG_NET_PREALLOC_DEVIF_CALLBACKS,
|
||||
CONFIG_NET_ALLOC_DEVIF_CALLBACKS, 0);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -88,7 +87,7 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
|
|||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
/* Check for double freed callbacks */
|
||||
|
||||
curr = g_cbfreelist;
|
||||
curr = (FAR struct devif_callback_s *)g_cbprealloc.freebuffers.head;
|
||||
|
||||
while (curr != NULL)
|
||||
{
|
||||
|
@ -187,23 +186,9 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
|
|||
}
|
||||
}
|
||||
|
||||
/* If this is a preallocated or a batch allocated callback store it in
|
||||
* the free callbacks list. Else free it.
|
||||
*/
|
||||
/* Free the callback structure */
|
||||
|
||||
#if CONFIG_NET_ALLOC_DEVIF_CALLBACKS == 1
|
||||
if (cb < g_cbprealloc || cb >= (g_cbprealloc +
|
||||
CONFIG_NET_PREALLOC_DEVIF_CALLBACKS))
|
||||
{
|
||||
kmm_free(cb);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cb->nxtconn = g_cbfreelist;
|
||||
cb->nxtdev = NULL;
|
||||
g_cbfreelist = cb;
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_cbprealloc, cb);
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
|
@ -266,15 +251,7 @@ static bool devif_event_trigger(uint16_t events, uint16_t triggers)
|
|||
|
||||
void devif_callback_init(void)
|
||||
{
|
||||
#if CONFIG_NET_PREALLOC_DEVIF_CALLBACKS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_PREALLOC_DEVIF_CALLBACKS; i++)
|
||||
{
|
||||
g_cbprealloc[i].nxtconn = g_cbfreelist;
|
||||
g_cbfreelist = &g_cbprealloc[i];
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_cbprealloc);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -299,9 +276,6 @@ FAR struct devif_callback_s *
|
|||
FAR struct devif_callback_s **list_tail)
|
||||
{
|
||||
FAR struct devif_callback_s *ret;
|
||||
#if CONFIG_NET_ALLOC_DEVIF_CALLBACKS > 0
|
||||
int i;
|
||||
#endif
|
||||
|
||||
net_lock();
|
||||
|
||||
|
@ -324,34 +298,11 @@ FAR struct devif_callback_s *
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate the callback entry from heap */
|
||||
/* Get a callback structure */
|
||||
|
||||
#if CONFIG_NET_ALLOC_DEVIF_CALLBACKS > 0
|
||||
if (g_cbfreelist == NULL)
|
||||
{
|
||||
ret = kmm_zalloc(sizeof(struct devif_callback_s) *
|
||||
CONFIG_NET_ALLOC_DEVIF_CALLBACKS);
|
||||
if (ret != NULL)
|
||||
{
|
||||
for (i = 0; i < CONFIG_NET_ALLOC_DEVIF_CALLBACKS; i++)
|
||||
{
|
||||
ret[i].nxtconn = g_cbfreelist;
|
||||
g_cbfreelist = &ret[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check the head of the free list */
|
||||
|
||||
ret = g_cbfreelist;
|
||||
ret = NET_BUFPOOL_TRYALLOC(g_cbprealloc);
|
||||
if (ret)
|
||||
{
|
||||
/* Remove the next instance from the head of the free list */
|
||||
|
||||
g_cbfreelist = ret->nxtconn;
|
||||
memset(ret, 0, sizeof(struct devif_callback_s));
|
||||
|
||||
/* Add the newly allocated instance to the head of the device event
|
||||
* list.
|
||||
*/
|
||||
|
|
|
@ -41,22 +41,27 @@
|
|||
|
||||
#include "devif/devif.h"
|
||||
#include "icmp/icmp.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
#ifdef CONFIG_NET_ICMP_SOCKET
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NET_ICMP_MAX_CONNS
|
||||
# define CONFIG_NET_ICMP_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The array containing all IPPROTO_ICMP socket connections */
|
||||
|
||||
#if CONFIG_NET_ICMP_PREALLOC_CONNS > 0
|
||||
static struct icmp_conn_s g_icmp_connections[CONFIG_NET_ICMP_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free IPPROTO_ICMP socket connections */
|
||||
|
||||
static dq_queue_t g_free_icmp_connections;
|
||||
NET_BUFPOOL_DECLARE(g_icmp_connections, sizeof(struct icmp_conn_s),
|
||||
CONFIG_NET_ICMP_PREALLOC_CONNS,
|
||||
CONFIG_NET_ICMP_ALLOC_CONNS, CONFIG_NET_ICMP_MAX_CONNS);
|
||||
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
|
||||
|
||||
/* A list of all allocated IPPROTO_ICMP socket connections */
|
||||
|
@ -78,17 +83,7 @@ static dq_queue_t g_active_icmp_connections;
|
|||
|
||||
void icmp_sock_initialize(void)
|
||||
{
|
||||
#if CONFIG_NET_ICMP_PREALLOC_CONNS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_ICMP_PREALLOC_CONNS; i++)
|
||||
{
|
||||
/* Move the connection structure to the free list */
|
||||
|
||||
dq_addlast(&g_icmp_connections[i].sconn.node,
|
||||
&g_free_icmp_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_icmp_connections);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -111,31 +106,7 @@ FAR struct icmp_conn_s *icmp_alloc(void)
|
|||
ret = nxmutex_lock(&g_free_lock);
|
||||
if (ret >= 0)
|
||||
{
|
||||
#if CONFIG_NET_ICMP_ALLOC_CONNS > 0
|
||||
if (dq_peek(&g_free_icmp_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_NET_ICMP_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_icmp_connections) +
|
||||
CONFIG_NET_ICMP_ALLOC_CONNS > CONFIG_NET_ICMP_MAX_CONNS)
|
||||
{
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(*conn) * CONFIG_NET_ICMP_ALLOC_CONNS);
|
||||
if (conn != NULL)
|
||||
{
|
||||
for (ret = 0; ret < CONFIG_NET_ICMP_ALLOC_CONNS; ret++)
|
||||
{
|
||||
dq_addlast(&conn[ret].sconn.node,
|
||||
&g_free_icmp_connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = (FAR struct icmp_conn_s *)dq_remfirst(&g_free_icmp_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_icmp_connections);
|
||||
if (conn != NULL)
|
||||
{
|
||||
/* Enqueue the connection into the active list */
|
||||
|
@ -184,22 +155,9 @@ void icmp_free(FAR struct icmp_conn_s *conn)
|
|||
|
||||
dq_rem(&conn->sconn.node, &g_active_icmp_connections);
|
||||
|
||||
/* If this is a preallocated or a batch allocated connection store it
|
||||
* in the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection. */
|
||||
|
||||
#if CONFIG_NET_ICMP_ALLOC_CONNS == 1
|
||||
if (conn < g_icmp_connections || conn >= (g_icmp_connections +
|
||||
CONFIG_NET_ICMP_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
dq_addlast(&conn->sconn.node, &g_free_icmp_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_icmp_connections, conn);
|
||||
}
|
||||
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
|
|
|
@ -41,23 +41,28 @@
|
|||
|
||||
#include "devif/devif.h"
|
||||
#include "icmpv6/icmpv6.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6_SOCKET
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NET_ICMPv6_MAX_CONNS
|
||||
# define CONFIG_NET_ICMPv6_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The array containing all IPPROTO_ICMP socket connections */
|
||||
|
||||
#if CONFIG_NET_ICMPv6_PREALLOC_CONNS > 0
|
||||
static struct icmpv6_conn_s
|
||||
g_icmpv6_connections[CONFIG_NET_ICMPv6_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free IPPROTO_ICMP socket connections */
|
||||
|
||||
static dq_queue_t g_free_icmpv6_connections;
|
||||
NET_BUFPOOL_DECLARE(g_icmpv6_connections, sizeof(struct icmpv6_conn_s),
|
||||
CONFIG_NET_ICMPv6_PREALLOC_CONNS,
|
||||
CONFIG_NET_ICMPv6_ALLOC_CONNS,
|
||||
CONFIG_NET_ICMPv6_MAX_CONNS);
|
||||
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
|
||||
|
||||
/* A list of all allocated IPPROTO_ICMP socket connections */
|
||||
|
@ -79,17 +84,7 @@ static dq_queue_t g_active_icmpv6_connections;
|
|||
|
||||
void icmpv6_sock_initialize(void)
|
||||
{
|
||||
#if CONFIG_NET_ICMPv6_PREALLOC_CONNS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_ICMPv6_PREALLOC_CONNS; i++)
|
||||
{
|
||||
/* Move the connection structure to the free list */
|
||||
|
||||
dq_addlast(&g_icmpv6_connections[i].sconn.node,
|
||||
&g_free_icmpv6_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_icmpv6_connections);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -112,32 +107,7 @@ FAR struct icmpv6_conn_s *icmpv6_alloc(void)
|
|||
ret = nxmutex_lock(&g_free_lock);
|
||||
if (ret >= 0)
|
||||
{
|
||||
#if CONFIG_NET_ICMPv6_ALLOC_CONNS > 0
|
||||
if (dq_peek(&g_active_icmpv6_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_NET_ICMPv6_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_icmpv6_connections) +
|
||||
CONFIG_NET_ICMPv6_ALLOC_CONNS > CONFIG_NET_ICMPv6_MAX_CONNS)
|
||||
{
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(*conn) * CONFIG_NET_ICMPv6_ALLOC_CONNS);
|
||||
if (conn != NULL)
|
||||
{
|
||||
for (ret = 0; ret < CONFIG_NET_ICMPv6_ALLOC_CONNS; ret++)
|
||||
{
|
||||
dq_addlast(&conn[ret].sconn.node,
|
||||
&g_free_icmpv6_connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = (FAR struct icmpv6_conn_s *)
|
||||
dq_remfirst(&g_free_icmpv6_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_icmpv6_connections);
|
||||
if (conn != NULL)
|
||||
{
|
||||
/* Enqueue the connection into the active list */
|
||||
|
@ -174,22 +144,9 @@ void icmpv6_free(FAR struct icmpv6_conn_s *conn)
|
|||
|
||||
dq_rem(&conn->sconn.node, &g_active_icmpv6_connections);
|
||||
|
||||
/* If this is a preallocated or a batch allocated connection store it in
|
||||
* the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection. */
|
||||
|
||||
#if CONFIG_NET_ICMPv6_ALLOC_CONNS == 1
|
||||
if (conn < g_icmpv6_connections || conn >= (g_icmpv6_connections +
|
||||
CONFIG_NET_ICMPv6_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
dq_addlast(&conn->sconn.node, &g_free_icmpv6_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_icmpv6_connections, conn);
|
||||
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
}
|
||||
|
|
|
@ -42,9 +42,18 @@
|
|||
|
||||
#include "devif/devif.h"
|
||||
#include "ieee802154/ieee802154.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
#ifdef CONFIG_NET_IEEE802154
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NET_IEEE802154_MAX_CONNS
|
||||
# define CONFIG_NET_IEEE802154_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
@ -53,14 +62,11 @@
|
|||
* network lock.
|
||||
*/
|
||||
|
||||
#if CONFIG_NET_IEEE802154_PREALLOC_CONNS > 0
|
||||
static struct ieee802154_conn_s
|
||||
g_ieee802154_connections[CONFIG_NET_IEEE802154_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free packet socket connections */
|
||||
|
||||
static dq_queue_t g_free_ieee802154_connections;
|
||||
NET_BUFPOOL_DECLARE(g_ieee802154_connections,
|
||||
sizeof(struct ieee802154_conn_s),
|
||||
CONFIG_NET_IEEE802154_PREALLOC_CONNS,
|
||||
CONFIG_NET_IEEE802154_ALLOC_CONNS,
|
||||
CONFIG_NET_IEEE802154_MAX_CONNS);
|
||||
|
||||
/* A list of all allocated packet socket connections */
|
||||
|
||||
|
@ -84,17 +90,7 @@ static dq_queue_t g_active_ieee802154_connections;
|
|||
|
||||
void ieee802154_conn_initialize(void)
|
||||
{
|
||||
#if CONFIG_NET_IEEE802154_PREALLOC_CONNS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_IEEE802154_PREALLOC_CONNS; i++)
|
||||
{
|
||||
/* Link each pre-allocated connection structure into the free list. */
|
||||
|
||||
dq_addlast(&g_ieee802154_connections[i].sconn.node,
|
||||
&g_free_ieee802154_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_ieee802154_connections);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -109,39 +105,12 @@ void ieee802154_conn_initialize(void)
|
|||
FAR struct ieee802154_conn_s *ieee802154_conn_alloc(void)
|
||||
{
|
||||
FAR struct ieee802154_conn_s *conn;
|
||||
#if CONFIG_NET_IEEE802154_ALLOC_CONNS > 0
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* The free list is protected by the network lock. */
|
||||
|
||||
net_lock();
|
||||
#if CONFIG_NET_IEEE802154_ALLOC_CONNS > 0
|
||||
if (dq_peek(&g_free_ieee802154_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_NET_IEEE802154_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_ieee802154_connections) +
|
||||
CONFIG_NET_IEEE802154_ALLOC_CONNS > CONFIG_NET_IEEE802154_MAX_CONNS)
|
||||
{
|
||||
net_unlock();
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(*conn) * CONFIG_NET_IEEE802154_ALLOC_CONNS);
|
||||
if (conn != NULL)
|
||||
{
|
||||
for (i = 0; i < CONFIG_NET_IEEE802154_ALLOC_CONNS; i++)
|
||||
{
|
||||
dq_addlast(&conn[i].sconn.node,
|
||||
&g_free_ieee802154_connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = (FAR struct ieee802154_conn_s *)
|
||||
dq_remfirst(&g_free_ieee802154_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_ieee802154_connections);
|
||||
if (conn)
|
||||
{
|
||||
dq_addlast(&conn->sconn.node, &g_active_ieee802154_connections);
|
||||
|
@ -195,22 +164,9 @@ void ieee802154_conn_free(FAR struct ieee802154_conn_s *conn)
|
|||
ieee802154_container_free(container);
|
||||
}
|
||||
|
||||
/* If this is a preallocated or a batch allocated connection store it in
|
||||
* the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection. */
|
||||
|
||||
#if CONFIG_NET_IEEE802154_ALLOC_CONNS == 1
|
||||
if (conn < g_ieee802154_connections || conn >= (g_ieee802154_connections +
|
||||
CONFIG_NET_IEEE802154_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
dq_addlast(&conn->sconn.node, &g_free_ieee802154_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_ieee802154_connections, conn);
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
|
|
|
@ -48,20 +48,23 @@
|
|||
|
||||
#ifdef CONFIG_NET_NETLINK
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NETLINK_MAX_CONNS
|
||||
# define CONFIG_NETLINK_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The array containing all NetLink connections. */
|
||||
|
||||
#if CONFIG_NETLINK_PREALLOC_CONNS > 0
|
||||
static struct netlink_conn_s
|
||||
g_netlink_connections[CONFIG_NETLINK_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free NetLink connections */
|
||||
|
||||
static dq_queue_t g_free_netlink_connections;
|
||||
NET_BUFPOOL_DECLARE(g_netlink_connections, sizeof(struct netlink_conn_s),
|
||||
CONFIG_NETLINK_PREALLOC_CONNS,
|
||||
CONFIG_NETLINK_ALLOC_CONNS, CONFIG_NETLINK_MAX_CONNS);
|
||||
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
|
||||
|
||||
/* A list of all allocated NetLink connections */
|
||||
|
@ -147,17 +150,7 @@ netlink_get_terminator(FAR const struct nlmsghdr *req)
|
|||
|
||||
void netlink_initialize(void)
|
||||
{
|
||||
#if CONFIG_NETLINK_PREALLOC_CONNS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NETLINK_PREALLOC_CONNS; i++)
|
||||
{
|
||||
/* Mark the connection closed and move it to the free list */
|
||||
|
||||
dq_addlast(&g_netlink_connections[i].sconn.node,
|
||||
&g_free_netlink_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_netlink_connections);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -172,38 +165,12 @@ void netlink_initialize(void)
|
|||
FAR struct netlink_conn_s *netlink_alloc(void)
|
||||
{
|
||||
FAR struct netlink_conn_s *conn;
|
||||
#if CONFIG_NETLINK_ALLOC_CONNS > 0
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* The free list is protected by a mutex. */
|
||||
|
||||
nxmutex_lock(&g_free_lock);
|
||||
#if CONFIG_NETLINK_ALLOC_CONNS > 0
|
||||
if (dq_peek(&g_free_netlink_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_NETLINK_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_netlink_connections) +
|
||||
CONFIG_NETLINK_ALLOC_CONNS > CONFIG_NETLINK_MAX_CONNS)
|
||||
{
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(*conn) * CONFIG_NETLINK_ALLOC_CONNS);
|
||||
if (conn != NULL)
|
||||
{
|
||||
for (i = 0; i < CONFIG_NETLINK_ALLOC_CONNS; i++)
|
||||
{
|
||||
dq_addlast(&conn[i].sconn.node, &g_free_netlink_connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = (FAR struct netlink_conn_s *)
|
||||
dq_remfirst(&g_free_netlink_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_netlink_connections);
|
||||
if (conn != NULL)
|
||||
{
|
||||
/* Enqueue the connection into the active list */
|
||||
|
@ -245,22 +212,9 @@ void netlink_free(FAR struct netlink_conn_s *conn)
|
|||
kmm_free(resp);
|
||||
}
|
||||
|
||||
/* If this is a preallocated or a batch allocated connection store it in
|
||||
* the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection */
|
||||
|
||||
#if CONFIG_NETLINK_ALLOC_CONNS == 1
|
||||
if (conn < g_netlink_connections || conn >= (g_netlink_connections +
|
||||
CONFIG_NETLINK_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
dq_addlast(&conn->sconn.node, &g_free_netlink_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_netlink_connections, conn);
|
||||
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "devif/devif.h"
|
||||
#include "pkt/pkt.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
@ -52,19 +53,19 @@
|
|||
(addr1[2] == addr2[2]) && (addr1[3] == addr2[3]) && \
|
||||
(addr1[4] == addr2[4]) && (addr1[5] == addr2[5]))
|
||||
|
||||
#ifndef CONFIG_NET_PKT_MAX_CONNS
|
||||
# define CONFIG_NET_PKT_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The array containing all packet socket connections */
|
||||
|
||||
#if CONFIG_NET_PKT_PREALLOC_CONNS > 0
|
||||
static struct pkt_conn_s g_pkt_connections[CONFIG_NET_PKT_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free packet socket connections */
|
||||
|
||||
static dq_queue_t g_free_pkt_connections;
|
||||
NET_BUFPOOL_DECLARE(g_pkt_connections, sizeof(struct pkt_conn_s),
|
||||
CONFIG_NET_PKT_PREALLOC_CONNS,
|
||||
CONFIG_NET_PKT_ALLOC_CONNS, CONFIG_NET_PKT_MAX_CONNS);
|
||||
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
|
||||
|
||||
/* A list of all allocated packet socket connections */
|
||||
|
@ -86,14 +87,7 @@ static dq_queue_t g_active_pkt_connections;
|
|||
|
||||
void pkt_initialize(void)
|
||||
{
|
||||
#if CONFIG_NET_PKT_PREALLOC_CONNS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_PKT_PREALLOC_CONNS; i++)
|
||||
{
|
||||
dq_addlast(&g_pkt_connections[i].sconn.node, &g_free_pkt_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_pkt_connections);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -108,37 +102,12 @@ void pkt_initialize(void)
|
|||
FAR struct pkt_conn_s *pkt_alloc(void)
|
||||
{
|
||||
FAR struct pkt_conn_s *conn;
|
||||
#if CONFIG_NET_PKT_ALLOC_CONNS > 0
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* The free list is protected by a mutex. */
|
||||
|
||||
nxmutex_lock(&g_free_lock);
|
||||
#if CONFIG_NET_PKT_ALLOC_CONNS > 0
|
||||
if (dq_peek(&g_free_pkt_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_NET_PKT_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_pkt_connections) +
|
||||
CONFIG_NET_PKT_ALLOC_CONNS > CONFIG_NET_PKT_MAX_CONNS)
|
||||
{
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(*conn) * CONFIG_NET_PKT_ALLOC_CONNS);
|
||||
if (conn != NULL)
|
||||
{
|
||||
for (i = 0; i < CONFIG_NET_PKT_ALLOC_CONNS; i++)
|
||||
{
|
||||
dq_addlast(&conn[i].sconn.node, &g_free_pkt_connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = (FAR struct pkt_conn_s *)dq_remfirst(&g_free_pkt_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_pkt_connections);
|
||||
if (conn)
|
||||
{
|
||||
/* Enqueue the connection into the active list */
|
||||
|
@ -171,22 +140,9 @@ void pkt_free(FAR struct pkt_conn_s *conn)
|
|||
|
||||
dq_rem(&conn->sconn.node, &g_active_pkt_connections);
|
||||
|
||||
/* If this is a preallocated or a batch allocated connection store it in
|
||||
* the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection. */
|
||||
|
||||
#if CONFIG_NET_PKT_ALLOC_CONNS == 1
|
||||
if (conn < g_pkt_connections || conn >= (g_pkt_connections +
|
||||
CONFIG_NET_PKT_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
dq_addlast(&conn->sconn.node, &g_free_pkt_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_pkt_connections, conn);
|
||||
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
}
|
||||
|
|
|
@ -73,19 +73,23 @@
|
|||
#include "netdev/netdev.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NET_TCP_MAX_CONNS
|
||||
# define CONFIG_NET_TCP_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The array containing all TCP connections. */
|
||||
|
||||
#if CONFIG_NET_TCP_PREALLOC_CONNS > 0
|
||||
static struct tcp_conn_s g_tcp_connections[CONFIG_NET_TCP_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free TCP connections */
|
||||
|
||||
static dq_queue_t g_free_tcp_connections;
|
||||
NET_BUFPOOL_DECLARE(g_tcp_connections, sizeof(struct tcp_conn_s),
|
||||
CONFIG_NET_TCP_PREALLOC_CONNS,
|
||||
CONFIG_NET_TCP_ALLOC_CONNS, CONFIG_NET_TCP_MAX_CONNS);
|
||||
|
||||
/* A list of all connected TCP connections */
|
||||
|
||||
|
@ -497,54 +501,6 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
|
|||
}
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_alloc_conn
|
||||
*
|
||||
* Description:
|
||||
* Find or allocate a free TCP/IP connection structure for use.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_TCP_ALLOC_CONNS > 0
|
||||
static FAR struct tcp_conn_s *tcp_alloc_conn(void)
|
||||
{
|
||||
FAR struct tcp_conn_s *conn;
|
||||
int i;
|
||||
|
||||
/* Return the entry from the head of the free list */
|
||||
|
||||
if (dq_peek(&g_free_tcp_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_NET_TCP_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_tcp_connections) +
|
||||
CONFIG_NET_TCP_ALLOC_CONNS > CONFIG_NET_TCP_MAX_CONNS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(struct tcp_conn_s) *
|
||||
CONFIG_NET_TCP_ALLOC_CONNS);
|
||||
if (conn == NULL)
|
||||
{
|
||||
return conn;
|
||||
}
|
||||
|
||||
/* Now initialize each connection structure */
|
||||
|
||||
for (i = 0; i < CONFIG_NET_TCP_ALLOC_CONNS; i++)
|
||||
{
|
||||
/* Mark the connection closed and move it to the free list */
|
||||
|
||||
conn[i].tcpstateflags = TCP_CLOSED;
|
||||
dq_addlast(&conn[i].sconn.node, &g_free_tcp_connections);
|
||||
}
|
||||
}
|
||||
|
||||
return (FAR struct tcp_conn_s *)dq_remfirst(&g_free_tcp_connections);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -650,17 +606,7 @@ int tcp_selectport(uint8_t domain,
|
|||
|
||||
void tcp_initialize(void)
|
||||
{
|
||||
#if CONFIG_NET_TCP_PREALLOC_CONNS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_TCP_PREALLOC_CONNS; i++)
|
||||
{
|
||||
/* Mark the connection closed and move it to the free list */
|
||||
|
||||
g_tcp_connections[i].tcpstateflags = TCP_CLOSED;
|
||||
dq_addlast(&g_tcp_connections[i].sconn.node, &g_free_tcp_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_tcp_connections);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -687,7 +633,7 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain)
|
|||
|
||||
/* Return the entry from the head of the free list */
|
||||
|
||||
conn = (FAR struct tcp_conn_s *)dq_remfirst(&g_free_tcp_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_tcp_connections);
|
||||
|
||||
#ifndef CONFIG_NET_SOLINGER
|
||||
/* Is the free list empty? */
|
||||
|
@ -760,21 +706,11 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain)
|
|||
* a new connection.
|
||||
*/
|
||||
|
||||
conn = (FAR struct tcp_conn_s *)
|
||||
dq_remfirst(&g_free_tcp_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_tcp_connections);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate the connect entry from heap */
|
||||
|
||||
#if CONFIG_NET_TCP_ALLOC_CONNS > 0
|
||||
if (conn == NULL)
|
||||
{
|
||||
conn = tcp_alloc_conn();
|
||||
}
|
||||
#endif
|
||||
|
||||
net_unlock();
|
||||
|
||||
/* Mark the connection allocated */
|
||||
|
@ -972,21 +908,9 @@ void tcp_free(FAR struct tcp_conn_s *conn)
|
|||
|
||||
conn->tcpstateflags = TCP_CLOSED;
|
||||
|
||||
/* If this is a preallocated or a batch allocated connection store it in
|
||||
* the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection structure */
|
||||
|
||||
#if CONFIG_NET_TCP_ALLOC_CONNS == 1
|
||||
if (conn < g_tcp_connections || conn >= (g_tcp_connections +
|
||||
CONFIG_NET_TCP_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
dq_addlast(&conn->sconn.node, &g_free_tcp_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_tcp_connections, conn);
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
|
|
|
@ -74,19 +74,23 @@
|
|||
#include "udp/udp.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NET_UDP_MAX_CONNS
|
||||
# define CONFIG_NET_UDP_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The array containing all UDP connections. */
|
||||
|
||||
#if CONFIG_NET_UDP_PREALLOC_CONNS > 0
|
||||
static struct udp_conn_s g_udp_connections[CONFIG_NET_UDP_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free UDP connections */
|
||||
|
||||
static dq_queue_t g_free_udp_connections;
|
||||
NET_BUFPOOL_DECLARE(g_udp_connections, sizeof(struct udp_conn_s),
|
||||
CONFIG_NET_UDP_PREALLOC_CONNS,
|
||||
CONFIG_NET_UDP_ALLOC_CONNS, CONFIG_NET_UDP_MAX_CONNS);
|
||||
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
|
||||
|
||||
/* A list of all allocated UDP connections */
|
||||
|
@ -460,54 +464,6 @@ udp_ipv6_active(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn,
|
|||
}
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: udp_alloc_conn
|
||||
*
|
||||
* Description:
|
||||
* Allocate a uninitialized UDP connection structure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_UDP_ALLOC_CONNS > 0
|
||||
static FAR struct udp_conn_s *udp_alloc_conn(void)
|
||||
{
|
||||
FAR struct udp_conn_s *conn;
|
||||
int i;
|
||||
|
||||
/* Return the entry from the head of the free list */
|
||||
|
||||
if (dq_peek(&g_free_udp_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_NET_UDP_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_udp_connections) +
|
||||
CONFIG_NET_UDP_ALLOC_CONNS > CONFIG_NET_UDP_MAX_CONNS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(struct udp_conn_s) *
|
||||
CONFIG_NET_UDP_ALLOC_CONNS);
|
||||
if (conn == NULL)
|
||||
{
|
||||
return conn;
|
||||
}
|
||||
|
||||
/* Now initialize each connection structure */
|
||||
|
||||
for (i = 0; i < CONFIG_NET_UDP_ALLOC_CONNS; i++)
|
||||
{
|
||||
/* Mark the connection closed and move it to the free list */
|
||||
|
||||
conn[i].lport = 0;
|
||||
dq_addlast(&conn[i].sconn.node, &g_free_udp_connections);
|
||||
}
|
||||
}
|
||||
|
||||
return (FAR struct udp_conn_s *)dq_remfirst(&g_free_udp_connections);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -593,17 +549,7 @@ errout:
|
|||
|
||||
void udp_initialize(void)
|
||||
{
|
||||
#if CONFIG_NET_UDP_PREALLOC_CONNS > 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_UDP_PREALLOC_CONNS; i++)
|
||||
{
|
||||
/* Mark the connection closed and move it to the free list */
|
||||
|
||||
g_udp_connections[i].lport = 0;
|
||||
dq_addlast(&g_udp_connections[i].sconn.node, &g_free_udp_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_udp_connections);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -623,14 +569,7 @@ FAR struct udp_conn_s *udp_alloc(uint8_t domain)
|
|||
|
||||
nxmutex_lock(&g_free_lock);
|
||||
|
||||
conn = (FAR struct udp_conn_s *)dq_remfirst(&g_free_udp_connections);
|
||||
|
||||
#if CONFIG_NET_UDP_ALLOC_CONNS > 0
|
||||
if (conn == NULL)
|
||||
{
|
||||
conn = udp_alloc_conn();
|
||||
}
|
||||
#endif
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_udp_connections);
|
||||
|
||||
if (conn)
|
||||
{
|
||||
|
@ -712,23 +651,9 @@ void udp_free(FAR struct udp_conn_s *conn)
|
|||
|
||||
#endif
|
||||
|
||||
/* Free the connection.
|
||||
* If this is a preallocated or a batch allocated connection store it in
|
||||
* the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection. */
|
||||
|
||||
#if CONFIG_NET_UDP_ALLOC_CONNS == 1
|
||||
if (conn < g_udp_connections || conn >= (g_udp_connections +
|
||||
CONFIG_NET_UDP_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
dq_addlast(&conn->sconn.node, &g_free_udp_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_udp_connections, conn);
|
||||
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,15 @@
|
|||
#include <nuttx/net/usrsock.h>
|
||||
|
||||
#include "usrsock/usrsock.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NET_USRSOCK_MAX_CONNS
|
||||
# define CONFIG_NET_USRSOCK_MAX_CONNS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
@ -50,14 +59,10 @@
|
|||
|
||||
/* The array containing all usrsock connections. */
|
||||
|
||||
#if CONFIG_NET_USRSOCK_PREALLOC_CONNS > 0
|
||||
static struct usrsock_conn_s
|
||||
g_usrsock_connections[CONFIG_NET_USRSOCK_PREALLOC_CONNS];
|
||||
#endif
|
||||
|
||||
/* A list of all free usrsock connections */
|
||||
|
||||
static dq_queue_t g_free_usrsock_connections;
|
||||
NET_BUFPOOL_DECLARE(g_usrsock_connections, sizeof(struct usrsock_conn_s),
|
||||
CONFIG_NET_USRSOCK_PREALLOC_CONNS,
|
||||
CONFIG_NET_USRSOCK_ALLOC_CONNS,
|
||||
CONFIG_NET_USRSOCK_MAX_CONNS);
|
||||
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
|
||||
|
||||
/* A list of all allocated usrsock connections */
|
||||
|
@ -80,38 +85,12 @@ static dq_queue_t g_active_usrsock_connections;
|
|||
FAR struct usrsock_conn_s *usrsock_alloc(void)
|
||||
{
|
||||
FAR struct usrsock_conn_s *conn;
|
||||
#if CONFIG_NET_USRSOCK_ALLOC_CONNS > 0
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* The free list is protected by a a mutex. */
|
||||
|
||||
nxmutex_lock(&g_free_lock);
|
||||
#if CONFIG_NET_USRSOCK_ALLOC_CONNS > 0
|
||||
if (dq_peek(&g_free_usrsock_connections) == NULL)
|
||||
{
|
||||
#if CONFIG_NET_USRSOCK_MAX_CONNS > 0
|
||||
if (dq_count(&g_active_usrsock_connections) +
|
||||
CONFIG_NET_USRSOCK_ALLOC_CONNS > CONFIG_NET_USRSOCK_MAX_CONNS)
|
||||
{
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = kmm_zalloc(sizeof(*conn) * CONFIG_NET_USRSOCK_ALLOC_CONNS);
|
||||
if (conn != NULL)
|
||||
{
|
||||
for (i = 0; i < CONFIG_NET_USRSOCK_ALLOC_CONNS; i++)
|
||||
{
|
||||
dq_addlast(&conn[i].sconn.node, &g_free_usrsock_connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn = (FAR struct usrsock_conn_s *)
|
||||
dq_remfirst(&g_free_usrsock_connections);
|
||||
conn = NET_BUFPOOL_TRYALLOC(g_usrsock_connections);
|
||||
if (conn)
|
||||
{
|
||||
/* Make sure that the connection is marked as uninitialized */
|
||||
|
@ -154,22 +133,9 @@ void usrsock_free(FAR struct usrsock_conn_s *conn)
|
|||
|
||||
nxsem_destroy(&conn->resp.sem);
|
||||
|
||||
/* If this is a preallocated or a batch allocated connection store it in
|
||||
* the free connections list. Else free it.
|
||||
*/
|
||||
/* Free the connection. */
|
||||
|
||||
#if CONFIG_NET_USRSOCK_ALLOC_CONNS == 1
|
||||
if (conn < g_usrsock_connections || conn >= (g_usrsock_connections +
|
||||
CONFIG_NET_USRSOCK_PREALLOC_CONNS))
|
||||
{
|
||||
kmm_free(conn);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
dq_addlast(&conn->sconn.node, &g_free_usrsock_connections);
|
||||
}
|
||||
NET_BUFPOOL_FREE(g_usrsock_connections, conn);
|
||||
|
||||
nxmutex_unlock(&g_free_lock);
|
||||
}
|
||||
|
@ -334,21 +300,7 @@ void usrsock_setup_datain(FAR struct usrsock_conn_s *conn,
|
|||
|
||||
void usrsock_initialize(void)
|
||||
{
|
||||
#if CONFIG_NET_USRSOCK_PREALLOC_CONNS > 0
|
||||
FAR struct usrsock_conn_s *conn;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_USRSOCK_PREALLOC_CONNS; i++)
|
||||
{
|
||||
conn = &g_usrsock_connections[i];
|
||||
|
||||
/* Mark the connection closed and move it to the free list */
|
||||
|
||||
conn->usockid = USRSOCK_USOCKID_INVALID;
|
||||
conn->state = USRSOCK_CONN_STATE_UNINITIALIZED;
|
||||
dq_addlast(&conn->sconn.node, &g_free_usrsock_connections);
|
||||
}
|
||||
#endif
|
||||
NET_BUFPOOL_INIT(g_usrsock_connections);
|
||||
|
||||
/* Register /dev/usrsock character device. */
|
||||
|
||||
|
|
|
@ -33,7 +33,8 @@ set(SRCS
|
|||
net_snoop.c
|
||||
net_cmsg.c
|
||||
net_iob_concat.c
|
||||
net_mask2pref.c)
|
||||
net_mask2pref.c
|
||||
net_bufpool.c)
|
||||
|
||||
# IPv6 utilities
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
NET_CSRCS += net_dsec2tick.c net_dsec2timeval.c net_timeval2dsec.c
|
||||
NET_CSRCS += net_chksum.c net_ipchksum.c net_incr32.c net_lock.c
|
||||
NET_CSRCS += net_snoop.c net_cmsg.c net_iob_concat.c net_mask2pref.c
|
||||
NET_CSRCS += net_bufpool.c
|
||||
|
||||
# IPv6 utilities
|
||||
|
||||
|
|
172
net/utils/net_bufpool.c
Normal file
172
net/utils/net_bufpool.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
/****************************************************************************
|
||||
* net/utils/net_bufpool.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
#include "utils/utils.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* The node to store in the pool */
|
||||
|
||||
struct net_bufnode_s
|
||||
{
|
||||
sq_entry_t node;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_bufpool_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize a network buffer pool.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pool - The pool to be initialized
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void net_bufpool_init(FAR struct net_bufpool_s *pool)
|
||||
{
|
||||
int i;
|
||||
unsigned int maxalloc;
|
||||
|
||||
if (pool->dynalloc > 0)
|
||||
{
|
||||
maxalloc = pool->u.maxalloc > 0 ? pool->u.maxalloc : INT16_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxalloc = pool->prealloc;
|
||||
}
|
||||
|
||||
nxsem_init(&pool->u.sem, 0, maxalloc);
|
||||
|
||||
sq_init(&pool->freebuffers);
|
||||
for (i = 0; i < pool->prealloc; i++)
|
||||
{
|
||||
FAR struct net_bufnode_s *node = (FAR struct net_bufnode_s *)
|
||||
(pool->pool + i * pool->nodesize);
|
||||
sq_addlast(&node->node, &pool->freebuffers);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_bufpool_timedalloc
|
||||
*
|
||||
* Description:
|
||||
* Allocate a buffer from the pool. If no buffer is available, then wait
|
||||
* for the specified timeout.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pool - The pool from which to allocate the buffer
|
||||
* timeout - The maximum time to wait for a buffer to become available.
|
||||
*
|
||||
* Returned Value:
|
||||
* A reference to the allocated buffer, which is guaranteed to be zeroed.
|
||||
* NULL is returned on a timeout.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *net_bufpool_timedalloc(FAR struct net_bufpool_s *pool,
|
||||
unsigned int timeout)
|
||||
{
|
||||
FAR struct net_bufnode_s *node;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = net_sem_timedwait_uninterruptible(&pool->u.sem, timeout);
|
||||
if (ret != OK)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If we get here, then we didn't exceed maxalloc. */
|
||||
|
||||
if (pool->dynalloc > 0 && sq_peek(&pool->freebuffers) == NULL)
|
||||
{
|
||||
node = kmm_zalloc(pool->nodesize * pool->dynalloc);
|
||||
if (node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Now initialize each connection structure */
|
||||
|
||||
for (i = 0; i < pool->dynalloc; i++)
|
||||
{
|
||||
sq_addlast(&node->node, &pool->freebuffers);
|
||||
node = (FAR struct net_bufnode_s *)
|
||||
((FAR char *)node + pool->nodesize);
|
||||
}
|
||||
}
|
||||
|
||||
return sq_remfirst(&pool->freebuffers);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_bufpool_free
|
||||
*
|
||||
* Description:
|
||||
* Free a buffer from the pool.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pool - The pool from which to allocate the buffer
|
||||
* node - The buffer to be freed
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void net_bufpool_free(FAR struct net_bufpool_s *pool, FAR void *node)
|
||||
{
|
||||
if (pool->dynalloc == 1 &&
|
||||
((FAR char *)node < pool->pool ||
|
||||
(FAR char *)node >= pool->pool + pool->prealloc * pool->nodesize))
|
||||
{
|
||||
kmm_free(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAR struct net_bufnode_s *net_bufnode = node;
|
||||
|
||||
/* Set the buffer to zero, to make sure all nodes in the free buffer
|
||||
* pool are zeroed.
|
||||
*/
|
||||
|
||||
memset(net_bufnode, 0, pool->nodesize);
|
||||
sq_addlast(&net_bufnode->node, &pool->freebuffers);
|
||||
}
|
||||
|
||||
nxsem_post(&pool->u.sem);
|
||||
}
|
|
@ -76,6 +76,33 @@
|
|||
(nport) = HTONS(hport); \
|
||||
} while (0)
|
||||
|
||||
/* Network buffer pool related macros, in which:
|
||||
* pool: The name of the buffer pool
|
||||
* nodesize: The size of each node in the pool
|
||||
* prealloc: The number of pre-allocated buffers
|
||||
* dynalloc: The number per dynamic allocations
|
||||
* maxalloc: The number of max allocations, 0 means no limit
|
||||
*/
|
||||
|
||||
#define NET_BUFPOOL_DECLARE(pool,nodesize,prealloc,dynalloc,maxalloc) \
|
||||
static char pool##_buffer[prealloc][nodesize]; \
|
||||
static struct net_bufpool_s pool = \
|
||||
{ \
|
||||
pool##_buffer[0], \
|
||||
prealloc, \
|
||||
dynalloc, \
|
||||
nodesize, \
|
||||
{ \
|
||||
maxalloc \
|
||||
} \
|
||||
};
|
||||
|
||||
#define NET_BUFPOOL_INIT(p) net_bufpool_init(&p)
|
||||
#define NET_BUFPOOL_TIMEDALLOC(p,t) net_bufpool_timedalloc(&p, t)
|
||||
#define NET_BUFPOOL_TRYALLOC(p) net_bufpool_timedalloc(&p, 0)
|
||||
#define NET_BUFPOOL_ALLOC(p) net_bufpool_timedalloc(&p, UINT_MAX)
|
||||
#define NET_BUFPOOL_FREE(p,n) net_bufpool_free(&p, n)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
@ -89,6 +116,26 @@ enum tv2ds_remainder_e
|
|||
TV2DS_CEIL /* Force to next larger full decisecond */
|
||||
};
|
||||
|
||||
/* This structure is used to manage a pool of network buffers */
|
||||
|
||||
struct net_bufpool_s
|
||||
{
|
||||
/* Allocation configuration */
|
||||
|
||||
FAR char *pool; /* The beginning of the pre-allocated buffer pool */
|
||||
const int prealloc; /* The number of pre-allocated buffers */
|
||||
const int dynalloc; /* The number per dynamic allocations */
|
||||
const int nodesize; /* The size of each node in the pool */
|
||||
|
||||
union
|
||||
{
|
||||
int16_t maxalloc; /* The number of max allocations, used before init */
|
||||
sem_t sem; /* The semaphore for waiting for free buffers */
|
||||
} u;
|
||||
|
||||
sq_queue_t freebuffers;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
@ -322,6 +369,53 @@ FAR void *net_ipv6_payload(FAR struct ipv6_hdr_s *ipv6, FAR uint8_t *proto);
|
|||
uint16_t net_iob_concat(FAR struct iob_s **iob1, FAR struct iob_s **iob2);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_bufpool_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize a network buffer pool.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pool - The pool to be initialized
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void net_bufpool_init(FAR struct net_bufpool_s *pool);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_bufpool_timedalloc
|
||||
*
|
||||
* Description:
|
||||
* Allocate a buffer from the pool. If no buffer is available, then wait
|
||||
* for the specified timeout.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pool - The pool from which to allocate the buffer
|
||||
* timeout - The maximum time to wait for a buffer to become available.
|
||||
*
|
||||
* Returned Value:
|
||||
* A reference to the allocated buffer, which is guaranteed to be zeroed.
|
||||
* NULL is returned on a timeout.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *net_bufpool_timedalloc(FAR struct net_bufpool_s *pool,
|
||||
unsigned int timeout);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_bufpool_free
|
||||
*
|
||||
* Description:
|
||||
* Free a buffer from the pool.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pool - The pool from which to allocate the buffer
|
||||
* node - The buffer to be freed
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void net_bufpool_free(FAR struct net_bufpool_s *pool, FAR void *node);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_chksum_adjust
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue