diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-06-06 09:35:31 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-06-06 09:35:31 -0600 |
commit | 34c0b633c6530b8e7fce5479a5d0d41cd10b10cb (patch) | |
tree | 7ca3bf869409dd7665b31d5f7ff18fe42863c77b /nuttx/net/iob | |
parent | c7395ffbde4fb05be4f9f7dae07d2e3bb67c3438 (diff) | |
download | px4-nuttx-34c0b633c6530b8e7fce5479a5d0d41cd10b10cb.tar.gz px4-nuttx-34c0b633c6530b8e7fce5479a5d0d41cd10b10cb.tar.bz2 px4-nuttx-34c0b633c6530b8e7fce5479a5d0d41cd10b10cb.zip |
IOB: Add queue handling interfaces; improve lists
Diffstat (limited to 'nuttx/net/iob')
-rw-r--r-- | nuttx/net/iob/Kconfig | 8 | ||||
-rw-r--r-- | nuttx/net/iob/Make.defs | 8 | ||||
-rw-r--r-- | nuttx/net/iob/iob.h | 32 | ||||
-rw-r--r-- | nuttx/net/iob/iob_add_queue.c | 104 | ||||
-rw-r--r-- | nuttx/net/iob/iob_alloc.c | 36 | ||||
-rw-r--r-- | nuttx/net/iob/iob_alloc_qentry.c (renamed from nuttx/net/iob/iob_freeq.c) | 43 | ||||
-rw-r--r-- | nuttx/net/iob/iob_clone.c | 9 | ||||
-rw-r--r-- | nuttx/net/iob/iob_concat.c | 7 | ||||
-rw-r--r-- | nuttx/net/iob/iob_copyin.c | 7 | ||||
-rw-r--r-- | nuttx/net/iob/iob_copyout.c | 5 | ||||
-rw-r--r-- | nuttx/net/iob/iob_free.c | 17 | ||||
-rw-r--r-- | nuttx/net/iob/iob_free_chain.c (renamed from nuttx/net/iob/iob_freechain.c) | 35 | ||||
-rw-r--r-- | nuttx/net/iob/iob_free_qentry.c | 96 | ||||
-rw-r--r-- | nuttx/net/iob/iob_free_queue.c | 114 | ||||
-rw-r--r-- | nuttx/net/iob/iob_initialize.c | 35 | ||||
-rw-r--r-- | nuttx/net/iob/iob_pack.c | 7 | ||||
-rw-r--r-- | nuttx/net/iob/iob_remove_queue.c | 94 | ||||
-rw-r--r-- | nuttx/net/iob/iob_test.c | 39 | ||||
-rw-r--r-- | nuttx/net/iob/iob_trimhead.c | 6 | ||||
-rw-r--r-- | nuttx/net/iob/iob_trimtail.c | 7 |
20 files changed, 571 insertions, 138 deletions
diff --git a/nuttx/net/iob/Kconfig b/nuttx/net/iob/Kconfig index 0a5c8522a..a82e1c174 100644 --- a/nuttx/net/iob/Kconfig +++ b/nuttx/net/iob/Kconfig @@ -28,4 +28,12 @@ config IOB_BUFSIZE chain. This setting determines the data payload each preallocated I/O buffer. +config IOB_NCHAINS + int "Number of pre-allocated I/O buffer chain heads" + default 8 + ---help--- + These tiny nodes are used as "containers" to suppor queueing of + I/O buffer chains. This will limit the number of I/O transactions + that can be "in-flight" at any give time. + endif # NET_IOB diff --git a/nuttx/net/iob/Make.defs b/nuttx/net/iob/Make.defs index f70b7821a..9ad9b871b 100644 --- a/nuttx/net/iob/Make.defs +++ b/nuttx/net/iob/Make.defs @@ -40,9 +40,11 @@ ifeq ($(CONFIG_NET_IOB),y) # Include IOB src files -NET_CSRCS += iob_alloc.c iob_clone.c iob_concat.c iob_copyin.c iob_copyout.c -NET_CSRCS += iob_free.c iob_freechain.c iob_freeq.c iob_initialize.c -NET_CSRCS += iob_pack.c iob_trimhead.c iob_trimtail.c +NET_CSRCS += iob_add_queue.c iob_alloc.c iob_alloc_qentry.c iob_clone.c +NET_CSRCS += iob_concat.c iob_copyin.c iob_copyout.c iob_free.c +NET_CSRCS += iob_free_chain.c iob_free_qentry.c iob_free_queue.c +NET_CSRCS += iob_initialize.c iob_pack.c iob_remove_queue.c iob_trimhead.c +NET_CSRCS += iob_trimtail.c # Include iob build support diff --git a/nuttx/net/iob/iob.h b/nuttx/net/iob/iob.h index 1a6fe540c..0507fa34d 100644 --- a/nuttx/net/iob/iob.h +++ b/nuttx/net/iob/iob.h @@ -42,8 +42,6 @@ #include <nuttx/config.h> -#include <queue.h> - #include <nuttx/net/iob.h> /**************************************************************************** @@ -58,13 +56,13 @@ * Public Data ****************************************************************************/ -/* This is a pool of pre-allocated I/O buffers */ +/* A list of all free, unallocated I/O buffers */ -extern struct iob_s g_iob_pool[CONFIG_IOB_NBUFFERS]; +extern FAR struct iob_s *g_iob_freelist; -/* A list of all free, unallocated I/O buffers */ +/* A list of all free, unallocated I/O buffer queue containers */ -extern sq_queue_t g_iob_freelist; +extern FAR struct iob_qentry_s *g_iob_freeqlist; /**************************************************************************** * Public Data @@ -74,5 +72,27 @@ extern sq_queue_t g_iob_freelist; * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Name: iob_alloc_qentry + * + * Description: + * Allocate an I/O buffer chain container by taking the buffer at the head + * of the free list. This function is intended only for internal use by + * the IOB module. + * + ****************************************************************************/ + +FAR struct iob_qentry_s *iob_alloc_qentry(void); + +/**************************************************************************** + * Name: iob_free_qentry + * + * Description: + * Free the I/O buffer chain container by returning it to the free list. + * The link to the next I/O buffer in the chain is return. + * + ****************************************************************************/ + +FAR struct iob_qentry_s *iob_free_qentry(FAR struct iob_qentry_s *iobq); #endif /* __NET_IOB_IOB_H */ diff --git a/nuttx/net/iob/iob_add_queue.c b/nuttx/net/iob/iob_add_queue.c new file mode 100644 index 000000000..0a2ac3d0a --- /dev/null +++ b/nuttx/net/iob/iob_add_queue.c @@ -0,0 +1,104 @@ +/**************************************************************************** + * net/iob/iob_add_queue.c + * + * Copyright (C) 2014 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 <assert.h> +#include <errno.h> +#include <debug.h> + +#include <nuttx/net/iob.h> + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef NULL +# define NULL ((FAR void *)0) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_add_queue + * + * Description: + * Add one I/O buffer chain to the end of a queue. May fail due to lack + * of resources. + * + ****************************************************************************/ + +int iob_add_queue(FAR struct iob_s *iob, FAR struct iob_queue_s *iobq) +{ + FAR struct iob_qentry_s *qentry; + + /* Allocate a container to hold the I/O buffer chain */ + + qentry = iob_alloc_qentry(); + if (!qentry) + { + ndbg("ERROR: Failed to allocate a container\n"); + return -ENOMEM; + } + + /* Add the I/O buffer chain to the container */ + + qentry->qe_head = iob; + + /* Add the container to the end of the queue */ + + qentry->qe_flink = NULL; + if (!iobq->qh_head) + { + iobq->qh_head = qentry; + iobq->qh_tail = qentry; + } + else + { + DEBUGASSERT(iobq->qh_tail); + iobq->qh_tail->qe_flink = qentry; + iobq->qh_tail = qentry; + } + + return 0; +} diff --git a/nuttx/net/iob/iob_alloc.c b/nuttx/net/iob/iob_alloc.c index a3c1bc64a..39c7d5f1c 100644 --- a/nuttx/net/iob/iob_alloc.c +++ b/nuttx/net/iob/iob_alloc.c @@ -39,8 +39,7 @@ #include <nuttx/config.h> -#include <queue.h> - +#include <nuttx/arch.h> #include <nuttx/net/iob.h> #include "iob.h" @@ -69,24 +68,39 @@ * Name: iob_alloc * * Description: - * Allocate an I/O buffer by take the buffer at the head of the free list. + * Allocate an I/O buffer by taking the buffer at the head of the free list. * ****************************************************************************/ FAR struct iob_s *iob_alloc(void) { FAR struct iob_s *iob; + irqstate_t flags; + + /* We don't know what context we are called from so we use extreme measures + * to protect the free list: We disable interrupts very briefly. + */ - iob = (FAR struct iob_s *)sq_remfirst(&g_iob_freelist); + flags = irqsave(); + iob = g_iob_freelist; if (iob) { - iob->io_link.flink = NULL; /* Not in a chain */ - iob->io_flags = 0; /* Flags associated with the I/O buffer */ - iob->io_len = 0; /* Length of the data in the entry */ - iob->io_offset = 0; /* Offset to the beginning of data */ - iob->io_pktlen = 0; /* Total length of the packet */ - iob->io_priv = NULL; /* User private data attached to the I/O buffer */ + /* Remove the I/O buffer from the free list */ + + g_iob_freelist = iob->io_flink; + irqrestore(flags); + + /* Put the I/O buffer in a known state */ + + iob->io_flink = NULL; /* Not in a chain */ + iob->io_flags = 0; /* Flags associated with the I/O buffer */ + iob->io_len = 0; /* Length of the data in the entry */ + iob->io_offset = 0; /* Offset to the beginning of data */ + iob->io_pktlen = 0; /* Total length of the packet */ + iob->io_priv = NULL; /* User private data attached to the I/O buffer */ + return iob; } - return iob; + irqrestore(flags); + return NULL; } diff --git a/nuttx/net/iob/iob_freeq.c b/nuttx/net/iob/iob_alloc_qentry.c index 12eb8021e..0c29fbec1 100644 --- a/nuttx/net/iob/iob_freeq.c +++ b/nuttx/net/iob/iob_alloc_qentry.c @@ -1,5 +1,5 @@ /**************************************************************************** - * net/iob/iob_freeq.c + * net/iob/iob_alloc_qentry.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> @@ -39,8 +39,7 @@ #include <nuttx/config.h> -#include <queue.h> - +#include <nuttx/arch.h> #include <nuttx/net/iob.h> #include "iob.h" @@ -66,35 +65,37 @@ ****************************************************************************/ /**************************************************************************** - * Name: iob_freeq + * Name: iob_alloc_qentry * * Description: - * Free an entire buffer chain, starting at a queue head + * Allocate an I/O buffer chain container by taking the buffer at the head + * of the free list. This function is intended only for internal use by + * the IOB module. * ****************************************************************************/ -void iob_freeq(FAR sq_queue_t *q) +FAR struct iob_qentry_s *iob_alloc_qentry(void) { - /* If the free list is empty, then just move the entry queue to the free - * list. Otherwise, append the list to the end of the free list. + FAR struct iob_qentry_s *iobq; + irqstate_t flags; + + /* We don't know what context we are called from so we use extreme measures + * to protect the free list: We disable interrupts very briefly. */ - if (g_iob_freelist.tail) - { - g_iob_freelist.tail->flink = q->head; - } - else + flags = irqsave(); + iobq = g_iob_freeqlist; + if (iobq) { - g_iob_freelist.head = q->head; - } + /* Remove the I/O buffer chain container from the free list */ - /* In either case, the tail of the queue is the tail of queue becomes the - * tail of the free list. - */ + g_iob_freeqlist = iobq->qe_flink; - g_iob_freelist.tail = q->tail; + /* Put the I/O buffer in a known state */ - /* Reset the queue to empty */ + iobq->qe_head = NULL; /* Nothing is contained */ + } - sq_init(q); + irqrestore(flags); + return iobq; } diff --git a/nuttx/net/iob/iob_clone.c b/nuttx/net/iob/iob_clone.c index 0ba98f9f2..c44daffc7 100644 --- a/nuttx/net/iob/iob_clone.c +++ b/nuttx/net/iob/iob_clone.c @@ -40,7 +40,6 @@ #include <nuttx/config.h> #include <string.h> -#include <queue.h> #include <assert.h> #include <errno.h> #include <debug.h> @@ -92,7 +91,7 @@ int iob_clone(FAR struct iob_s *iob1, FAR struct iob_s *iob2) unsigned int offset2; DEBUGASSERT(iob2->io_len == 0 && iob2->io_offset == 0 && - iob2->io_pktlen == 0 && iob2->io_link.flink == NULL); + iob2->io_pktlen == 0 && iob2->io_flink == NULL); /* Copy the header information */ @@ -106,7 +105,7 @@ int iob_clone(FAR struct iob_s *iob1, FAR struct iob_s *iob2) while (iob1->io_len <= 0) { - iob1 = (FAR struct iob_s *)iob1->io_link.flink; + iob1 = iob1->io_flink; } /* Pack each entry from iob1 to iob2 */ @@ -152,7 +151,7 @@ int iob_clone(FAR struct iob_s *iob1, FAR struct iob_s *iob2) { /* Yes.. move to the next source I/O buffer */ - iob1 = (FAR struct iob_s *)iob1->io_link.flink; + iob1 = iob1->io_flink; } while (iob1->io_len <= 0); @@ -180,7 +179,7 @@ int iob_clone(FAR struct iob_s *iob1, FAR struct iob_s *iob2) return -ENOMEM; } - iob2->io_link.flink = &next->io_link; + iob2->io_flink = next; iob2 = next; offset2 = 0; } diff --git a/nuttx/net/iob/iob_concat.c b/nuttx/net/iob/iob_concat.c index 1e2620615..9ca09b1d9 100644 --- a/nuttx/net/iob/iob_concat.c +++ b/nuttx/net/iob/iob_concat.c @@ -40,7 +40,6 @@ #include <nuttx/config.h> #include <string.h> -#include <queue.h> #include <nuttx/net/iob.h> @@ -78,14 +77,14 @@ void iob_concat(FAR struct iob_s *iob1, FAR struct iob_s *iob2) { /* Find the last buffer in the iob1 buffer chain */ - while (iob1->io_link.flink) + while (iob1->io_flink) { - iob1 = (FAR struct iob_s *)iob1->io_link.flink; + iob1 = iob1->io_flink; } /* Then connect iob2 buffer chain to the end of the iob1 chain */ - iob1->io_link.flink = iob2->io_link.flink; + iob1->io_flink = iob2; /* Combine the total packet size. flags, VLAN, tags, and private * data from iob2 are lost. diff --git a/nuttx/net/iob/iob_copyin.c b/nuttx/net/iob/iob_copyin.c index 48129af0c..0c9b3f037 100644 --- a/nuttx/net/iob/iob_copyin.c +++ b/nuttx/net/iob/iob_copyin.c @@ -41,7 +41,6 @@ #include <stdint.h> #include <string.h> -#include <queue.h> #include <errno.h> #include <assert.h> #include <debug.h> @@ -108,14 +107,14 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src, while (offset > iob->io_len) { offset -= iob->io_len; - iob = (FAR struct iob_s *)iob->io_link.flink; + iob = iob->io_flink; } /* Then loop until all of the I/O data is copied from the user buffer */ while (len > 0) { - next = (FAR struct iob_s *)iob->io_link.flink; + next = iob->io_flink; /* Get the destination I/O buffer address and the amount of data * available from that address. @@ -204,7 +203,7 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src, /* Add the new, empty I/O buffer to the end of the buffer chain. */ - iob->io_link.flink = &next->io_link; + iob->io_flink = next; } iob = next; diff --git a/nuttx/net/iob/iob_copyout.c b/nuttx/net/iob/iob_copyout.c index 4afab2616..5695eb2e9 100644 --- a/nuttx/net/iob/iob_copyout.c +++ b/nuttx/net/iob/iob_copyout.c @@ -42,7 +42,6 @@ #include <stdint.h> #include <string.h> #include <assert.h> -#include <queue.h> #include <nuttx/net/iob.h> @@ -94,7 +93,7 @@ int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob, while (offset >= iob->io_len) { offset -= iob->io_len; - iob = (FAR struct iob_s *)iob->io_link.flink; + iob = iob->io_flink; } /* Then loop until all of the I/O data is copied to the user buffer */ @@ -123,7 +122,7 @@ int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob, /* Skip to the next I/O buffer in the chain */ - iob = (FAR struct iob_s *)iob->io_link.flink; + iob = iob->io_flink; offset = 0; } diff --git a/nuttx/net/iob/iob_free.c b/nuttx/net/iob/iob_free.c index 3cebb099a..e92bf1937 100644 --- a/nuttx/net/iob/iob_free.c +++ b/nuttx/net/iob/iob_free.c @@ -39,9 +39,9 @@ #include <nuttx/config.h> -#include <queue.h> #include <assert.h> +#include <nuttx/arch.h> #include <nuttx/net/iob.h> #include "iob.h" @@ -77,7 +77,8 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob) { - FAR struct iob_s *next = (FAR struct iob_s *)iob->io_link.flink; + FAR struct iob_s *next = iob->io_flink; + irqstate_t flags; /* Copy the data that only exists in the head of a I/O buffer chain into * the next entry. @@ -108,13 +109,19 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob) */ next->io_pktlen = 0; - DEBUGASSERT(next->io_len == 0 && next->io_link.flink == NULL); + DEBUGASSERT(next->io_len == 0 && next->io_flink == NULL); } } - /* Free the I/O buffer by adding to the end of the free list */ + /* Free the I/O buffer by adding it to the head of the free list. We don't + * know what context we are called from so we use extreme measures to + * protect the free list: We disable interrupts very briefly. + */ - sq_addlast(&iob->io_link, &g_iob_freelist); + flags = irqsave(); + iob->io_flink = g_iob_freelist; + g_iob_freelist = iob; + irqrestore(flags); /* And return the I/O buffer after the one that was freed */ diff --git a/nuttx/net/iob/iob_freechain.c b/nuttx/net/iob/iob_free_chain.c index bc66365f7..db9fc408c 100644 --- a/nuttx/net/iob/iob_freechain.c +++ b/nuttx/net/iob/iob_free_chain.c @@ -1,5 +1,5 @@ /**************************************************************************** - * net/iob/iob_freechain.c + * net/iob/iob_free_chain.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> @@ -39,8 +39,7 @@ #include <nuttx/config.h> -#include <queue.h> - +#include <nuttx/arch.h> #include <nuttx/net/iob.h> #include "iob.h" @@ -66,7 +65,7 @@ ****************************************************************************/ /**************************************************************************** - * Name: iob_freechain + * Name: iob_free_chain * * Description: * Free an entire buffer chain, starting at the beginning of the I/O @@ -74,28 +73,22 @@ * ****************************************************************************/ -void iob_freechain(FAR struct iob_s *iob) +void iob_free_chain(FAR struct iob_s *iob) { - FAR sq_entry_t *first = (sq_entry_t *)&iob->io_link; - FAR sq_entry_t *last; + FAR struct iob_s *last; + irqstate_t flags; /* Find the last entry in the I/O buffer list */ - for (last = first; last->flink; last = last->flink); + for (last = iob; last->io_flink; last = last->io_flink); - /* If the free list is empty, then just move the I/O buffer chain to the - * free list. Otherwise, append the I/O buffer chain to the end of the - * free list. + /* Free the I/O buffer chain by adding it to the head of the free list. We + * don't know what context we are called from so we use extreme measures to + * protect the free list: We disable interrupts very briefly. */ - if (g_iob_freelist.tail) - { - g_iob_freelist.tail->flink = first; - } - else - { - g_iob_freelist.head = first; - } - - g_iob_freelist.tail = last; + flags = irqsave(); + last->io_flink = g_iob_freelist; + g_iob_freelist = iob; + irqrestore(flags); } diff --git a/nuttx/net/iob/iob_free_qentry.c b/nuttx/net/iob/iob_free_qentry.c new file mode 100644 index 000000000..55d4cf848 --- /dev/null +++ b/nuttx/net/iob/iob_free_qentry.c @@ -0,0 +1,96 @@ +/**************************************************************************** + * net/iob/iob_free_qentry.c + * + * Copyright (C) 2014 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 <assert.h> + +#include <nuttx/arch.h> +#include <nuttx/net/iob.h> + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_free_qentry + * + * Description: + * Free the I/O buffer chain container by returning it to the free list. + * The link to the next I/O buffer in the chain is return. + * + ****************************************************************************/ + +FAR struct iob_qentry_s *iob_free_qentry(FAR struct iob_qentry_s *iobq) +{ + FAR struct iob_qentry_s *nextq = iobq->qe_flink; + irqstate_t flags; + + /* Free the I/O buffer chain container by adding it to the head of the free + * list. We don't know what context we are called from so we use extreme + * measures to protect the free list: We disable interrupts very briefly. + */ + + flags = irqsave(); + iobq->qe_flink = g_iob_freeqlist; + g_iob_freeqlist = iobq; + irqrestore(flags); + + /* And return the I/O buffer chain container after the one that was freed */ + + return nextq; +} diff --git a/nuttx/net/iob/iob_free_queue.c b/nuttx/net/iob/iob_free_queue.c new file mode 100644 index 000000000..1b1a51888 --- /dev/null +++ b/nuttx/net/iob/iob_free_queue.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * net/iob/iob_free_queue.c + * + * Copyright (C) 2014 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 <assert.h> + +#include <nuttx/net/iob.h> + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifndef NULL +# define NULL ((FAR void *)0) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_free_queue + * + * Description: + * Free an entire queue of I/O buffer chains. + * + ****************************************************************************/ + +void iob_free_queue(FAR struct iob_queue_s *qhead) +{ + FAR struct iob_qentry_s *iobq; + FAR struct iob_qentry_s *nextq; + FAR struct iob_s *iob; + + /* Detach the list from the queue head so first for safety (should be safe + * anyway). + */ + + iobq = qhead->qh_head; + qhead->qh_head = NULL; + + /* Remove each I/O buffer chain from the queue */ + + while (iobq) + { + /* Remove the I/O buffer chain from the head of the queue and + * discard the queue container. + */ + + iob = iobq->qe_head; + DEBUGASSERT(iob); + + /* Remove the queue container from the list and discard it */ + + nextq = iobq->qe_flink; + iob_free_qentry(iobq); + iobq = nextq; + + /* Free the I/O chain */ + + iob_free_chain(iob); + } +} diff --git a/nuttx/net/iob/iob_initialize.c b/nuttx/net/iob/iob_initialize.c index c5f72c397..5c4c122c3 100644 --- a/nuttx/net/iob/iob_initialize.c +++ b/nuttx/net/iob/iob_initialize.c @@ -40,7 +40,6 @@ #include <nuttx/config.h> #include <stdbool.h> -#include <queue.h> #include <nuttx/net/iob.h> @@ -60,16 +59,21 @@ /* This is a pool of pre-allocated I/O buffers */ -struct iob_s g_iob_pool[CONFIG_IOB_NBUFFERS]; - -/* A list of all free, unallocated I/O buffers */ - -sq_queue_t g_iob_freelist; +static struct iob_s g_iob_pool[CONFIG_IOB_NBUFFERS]; +static struct iob_qentry_s g_iob_qpool[CONFIG_IOB_NCHAINS]; /**************************************************************************** * Public Data ****************************************************************************/ +/* A list of all free, unallocated I/O buffers */ + +FAR struct iob_s *g_iob_freelist; + +/* A list of all free, unallocated I/O buffer queue containers */ + +FAR struct iob_qentry_s *g_iob_freeqlist; + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -95,7 +99,24 @@ void iob_initialize(void) for (i = 0; i < CONFIG_IOB_NBUFFERS; i++) { - sq_addlast(&g_iob_pool[i].io_link, &g_iob_freelist); + FAR struct iob_s *iob = &g_iob_pool[i]; + + /* Add the pre-allocate I/O buffer to the head of the free list */ + + iob->io_flink = g_iob_freelist; + g_iob_freelist = iob; + } + + /* Add each I/O buffer chain queue container to the free list */ + + for (i = 0; i < CONFIG_IOB_NCHAINS; i++) + { + FAR struct iob_qentry_s *iobq = &g_iob_qpool[i]; + + /* Add the pre-allocate buffer container to the head of the free list */ + + iobq->qe_flink = g_iob_freeqlist; + g_iob_freeqlist = iobq; } initialized = true; diff --git a/nuttx/net/iob/iob_pack.c b/nuttx/net/iob/iob_pack.c index 7533cf857..eb2c772c4 100644 --- a/nuttx/net/iob/iob_pack.c +++ b/nuttx/net/iob/iob_pack.c @@ -40,7 +40,6 @@ #include <nuttx/config.h> #include <string.h> -#include <queue.h> #include <nuttx/net/iob.h> @@ -102,7 +101,7 @@ FAR struct iob_s *iob_pack(FAR struct iob_s *iob) while (iob) { - next = (FAR struct iob_s *)iob->io_link.flink; + next = iob->io_flink; /* Eliminate the data offset in this entry */ @@ -149,8 +148,8 @@ FAR struct iob_s *iob_pack(FAR struct iob_s *iob) { /* Yes.. free the next entry in I/O buffer chain */ - next = iob_free(next); - iob->io_link.flink = (sq_entry_t *)next; + next = iob_free(next); + iob->io_flink = next; } } diff --git a/nuttx/net/iob/iob_remove_queue.c b/nuttx/net/iob/iob_remove_queue.c new file mode 100644 index 000000000..7a64d47c7 --- /dev/null +++ b/nuttx/net/iob/iob_remove_queue.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * net/iob/iob_remove_queue.c + * + * Copyright (C) 2014 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 <debug.h> + +#include <nuttx/net/iob.h> + +#include "iob.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef NULL +# define NULL ((FAR void *)0) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: iob_add_queue + * + * Description: + * Remove one I/O buffer chain from the heaqd of a queue. + * + ****************************************************************************/ + +FAR struct iob_s *iob_remove_queue(FAR struct iob_queue_s *iobq) +{ + FAR struct iob_qentry_s *qentry; + FAR struct iob_s *iob = NULL; + + /* Remove the I/O buffer chain from the head of the queue */ + + qentry = iobq->qh_head; + if (qentry) + { + iobq->qh_head = qentry->qe_flink; + if (!iobq->qh_head) + { + iobq->qh_tail = NULL; + } + + /* Extract the I/O buffer chain from the container and free the + * container. + */ + + iob = qentry->qe_head; + iob_free_qentry(qentry); + } + + return iob; +} + diff --git a/nuttx/net/iob/iob_test.c b/nuttx/net/iob/iob_test.c index 70e5f526f..93ed9b245 100644 --- a/nuttx/net/iob/iob_test.c +++ b/nuttx/net/iob/iob_test.c @@ -90,7 +90,7 @@ static void dump_chain(struct iob_s *iob) n, iob->io_len, iob->io_offset, iob->io_priv); pktlen += iob->io_len; - iob = (struct iob_s *)iob->io_link.flink; + iob = iob->io_flink; n++; } @@ -207,40 +207,3 @@ void my_assert(bool value) abort(); } } - -/**************************************************************************** - * Non-standard queue functions cloned from libc/queue - ****************************************************************************/ - -sq_entry_t *sq_remfirst(sq_queue_t *queue) -{ - sq_entry_t *ret = queue->head; - - if (ret) - { - queue->head = ret->flink; - if (!queue->head) - { - queue->tail = NULL; - } - - ret->flink = NULL; - } - - return ret; -} - -void sq_addlast(sq_entry_t *node, sq_queue_t *queue) -{ - node->flink = NULL; - if (!queue->head) - { - queue->head = node; - queue->tail = node; - } - else - { - queue->tail->flink = node; - queue->tail = node; - } -} diff --git a/nuttx/net/iob/iob_trimhead.c b/nuttx/net/iob/iob_trimhead.c index 7b051be46..0fe349023 100644 --- a/nuttx/net/iob/iob_trimhead.c +++ b/nuttx/net/iob/iob_trimhead.c @@ -49,6 +49,10 @@ * Pre-processor Definitions ****************************************************************************/ +#ifndef NULL +# define NULL ((FAR void *)0) +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -105,7 +109,7 @@ FAR struct iob_s *iob_trimhead(FAR struct iob_s *iob, unsigned int trimlen) /* Check if this was the last entry in the chain */ - next = (FAR struct iob_s *)iob->io_link.flink; + next = iob->io_flink; if (!next) { /* Yes.. break out of the loop returning the empty diff --git a/nuttx/net/iob/iob_trimtail.c b/nuttx/net/iob/iob_trimtail.c index 0a7dd2911..872560a49 100644 --- a/nuttx/net/iob/iob_trimtail.c +++ b/nuttx/net/iob/iob_trimtail.c @@ -40,7 +40,6 @@ #include <nuttx/config.h> #include <string.h> -#include <queue.h> #include <nuttx/net/iob.h> @@ -98,9 +97,7 @@ FAR struct iob_s *iob_trimtail(FAR struct iob_s *iob, unsigned int trimlen) last = NULL; iosize = 0; - for (entry = iob; - entry; - entry = (FAR struct iob_s *)entry->io_link.flink) + for (entry = iob; entry; entry = entry->io_flink) { /* Accumulate the total size of all buffers in the list */ @@ -139,7 +136,7 @@ FAR struct iob_s *iob_trimtail(FAR struct iob_s *iob, unsigned int trimlen) /* Unlink the penultimate from the freed buffer */ - penultimate->io_link.flink = NULL; + penultimate->io_flink = NULL; } else |