This commit adds an as-of-yet untested implemented of UDP write buffering.

Squashed commit of the following:

    net/udp:  Address most of the issues with UDP write buffering.  There is a remaining issue with handling one network going down in a multi-network environment.  None of this has been test but it is certainly ready for test.  Hence, the feature is marked EXPERIMENTAL.
    net/udp:  Some baby steps toward a corrected write buffering design.
    net/udp:  Remove pesky write buffer macros.
    Eliminate trailing space at the end of lines.
    net/udp:  A little more UDP write buffering logic.  Still at least on big gaping hole in the design.
    net/udp:  Undefined CONFIG_NET_SENDTO_TIMEOUT.
    net/udp:  Crude, naive port of the TCP write buffering logic into UDP.  This commit is certainly non-functional and is simply a starting point for the implementatin of UDP write buffering.
    net/udp:  Rename udp/udp_psock_sendto.c udp/udp_psock_sendto_unbuffered.c.
This commit is contained in:
Gregory Nutt
2018-01-22 18:32:02 -06:00
committed by Matt Thompson
parent 055a3ef844
commit 880176e1cb
15 changed files with 1354 additions and 22 deletions
+2 -2
View File
@@ -208,8 +208,8 @@ struct socket
FAR const struct sock_intf_s *s_sockif;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
/* Callback instance for TCP send */
#if defined(CONFIG_NET_TCP_WRITE_BUFFERS) || defined(CONFIG_NET_UDP_WRITE_BUFFERS)
/* Callback instance for TCP send() or UDP sendto() */
FAR struct devif_callback_s *s_sndcb;
#endif
+7 -7
View File
@@ -16,9 +16,9 @@ if MM_IOB
config IOB_NBUFFERS
int "Number of pre-allocated I/O buffers"
default 24 if (NET_TCP_WRITE_BUFFERS && !NET_TCP_READAHEAD) || (!NET_TCP_WRITE_BUFFERS && NET_TCP_READAHEAD)
default 36 if NET_TCP_WRITE_BUFFERS && NET_TCP_READAHEAD
default 8 if !NET_TCP_WRITE_BUFFERS && !NET_TCP_READAHEAD
default 24 if (NET_WRITE_BUFFERS && !NET_READAHEAD) || (!NET_WRITE_BUFFERS && NET_READAHEAD)
default 36 if NET_WRITE_BUFFERS && NET_READAHEAD
default 8 if !NET_WRITE_BUFFERS && !NET_READAHEAD
---help---
Each packet is represented by a series of small I/O buffers in a
chain. This setting determines the number of preallocated I/O
@@ -34,8 +34,8 @@ config IOB_BUFSIZE
config IOB_NCHAINS
int "Number of pre-allocated I/O buffer chain heads"
default 0 if !NET_TCP_READAHEAD && !NET_UDP_READAHEAD
default 8 if NET_TCP_READAHEAD || NET_UDP_READAHEAD
default 0 if !NET_READAHEAD && !NET_UDP_READAHEAD
default 8 if NET_READAHEAD || NET_UDP_READAHEAD
---help---
These tiny nodes are used as "containers" to support queueing of
I/O buffer chains. This will limit the number of I/O transactions
@@ -49,8 +49,8 @@ config IOB_NCHAINS
config IOB_THROTTLE
int "I/O buffer throttle value"
default 0 if !NET_TCP_WRITE_BUFFERS || !NET_TCP_READAHEAD
default 8 if NET_TCP_WRITE_BUFFERS && NET_TCP_READAHEAD
default 0 if !NET_WRITE_BUFFERS || !NET_READAHEAD
default 8 if NET_WRITE_BUFFERS && NET_READAHEAD
---help---
TCP write buffering and read-ahead buffer use the same pool of free
I/O buffers. In order to prevent uncontrolled incoming TCP packets
+8
View File
@@ -11,6 +11,14 @@ config ARCH_HAVE_PHY
bool
default n
config NET_WRITE_BUFFERS
bool
default n
config NET_READAHEAD
bool
default n
config NET
bool "Networking support"
default n
+1 -1
View File
@@ -1146,7 +1146,7 @@ static ssize_t inet_sendto(FAR struct socket *psock, FAR const void *buf,
#if defined(CONFIG_NET_6LOWPAN)
/* Try 6LoWPAN UDP packet sendto() */
nsent = psock_6lowpan_udp_sendto(psock, buf, len, flags, to, tolen);
nsent = psock_6lowpan_udp_sendto(psock, buf, len, flags, to, minlen);
#ifdef NET_UDP_HAVE_STACK
if (nsent < 0)
+4
View File
@@ -172,6 +172,10 @@ void net_setup(void)
/* Initialize the UDP connection structures */
udp_initialize();
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
udp_wrbuffer_initialize();
#endif
#endif
#ifdef CONFIG_NET_IGMP
+1 -1
View File
@@ -105,7 +105,7 @@ int psock_socket(int domain, int type, int protocol, FAR struct socket *psock)
psock->s_domain = domain;
psock->s_type = type;
psock->s_conn = NULL;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
#if defined(CONFIG_NET_TCP_WRITE_BUFFERS) || defined(CONFIG_NET_UDP_WRITE_BUFFERS)
psock->s_sndcb = NULL;
#endif
+3 -1
View File
@@ -70,6 +70,7 @@ config NET_MAX_LISTENPORTS
config NET_TCP_READAHEAD
bool "Enable TCP/IP read-ahead buffering"
default y
select NET_READAHEAD
select MM_IOB
---help---
Read-ahead buffers allows buffering of TCP/IP packets when there is no
@@ -91,6 +92,7 @@ endif # NET_TCP_READAHEAD
config NET_TCP_WRITE_BUFFERS
bool "Enable TCP/IP write buffering"
default n
select NET_WRITE_BUFFERS
select MM_IOB
---help---
Write buffers allows buffering of ongoing TCP/IP packets, providing
@@ -105,7 +107,7 @@ config NET_TCP_NWRBCHAINS
int "Number of pre-allocated I/O buffer chain heads"
default 8
---help---
These tiny nodes are used as "containers" to support queueing of
These tiny nodes are used as "containers" to support queuing of
TCP write buffers. This setting will limit the number of TCP write
operations that can be "in-flight" at any give time. So a good
choice for this value would be the same as the maximum number of
+50
View File
@@ -44,7 +44,57 @@ config NET_BROADCAST
config NET_UDP_READAHEAD
bool "Enable UDP/IP read-ahead buffering"
default y
select NET_READAHEAD
select MM_IOB
config NET_UDP_WRITE_BUFFERS
bool "Enable UDP/IP write buffering"
default n
select NET_WRITE_BUFFERS
select MM_IOB
depends on EXPERIMENTAL
---help---
Write buffers allows buffering of ongoing UDP/IP packets, providing
for higher performance, streamed output.
You might want to disable UDP/IP write buffering on a highly memory
memory constrained system where there are no performance issues.
if NET_UDP_WRITE_BUFFERS
config NET_UDP_NWRBCHAINS
int "Number of pre-allocated I/O buffer chain heads"
default 8
---help---
These tiny nodes are used as "containers" to support queuing of
UDP write buffers. This setting will limit the number of UDP write
operations that can be "in-flight" at any give time. So a good
choice for this value would be the same as the maximum number of
UDP connections.
config NET_UDP_WRBUFFER_DEBUG
bool "Force write buffer debug"
default n
depends on DEBUG_FEATURES
select IOB_DEBUG
---help---
This option will force debug output from UDP write buffer logic,
even without network debug output. This is not normally something
that would want to do but is convenient if you are debugging the
write buffer logic and do not want to get overloaded with other
network-related debug output.
config NET_UDP_WRBUFFER_DUMP
bool "Force write buffer dump"
default n
depends on DEBUG_NET || NET_UDP_WRBUFFER_DEBUG
select IOB_DEBUG
---help---
Dump the contents of the write buffers. You do not want to do this
unless you really want to analyze the write buffer transfers in
detail.
endif # NET_UDP_WRITE_BUFFERS
endif # NET_UDP && !NET_UDP_NO_STACK
endmenu # UDP Networking
+17 -2
View File
@@ -1,7 +1,7 @@
############################################################################
# net/udp/Make.defs
#
# Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
# Copyright (C) 2014-2015, 2018 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,13 @@ ifneq ($(CONFIG_NET_UDP_NO_STACK),y)
# Socket layer
NET_CSRCS += udp_psock_send.c udp_psock_sendto.c
NET_CSRCS += udp_psock_send.c
ifeq ($(CONFIG_NET_UDP_WRITE_BUFFERS),y)
SOCK_CSRCS += udp_psock_sendto_buffered.c
else
SOCK_CSRCS += udp_psock_sendto_unbuffered.c
endif
ifneq ($(CONFIG_DISABLE_POLL),y)
ifeq ($(CONFIG_NET_UDP_READAHEAD),y)
@@ -53,6 +59,15 @@ endif
NET_CSRCS += udp_conn.c udp_devpoll.c udp_send.c udp_input.c udp_finddev.c
NET_CSRCS += udp_callback.c udp_ipselect.c
# UDP write buffering
ifeq ($(CONFIG_NET_UDP_WRITE_BUFFERS),y)
NET_CSRCS += udp_wrbuffer.c
ifeq ($(CONFIG_DEBUG_FEATURES),y)
NET_CSRCS += udp_wrbuffer_dump.c
endif
endif
# Include UDP build support
DEPPATH += --dep-path udp
+127 -2
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* net/udp/udp.h
*
* Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2014-2015, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <queue.h>
#include <nuttx/clock.h>
#include <nuttx/net/ip.h>
#ifdef CONFIG_NET_UDP_READAHEAD
@@ -66,6 +67,17 @@
# define HAVE_UDP_POLL
#endif
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
/* UDP write buffer dump macros */
# ifdef CONFIG_DEBUG_FEATURES
# define UDPWB_DUMP(msg,wrb,len,offset) \
udp_wrbuffer_dump(msg,wrb,len,offset)
# else
# define UDPWB_DUMP(msg,wrb,len,offset)
# endif
#endif
/* Allocate a new UDP data callback */
#define udp_callback_alloc(dev,conn) \
@@ -102,11 +114,38 @@ struct udp_conn_s
struct iob_queue_s readahead; /* Read-ahead buffering */
#endif
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
/* Write buffering
*
* write_q - The queue of unsent I/O buffers. The head of this
* list may be partially sent. FIFO ordering.
*/
sq_queue_t write_q; /* Write buffering for UDP packets */
FAR struct net_driver_s *dev; /* Last device */
#endif
/* Defines the list of UDP callbacks */
FAR struct devif_callback_s *list;
};
/* This structure supports UDP write buffering. It is simply a container
* for a IOB list and associated destination address.
*/
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
struct udp_wrbuffer_s
{
sq_entry_t wb_node; /* Supports a singly linked list */
union ip_addr_u wb_dest; /* Destination address */
#ifdef CONFIG_NET_SOCKOPTS
systime_t wb_start; /* Start time for timeout calculation */
#endif
struct iob_s *wb_iob; /* Head of the I/O buffer chain */
};
#endif
/****************************************************************************
* Public Data
****************************************************************************/
@@ -291,6 +330,92 @@ void udp_poll(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn);
void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn);
/****************************************************************************
* Name: udp_wrbuffer_initialize
*
* Description:
* Initialize the list of free write buffers
*
* Assumptions:
* Called once early initialization.
*
****************************************************************************/
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
void udp_wrbuffer_initialize(void);
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
/****************************************************************************
* Name: udp_wrbuffer_alloc
*
* Description:
* Allocate a UDP write buffer by taking a pre-allocated buffer from
* the free list. This function is called from UDP logic when a buffer
* of UDP data is about to sent
*
* Input parameters:
* None
*
* Assumptions:
* Called from user logic with the network locked.
*
****************************************************************************/
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
struct udp_wrbuffer_s;
FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void);
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
/****************************************************************************
* Name: udp_wrbuffer_release
*
* Description:
* Release a UDP write buffer by returning the buffer to the free list.
* This function is called from user logic after it is consumed the
* buffered data.
*
* Assumptions:
* Called from network stack logic with the network stack locked
*
****************************************************************************/
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
void udp_wrbuffer_release(FAR struct udp_wrbuffer_s *wrb);
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
/****************************************************************************
* Name: udp_wrbuffer_test
*
* Description:
* Check if there is room in the write buffer. Does not reserve any space.
*
* Assumptions:
* None.
*
****************************************************************************/
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
int udp_wrbuffer_test(void);
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
/****************************************************************************
* Name: udp_wrbuffer_dump
*
* Description:
* Dump the contents of a write buffer.
*
****************************************************************************/
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
#ifdef CONFIG_DEBUG_FEATURES
void udp_wrbuffer_dump(FAR const char *msg, FAR struct udp_wrbuffer_s *wrb,
unsigned int len, unsigned int offset);
#else
# define udp_wrbuffer_dump(msg,wrb)
#endif
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
/****************************************************************************
* Name: udp_ipv4_input
*
@@ -495,7 +620,7 @@ int udp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds);
* Teardown monitoring of events on an UDP/IP socket
*
* Input Parameters:
* psock - The TCP/IP socket of interest
* psock - The UDP/IP socket of interest
* fds - The structure describing the events to be monitored, OR NULL if
* this is a request to stop monitoring events.
*
+20 -1
View File
@@ -1,7 +1,8 @@
/****************************************************************************
* net/udp/udp_conn.c
*
* Copyright (C) 2007-2009, 2011-2012, 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011-2012, 2016, 2018 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Large parts of this file were leveraged from uIP logic:
@@ -485,6 +486,11 @@ FAR struct udp_conn_s *udp_alloc(uint8_t domain)
conn->lport = 0;
conn->ttl = IP_TTL;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
/* Initialize the write buffer lists */
sq_init(&conn->write_q);
#endif
/* Enqueue the connection into the active list */
dq_addlast(&conn->node, &g_active_udp_connections);
@@ -505,6 +511,10 @@ FAR struct udp_conn_s *udp_alloc(uint8_t domain)
void udp_free(FAR struct udp_conn_s *conn)
{
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
FAR struct udp_wrbuffer_s *wrbuffer;
#endif
/* The free list is protected by a semaphore (that behaves like a mutex). */
DEBUGASSERT(conn->crefs == 0);
@@ -522,6 +532,15 @@ void udp_free(FAR struct udp_conn_s *conn)
iob_free_queue(&conn->readahead);
#endif
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
/* Release any write buffers attached to the connection */
while ((wrbuffer = (struct udp_wrbuffer_s *)sq_remfirst(&conn->write_q)) != NULL)
{
udp_wrbuffer_release(wrbuffer);
}
#endif
/* Free the connection */
dq_addlast(&conn->node, &g_free_udp_connections);
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,8 @@
/****************************************************************************
* net/udp/udp_psock_sendto.c
* net/udp/udp_psock_sendto_unbuffered.c
*
* Copyright (C) 2007-2009, 2011-2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011-2016, 2018 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -94,7 +95,7 @@ struct sendto_s
****************************************************************************/
/****************************************************************************
* Name: send_timeout
* Name: sendto_timeout
*
* Description:
* Check for send timeout.
@@ -111,7 +112,7 @@ struct sendto_s
****************************************************************************/
#ifdef CONFIG_NET_SOCKOPTS
static inline int send_timeout(FAR struct sendto_s *pstate)
static inline int sendto_timeout(FAR struct sendto_s *pstate)
{
FAR struct socket *psock;
@@ -235,7 +236,7 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
*/
#ifdef CONFIG_NET_SOCKOPTS
if (send_timeout(pstate))
if (sendto_timeout(pstate))
{
/* Yes.. report the timeout */
+217
View File
@@ -0,0 +1,217 @@
/****************************************************************************
* net/udp/udp_wrbuffer.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/net/netconfig.h>
#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP) && defined(CONFIG_NET_UDP_WRITE_BUFFERS)
#if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_NET_UDP_WRBUFFER_DEBUG)
/* Force debug output (from this file only) */
# undef CONFIG_DEBUG_NET
# define CONFIG_DEBUG_NET 1
#endif
#include <queue.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/semaphore.h>
#include <nuttx/net/net.h>
#include <nuttx/mm/iob.h>
#include "udp/udp.h"
/****************************************************************************
* Private Types
****************************************************************************/
/* Package all globals used by this logic into a structure */
struct wrbuffer_s
{
/* The semaphore to protect the buffers */
sem_t sem;
/* This is the list of available write buffers */
sq_queue_t freebuffers;
/* These are the pre-allocated write buffers */
struct udp_wrbuffer_s buffers[CONFIG_NET_UDP_NWRBCHAINS];
};
/****************************************************************************
* Private Data
****************************************************************************/
/* This is the state of the global write buffer resource */
static struct wrbuffer_s g_wrbuffer;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: udp_wrbuffer_initialize
*
* Description:
* Initialize the list of free write buffers
*
* Assumptions:
* Called once early initialization.
*
****************************************************************************/
void udp_wrbuffer_initialize(void)
{
int i;
sq_init(&g_wrbuffer.freebuffers);
for (i = 0; i < CONFIG_NET_UDP_NWRBCHAINS; i++)
{
sq_addfirst(&g_wrbuffer.buffers[i].wb_node, &g_wrbuffer.freebuffers);
}
nxsem_init(&g_wrbuffer.sem, 0, CONFIG_NET_UDP_NWRBCHAINS);
}
/****************************************************************************
* Name: udp_wrbuffer_alloc
*
* Description:
* Allocate a UDP write buffer by taking a pre-allocated buffer from
* the free list. This function is called from UDP logic when a buffer
* of UDP data is about to sent
*
* Input parameters:
* None
*
* Assumptions:
* Called from user logic with the network locked.
*
****************************************************************************/
FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void)
{
FAR struct udp_wrbuffer_s *wrb;
/* We need to allocate two things: (1) A write buffer structure and (2)
* at least one I/O buffer to start the chain.
*
* Allocate the write buffer structure first then the IOBG. In order to
* avoid deadlocks, we will need to free the IOB first, then the write
* buffer
*/
DEBUGVERIFY(net_lockedwait(&g_wrbuffer.sem)); /* TODO: Handle EINTR. */
/* Now, we are guaranteed to have a write buffer structure reserved
* for us in the free list.
*/
wrb = (FAR struct udp_wrbuffer_s *)sq_remfirst(&g_wrbuffer.freebuffers);
DEBUGASSERT(wrb);
memset(wrb, 0, sizeof(struct udp_wrbuffer_s));
/* Now get the first I/O buffer for the write buffer structure */
wrb->wb_iob = iob_alloc(false);
if (!wrb->wb_iob)
{
nerr("ERROR: Failed to allocate I/O buffer\n");
udp_wrbuffer_release(wrb);
return NULL;
}
return wrb;
}
/****************************************************************************
* Name: udp_wrbuffer_release
*
* Description:
* Release a UDP write buffer by returning the buffer to the free list.
* This function is called from user logic after it is consumed the
* buffered data.
*
* Assumptions:
* This function must be called with the network locked.
*
****************************************************************************/
void udp_wrbuffer_release(FAR struct udp_wrbuffer_s *wrb)
{
DEBUGASSERT(wrb && wrb->wb_iob);
/* To avoid deadlocks, we must following this ordering: Release the I/O
* buffer chain first, then the write buffer structure.
*/
iob_free_chain(wrb->wb_iob);
/* Then free the write buffer structure */
sq_addlast(&wrb->wb_node, &g_wrbuffer.freebuffers);
nxsem_post(&g_wrbuffer.sem);
}
/****************************************************************************
* Name: udp_wrbuffer_test
*
* Description:
* Check if there is room in the write buffer. Does not reserve any space.
*
* Assumptions:
* None.
*
****************************************************************************/
int udp_wrbuffer_test(void)
{
int val = 0;
nxsem_getvalue(&g_wrbuffer.sem, &val);
return val > 0 ? OK : ERROR;
}
#endif /* CONFIG_NET && CONFIG_NET_UDP && CONFIG_NET_UDP_WRITE_BUFFERS */
+70
View File
@@ -0,0 +1,70 @@
/****************************************************************************
* net/udp/udp_wrbuffer_dump.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <debug.h>
#include <nuttx/mm/iob.h>
#include "udp/udp.h"
#ifdef CONFIG_DEBUG_FEATURES
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: udp_wrbuffer_dump
*
* Description:
* Dump the contents of a write buffer
*
****************************************************************************/
void udp_wrbuffer_dump(FAR const char *msg, FAR struct udp_wrbuffer_s *wrb,
unsigned int len, unsigned int offset)
{
syslog(LOG_DEBUG, "%s: wrb=%p pktlen=%d\n", msg, wrb, wrb->wb_iob->io_pktlen);
iob_dump("I/O Buffer Chain", wrb->wb_iob, len, offset);
}
#endif /* CONFIG_DEBUG_FEATURES */