diff --git a/net/bluetooth/bluetooth_conn.c b/net/bluetooth/bluetooth_conn.c index f649943bd46..ad529326b64 100644 --- a/net/bluetooth/bluetooth_conn.c +++ b/net/bluetooth/bluetooth_conn.c @@ -42,10 +42,19 @@ #include #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(); } diff --git a/net/can/can_conn.c b/net/can/can_conn.c index 89be629af56..6f26bab4c87 100644 --- a/net/can/can_conn.c +++ b/net/can/can_conn.c @@ -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); } diff --git a/net/devif/devif_callback.c b/net/devif/devif_callback.c index ecd82836677..6f451a2b381 100644 --- a/net/devif/devif_callback.c +++ b/net/devif/devif_callback.c @@ -39,6 +39,7 @@ #include #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. */ diff --git a/net/icmp/icmp_conn.c b/net/icmp/icmp_conn.c index a4eac7cd3a8..3fb3d1938ce 100644 --- a/net/icmp/icmp_conn.c +++ b/net/icmp/icmp_conn.c @@ -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); diff --git a/net/icmpv6/icmpv6_conn.c b/net/icmpv6/icmpv6_conn.c index ac3d65a4dbc..228f83e8d5e 100644 --- a/net/icmpv6/icmpv6_conn.c +++ b/net/icmpv6/icmpv6_conn.c @@ -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); } diff --git a/net/ieee802154/ieee802154_conn.c b/net/ieee802154/ieee802154_conn.c index d30f05c14ba..46e7ff7047a 100644 --- a/net/ieee802154/ieee802154_conn.c +++ b/net/ieee802154/ieee802154_conn.c @@ -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(); } diff --git a/net/netlink/netlink_conn.c b/net/netlink/netlink_conn.c index 0a1b5f71da3..dddb52bd5cd 100644 --- a/net/netlink/netlink_conn.c +++ b/net/netlink/netlink_conn.c @@ -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); } diff --git a/net/pkt/pkt_conn.c b/net/pkt/pkt_conn.c index 601dff89f39..8856acb5bb1 100644 --- a/net/pkt/pkt_conn.c +++ b/net/pkt/pkt_conn.c @@ -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); } diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index 2cc05157f5b..d8bc2eda91f 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -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(); } diff --git a/net/udp/udp_conn.c b/net/udp/udp_conn.c index 83a13e725ec..d2062b46aec 100644 --- a/net/udp/udp_conn.c +++ b/net/udp/udp_conn.c @@ -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); } diff --git a/net/usrsock/usrsock_conn.c b/net/usrsock/usrsock_conn.c index c87703d915a..496f248d35a 100644 --- a/net/usrsock/usrsock_conn.c +++ b/net/usrsock/usrsock_conn.c @@ -43,6 +43,15 @@ #include #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. */ diff --git a/net/utils/CMakeLists.txt b/net/utils/CMakeLists.txt index 8803381a3dc..a960501fdbd 100644 --- a/net/utils/CMakeLists.txt +++ b/net/utils/CMakeLists.txt @@ -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 diff --git a/net/utils/Make.defs b/net/utils/Make.defs index de2d96a28a8..a279cd22151 100644 --- a/net/utils/Make.defs +++ b/net/utils/Make.defs @@ -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 diff --git a/net/utils/net_bufpool.c b/net/utils/net_bufpool.c new file mode 100644 index 00000000000..283f2748da6 --- /dev/null +++ b/net/utils/net_bufpool.c @@ -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 + +#include +#include +#include + +#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); +} diff --git a/net/utils/utils.h b/net/utils/utils.h index d5355d03d8d..4bd59159c80 100644 --- a/net/utils/utils.h +++ b/net/utils/utils.h @@ -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 *