Message ID | 1455704211-12666-1-git-send-email-maxim.uvarov@linaro.org |
---|---|
State | Accepted |
Commit | e7da5814397e15f67e4b6381dfe4d09120a1a041 |
Headers | show |
On 17 February 2016 at 05:16, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > Remove ring and dead api-next code. In api-next pktio ipc patches > moved ring code to linux-generic and updated that test case to > the latest odp api. If we ipc pktio will be accepted to master > than current api-next ring test will be used. > > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> > Reviewed-by Mike Holmes <mike.holmes@linaro.org> > --- > configure.ac | 1 - > helper/Makefile.am | 2 - > helper/include/odp/helper/ring.h | 577 ----------------------------------- > helper/ring.c | 634 > --------------------------------------- > test/Makefile.am | 2 +- > test/api_test/.gitignore | 2 - > test/api_test/Makefile.am | 16 - > test/api_test/odp_common.c | 91 ------ > test/api_test/odp_common.h | 42 --- > test/api_test/odp_ring_test.c | 470 ----------------------------- > 10 files changed, 1 insertion(+), 1836 deletions(-) > delete mode 100644 helper/include/odp/helper/ring.h > delete mode 100644 helper/ring.c > delete mode 100644 test/api_test/.gitignore > delete mode 100644 test/api_test/Makefile.am > delete mode 100644 test/api_test/odp_common.c > delete mode 100644 test/api_test/odp_common.h > delete mode 100644 test/api_test/odp_ring_test.c > > diff --git a/configure.ac b/configure.ac > index 8108ff2..a7cb035 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -336,7 +336,6 @@ AC_CONFIG_FILES([Makefile > pkgconfig/libodphelper.pc > scripts/Makefile > test/Makefile > - test/api_test/Makefile > test/performance/Makefile > test/validation/Makefile > test/validation/atomic/Makefile > diff --git a/helper/Makefile.am b/helper/Makefile.am > index a8665b2..6557793 100644 > --- a/helper/Makefile.am > +++ b/helper/Makefile.am > @@ -10,7 +10,6 @@ AM_CFLAGS += -I$(top_srcdir)/include > > helperincludedir = $(includedir)/odp/helper/ > helperinclude_HEADERS = \ > - $(srcdir)/include/odp/helper/ring.h \ > $(srcdir)/include/odp/helper/linux.h \ > $(srcdir)/include/odp/helper/chksum.h\ > $(srcdir)/include/odp/helper/eth.h\ > @@ -30,7 +29,6 @@ noinst_HEADERS = \ > > __LIB__libodphelper_la_SOURCES = \ > linux.c \ > - ring.c \ > hashtable.c \ > lineartable.c > > diff --git a/helper/include/odp/helper/ring.h > b/helper/include/odp/helper/ring.h > deleted file mode 100644 > index 65c32ad..0000000 > --- a/helper/include/odp/helper/ring.h > +++ /dev/null > @@ -1,577 +0,0 @@ > -/* Copyright (c) 2014, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/*- > - * BSD LICENSE > - * > - * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. > - * All rights reserved. > - * > - * Redistribution and use in source and binary forms, with or without > - * modification, are permitted provided that the following conditions > - * are met: > - * > - * * Redistributions of source code must retain the above copyright > - * notice, this list of conditions and the following disclaimer. > - * * 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. > - * * Neither the name of Intel Corporation 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. > - */ > - > -/* > - * Derived from FreeBSD's bufring.c > - * > - > ************************************************************************** > - * > - * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org > - * All rights reserved. > - * > - * 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. The name of Kip Macy nor the names of other > - * 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. > - * > - > ***************************************************************************/ > - > -/** > - * ODP Ring > - * > - * The Ring Manager is a fixed-size queue, implemented as a table of > - * pointers. Head and tail pointers are modified atomically, allowing > - * concurrent access to it. It has the following features: > - * > - * - FIFO (First In First Out) > - * - Maximum size is fixed; the pointers are stored in a table. > - * - Lockless implementation. > - * - Multi- or single-consumer dequeue. > - * - Multi- or single-producer enqueue. > - * - Bulk dequeue. > - * - Bulk enqueue. > - * > - * Note: the ring implementation is not preemptable. A lcore must not > - * be interrupted by another task that uses the same ring. > - * > - */ > - > -#ifndef ODPH_RING_H_ > -#define ODPH_RING_H_ > - > -#ifdef __cplusplus > -extern "C" { > -#endif > - > - > -#include <odp/std_types.h> > -#include <odp/hints.h> > -#include <odp/atomic.h> > -#include <errno.h> > -#include <sys/queue.h> > - > -enum odph_ring_queue_behavior { > - ODPH_RING_QUEUE_FIXED = 0, /**< Enq/Deq a fixed number > - of items from a ring */ > - ODPH_RING_QUEUE_VARIABLE /**< Enq/Deq as many items > - a possible from ring */ > -}; > - > - > -#define ODPH_RING_NAMESIZE 32 /**< The maximum length of a ring name. */ > - > -/** > - * An ODP ring structure. > - * > - * The producer and the consumer have a head and a tail index. The > particularity > - * of these index is that they are not between 0 and size(ring). These > indexes > - * are between 0 and 2^32, and we mask their value when we access the > ring[] > - * field. Thanks to this assumption, we can do subtractions between 2 > index > - * values in a modulo-32bit base: that's why the overflow of the indexes > is not > - * a problem. > - */ > -typedef struct odph_ring { > - /** @private Next in list. */ > - TAILQ_ENTRY(odph_ring) next; > - > - /** @private Name of the ring. */ > - char name[ODPH_RING_NAMESIZE]; > - /** @private Flags supplied at creation. */ > - int flags; > - > - /** @private Producer */ > - struct prod { > - uint32_t watermark; /* Maximum items */ > - uint32_t sp_enqueue; /* True, if single producer. */ > - uint32_t size; /* Size of ring. */ > - uint32_t mask; /* Mask (size-1) of ring. */ > - uint32_t head; /* Producer head. */ > - uint32_t tail; /* Producer tail. */ > - } prod ODP_ALIGNED_CACHE; > - > - /** @private Consumer */ > - struct cons { > - uint32_t sc_dequeue; /* True, if single consumer. */ > - uint32_t size; /* Size of the ring. */ > - uint32_t mask; /* Mask (size-1) of ring. */ > - uint32_t head; /* Consumer head. */ > - uint32_t tail; /* Consumer tail. */ > - } cons ODP_ALIGNED_CACHE; > - > - /** @private Memory space of ring starts here. */ > - void *ring[0] ODP_ALIGNED_CACHE; > -} odph_ring_t; > - > - > -#define ODPH_RING_F_SP_ENQ 0x0001 /* The default enqueue is > "single-producer".*/ > -#define ODPH_RING_F_SC_DEQ 0x0002 /* The default dequeue is > "single-consumer".*/ > -#define ODPH_RING_QUOT_EXCEED (1 << 31) /* Quota exceed for burst ops */ > -#define ODPH_RING_SZ_MASK (unsigned)(0x0fffffff) /* Ring size mask */ > - > - > -/** > - * Create a new ring named *name* in memory. > - * > - * This function uses odp_shm_reserve() to allocate memory. Its size is > - * set to *count*, which must be a power of two. Water marking is > - * disabled by default. Note that the real usable ring size is count-1 > - * instead of count. > - * > - * @param name > - * The name of the ring. > - * @param count > - * The size of the ring (must be a power of 2). > - * @param socket_id (dummy, not included : todo) > - * @param flags > - * An OR of the following: > - * - RING_F_SP_ENQ: If this flag is set, the default behavior when > - * using ``odp_ring_enqueue()`` or ``odp_ring_enqueue_bulk()`` > - * is "single-producer". Otherwise, it is "multi-producers". > - * - RING_F_SC_DEQ: If this flag is set, the default behavior when > - * using ``odp_ring_dequeue()`` or ``odp_ring_dequeue_bulk()`` > - * is "single-consumer". Otherwise, it is "multi-consumers". > - * @return > - * On success, the pointer to the new allocated ring. NULL on error with > - * odp_errno set appropriately. Possible errno values include: > - * - EINVAL - count provided is not a power of 2 > - * - ENOSPC - the maximum number of memzones has already been allocated > - * - EEXIST - a memzone with the same name already exists > - * - ENOMEM - no appropriate memory area found in which to create > memzone > - */ > -odph_ring_t *odph_ring_create(const char *name, unsigned count, > - unsigned flags); > - > - > -/** > - * Change the high water mark. > - * > - * If *count* is 0, water marking is disabled. Otherwise, it is set to the > - * *count* value. The *count* value must be greater than 0 and less > - * than the ring size. > - * > - * This function can be called at any time (not necessarily at > - * initialization). > - * > - * @param r Pointer to the ring structure. > - * @param count New water mark value. > - * @return 0: Success; water mark changed. > - * -EINVAL: Invalid water mark value. > - */ > -int odph_ring_set_water_mark(odph_ring_t *r, unsigned count); > - > -/** > - * Dump the status of the ring to the console. > - * > - * @param r A pointer to the ring structure. > - */ > -void odph_ring_dump(const odph_ring_t *r); > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - * > - * This function uses a "compare and set" instruction to move the > - * producer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @param behavior > - * ODP_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring > - * ODP_RING_QUEUE_VARIABLE: Enqueue as many items a possible from ring > - * @return > - * Depend on the behavior value > - * if behavior = ODP_RING_QUEUE_FIXED > - * - 0: Success; objects enqueue. > - * - -EDQUOT: Quota exceeded. The objects have been enqueued, but the > - * high water mark is exceeded. > - * - -ENOBUFS: Not enough room in the ring to enqueue, no object is > enqueued. > - * if behavior = ODP_RING_QUEUE_VARIABLE > - * - n: Actual number of objects enqueued. > - */ > -int __odph_ring_mp_do_enqueue(odph_ring_t *r, void * const *obj_table, > - unsigned n, > - enum odph_ring_queue_behavior behavior); > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @param behavior > - * ODP_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring > - * ODP_RING_QUEUE_VARIABLE: Enqueue as many items a possible from ring > - * @return > - * Depend on the behavior value > - * if behavior = ODP_RING_QUEUE_FIXED > - * - 0: Success; objects enqueue. > - * - -EDQUOT: Quota exceeded. The objects have been enqueued, but the > - * high water mark is exceeded. > - * - -ENOBUFS: Not enough room in the ring to enqueue, no object is > enqueued. > - * if behavior = ODP_RING_QUEUE_VARIABLE > - * - n: Actual number of objects enqueued. > - */ > -int __odph_ring_sp_do_enqueue(odph_ring_t *r, void * const *obj_table, > - unsigned n, > - enum odph_ring_queue_behavior behavior); > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). When > - * the request objects are more than the available objects, only dequeue > the > - * actual number of objects > - * > - * This function uses a "compare and set" instruction to move the > - * consumer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will be > filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @param behavior > - * ODP_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring > - * ODP_RING_QUEUE_VARIABLE: Dequeue as many items a possible from ring > - * @return > - * Depend on the behavior value > - * if behavior = ODP_RING_QUEUE_FIXED > - * - 0: Success; objects dequeued. > - * - -ENOENT: Not enough entries in the ring to dequeue; no object is > - * dequeued. > - * if behavior = ODP_RING_QUEUE_VARIABLE > - * - n: Actual number of objects dequeued. > - */ > - > -int __odph_ring_mc_do_dequeue(odph_ring_t *r, void **obj_table, > - unsigned n, > - enum odph_ring_queue_behavior behavior); > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - * When the request objects are more than the available objects, only > dequeue > - * the actual number of objects > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will be > filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @param behavior > - * ODP_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring > - * ODP_RING_QUEUE_VARIABLE: Dequeue as many items a possible from ring > - * @return > - * Depend on the behavior value > - * if behavior = ODP_RING_QUEUE_FIXED > - * - 0: Success; objects dequeued. > - * - -ENOENT: Not enough entries in the ring to dequeue; no object is > - * dequeued. > - * if behavior = ODP_RING_QUEUE_VARIABLE > - * - n: Actual number of objects dequeued. > - */ > -int __odph_ring_sc_do_dequeue(odph_ring_t *r, void **obj_table, > - unsigned n, > - enum odph_ring_queue_behavior behavior); > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - * > - * This function uses a "compare and set" instruction to move the > - * producer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - 0: Success; objects enqueue. > - * - -EDQUOT: Quota exceeded. The objects have been enqueued, but the > - * high water mark is exceeded. > - * - -ENOBUFS: Not enough room in the ring to enqueue, no object is > enqueued. > - */ > -int odph_ring_mp_enqueue_bulk(odph_ring_t *r, void * const *obj_table, > - unsigned n); > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - 0: Success; objects enqueued. > - * - -EDQUOT: Quota exceeded. The objects have been enqueued, but the > - * high water mark is exceeded. > - * - -ENOBUFS: Not enough room in the ring to enqueue; no object is > enqueued. > - */ > -int odph_ring_sp_enqueue_bulk(odph_ring_t *r, void * const *obj_table, > - unsigned n); > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). > - * > - * This function uses a "compare and set" instruction to move the > - * consumer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will be > filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @return > - * - 0: Success; objects dequeued. > - * - -ENOENT: Not enough entries in the ring to dequeue; no object is > - * dequeued. > - */ > -int odph_ring_mc_dequeue_bulk(odph_ring_t *r, void **obj_table, unsigned > n); > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will be > filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table, > - * must be strictly positive. > - * @return > - * - 0: Success; objects dequeued. > - * - -ENOENT: Not enough entries in the ring to dequeue; no object is > - * dequeued. > - */ > -int odph_ring_sc_dequeue_bulk(odph_ring_t *r, void **obj_table, unsigned > n); > - > -/** > - * Test if a ring is full. > - * > - * @param r > - * A pointer to the ring structure. > - * @return > - * - 1: The ring is full. > - * - 0: The ring is not full. > - */ > -int odph_ring_full(const odph_ring_t *r); > - > -/** > - * Test if a ring is empty. > - * > - * @param r > - * A pointer to the ring structure. > - * @return > - * - 1: The ring is empty. > - * - 0: The ring is not empty. > - */ > -int odph_ring_empty(const odph_ring_t *r); > - > -/** > - * Return the number of entries in a ring. > - * > - * @param r > - * A pointer to the ring structure. > - * @return > - * The number of entries in the ring. > - */ > -unsigned odph_ring_count(const odph_ring_t *r); > - > -/** > - * Return the number of free entries in a ring. > - * > - * @param r > - * A pointer to the ring structure. > - * @return > - * The number of free entries in the ring. > - */ > -unsigned odph_ring_free_count(const odph_ring_t *r); > - > -/** > - * search ring by name > - * @param name ring name to search > - * @return pointer to ring otherwise NULL > - */ > -odph_ring_t *odph_ring_lookup(const char *name); > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - * > - * This function uses a "compare and set" instruction to move the > - * producer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - n: Actual number of objects enqueued. > - */ > -int odph_ring_mp_enqueue_burst(odph_ring_t *r, void * const *obj_table, > - unsigned n); > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - n: Actual number of objects enqueued. > - */ > -int odph_ring_sp_enqueue_burst(odph_ring_t *r, void * const *obj_table, > - unsigned n); > -/** > - * Enqueue several objects on a ring. > - * > - * This function calls the multi-producer or the single-producer > - * version depending on the default behavior that was specified at > - * ring creation time (see flags). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - n: Actual number of objects enqueued. > - */ > -int odph_ring_enqueue_burst(odph_ring_t *r, void * const *obj_table, > - unsigned n); > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). When the > request > - * objects are more than the available objects, only dequeue the actual > number > - * of objects > - * > - * This function uses a "compare and set" instruction to move the > - * consumer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will be > filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @return > - * - n: Actual number of objects dequeued, 0 if ring is empty > - */ > -int odph_ring_mc_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned > n); > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe).When the > - * request objects are more than the available objects, only dequeue the > - * actual number of objects > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will be > filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @return > - * - n: Actual number of objects dequeued, 0 if ring is empty > - */ > -int odph_ring_sc_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned > n); > - > -/** > - * Dequeue multiple objects from a ring up to a maximum number. > - * > - * This function calls the multi-consumers or the single-consumer > - * version, depending on the default behaviour that was specified at > - * ring creation time (see flags). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will be > filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @return > - * - Number of objects dequeued, or a negative error code on error > - */ > -int odph_ring_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned n); > - > -/** > - * dump the status of all rings on the console > - */ > -void odph_ring_list_dump(void); > - > -/** > - * initialise ring tailq > - */ > -void odph_ring_tailq_init(void); > - > -#ifdef __cplusplus > -} > -#endif > - > -#endif > diff --git a/helper/ring.c b/helper/ring.c > deleted file mode 100644 > index 6699186..0000000 > --- a/helper/ring.c > +++ /dev/null > @@ -1,634 +0,0 @@ > -/* Copyright (c) 2014, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/*- > - * BSD LICENSE > - * > - * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. > - * All rights reserved. > - * > - * Redistribution and use in source and binary forms, with or without > - * modification, are permitted provided that the following conditions > - * are met: > - * > - * * Redistributions of source code must retain the above copyright > - * notice, this list of conditions and the following disclaimer. > - * * 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. > - * * Neither the name of Intel Corporation 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. > - */ > - > -/* > - * Derived from FreeBSD's bufring.c > - * > - > ************************************************************************** > - * > - * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org > - * All rights reserved. > - * > - * 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. The name of Kip Macy nor the names of other > - * 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. > - * > - > ***************************************************************************/ > - > -#include <odp.h> > -#include <fcntl.h> > -#include <stdio.h> > -#include <string.h> > -#include "odph_debug.h" > -#include <odp/helper/ring.h> > - > -static TAILQ_HEAD(, odph_ring) odp_ring_list; > - > -#define RING_VAL_IS_POWER_2(x) ((((x) - 1) & (x)) == 0) > - > -/* > - * the enqueue of pointers on the ring. > - */ > -#define ENQUEUE_PTRS() do { \ > - const uint32_t size = r->prod.size; \ > - uint32_t idx = prod_head & mask; \ > - if (odp_likely(idx + n < size)) { \ > - for (i = 0; i < (n & ((~(unsigned)0x3))); i += 4, idx += > 4) { \ > - r->ring[idx] = obj_table[i]; \ > - r->ring[idx+1] = obj_table[i+1]; \ > - r->ring[idx+2] = obj_table[i+2]; \ > - r->ring[idx+3] = obj_table[i+3]; \ > - } \ > - switch (n & 0x3) { \ > - case 3: \ > - r->ring[idx++] = obj_table[i++]; \ > - case 2: \ > - r->ring[idx++] = obj_table[i++]; \ > - case 1: \ > - r->ring[idx++] = obj_table[i++]; \ > - } \ > - } else { \ > - for (i = 0; idx < size; i++, idx++)\ > - r->ring[idx] = obj_table[i]; \ > - for (idx = 0; i < n; i++, idx++) \ > - r->ring[idx] = obj_table[i]; \ > - } \ > -} while (0) > - > -/* > - * the actual copy of pointers on the ring to obj_table. > - */ > -#define DEQUEUE_PTRS() do { \ > - uint32_t idx = cons_head & mask; \ > - const uint32_t size = r->cons.size; \ > - if (odp_likely(idx + n < size)) { \ > - for (i = 0; i < (n & (~(unsigned)0x3)); i += 4, idx += 4) > {\ > - obj_table[i] = r->ring[idx]; \ > - obj_table[i+1] = r->ring[idx+1]; \ > - obj_table[i+2] = r->ring[idx+2]; \ > - obj_table[i+3] = r->ring[idx+3]; \ > - } \ > - switch (n & 0x3) { \ > - case 3: \ > - obj_table[i++] = r->ring[idx++]; \ > - case 2: \ > - obj_table[i++] = r->ring[idx++]; \ > - case 1: \ > - obj_table[i++] = r->ring[idx++]; \ > - } \ > - } else { \ > - for (i = 0; idx < size; i++, idx++) \ > - obj_table[i] = r->ring[idx]; \ > - for (idx = 0; i < n; i++, idx++) \ > - obj_table[i] = r->ring[idx]; \ > - } \ > -} while (0) > - > -static odp_rwlock_t qlock; /* rings tailq lock */ > - > -/* init tailq_ring */ > -void odph_ring_tailq_init(void) > -{ > - TAILQ_INIT(&odp_ring_list); > - odp_rwlock_init(&qlock); > -} > - > -/* create the ring */ > -odph_ring_t * > -odph_ring_create(const char *name, unsigned count, unsigned flags) > -{ > - char ring_name[ODPH_RING_NAMESIZE]; > - odph_ring_t *r; > - size_t ring_size; > - odp_shm_t shm; > - > - /* count must be a power of 2 */ > - if (!RING_VAL_IS_POWER_2(count) || (count > ODPH_RING_SZ_MASK)) { > - ODPH_ERR("Requested size is invalid, must be power of 2, > and do not exceed the size limit %u\n", > - ODPH_RING_SZ_MASK); > - return NULL; > - } > - > - snprintf(ring_name, sizeof(ring_name), "%s", name); > - ring_size = count*sizeof(void *)+sizeof(odph_ring_t); > - > - odp_rwlock_write_lock(&qlock); > - /* reserve a memory zone for this ring.*/ > - shm = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE, > 0); > - > - r = odp_shm_addr(shm); > - > - if (r != NULL) { > - /* init the ring structure */ > - snprintf(r->name, sizeof(r->name), "%s", name); > - r->flags = flags; > - r->prod.watermark = count; > - r->prod.sp_enqueue = !!(flags & ODPH_RING_F_SP_ENQ); > - r->cons.sc_dequeue = !!(flags & ODPH_RING_F_SC_DEQ); > - r->prod.size = count; > - r->cons.size = count; > - r->prod.mask = count-1; > - r->cons.mask = count-1; > - r->prod.head = 0; > - r->cons.head = 0; > - r->prod.tail = 0; > - r->cons.tail = 0; > - > - TAILQ_INSERT_TAIL(&odp_ring_list, r, next); > - } else { > - ODPH_ERR("Cannot reserve memory\n"); > - } > - > - odp_rwlock_write_unlock(&qlock); > - return r; > -} > - > -/* > - * change the high water mark. If *count* is 0, water marking is > - * disabled > - */ > -int odph_ring_set_water_mark(odph_ring_t *r, unsigned count) > -{ > - if (count >= r->prod.size) > - return -EINVAL; > - > - /* if count is 0, disable the watermarking */ > - if (count == 0) > - count = r->prod.size; > - > - r->prod.watermark = count; > - return 0; > -} > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - */ > -int __odph_ring_mp_do_enqueue(odph_ring_t *r, void * const *obj_table, > - unsigned n, enum odph_ring_queue_behavior > behavior) > -{ > - uint32_t prod_head, prod_next; > - uint32_t cons_tail, free_entries; > - const unsigned max = n; > - int success; > - unsigned i; > - uint32_t mask = r->prod.mask; > - int ret; > - > - /* move prod.head atomically */ > - do { > - /* Reset n to the initial burst count */ > - n = max; > - > - prod_head = r->prod.head; > - cons_tail = r->cons.tail; > - /* The subtraction is done between two unsigned 32bits > value > - * (the result is always modulo 32 bits even if we have > - * prod_head > cons_tail). So 'free_entries' is always > between 0 > - * and size(ring)-1. */ > - free_entries = (mask + cons_tail - prod_head); > - > - /* check that we have enough room in ring */ > - if (odp_unlikely(n > free_entries)) { > - if (behavior == ODPH_RING_QUEUE_FIXED) { > - return -ENOBUFS; > - } else { > - /* No free entry available */ > - if (odp_unlikely(free_entries == 0)) > - return 0; > - > - n = free_entries; > - } > - } > - > - prod_next = prod_head + n; > - success = __atomic_compare_exchange_n(&r->prod.head, > - &prod_head, > - prod_next, > - false/*strong*/, > - __ATOMIC_ACQUIRE, > - __ATOMIC_RELAXED); > - } while (odp_unlikely(success == 0)); > - > - /* write entries in ring */ > - ENQUEUE_PTRS(); > - > - /* if we exceed the watermark */ > - if (odp_unlikely(((mask + 1) - free_entries + n) > > r->prod.watermark)) { > - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? -EDQUOT : > - (int)(n | ODPH_RING_QUOT_EXCEED); > - } else { > - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? 0 : n; > - } > - > - /* > - * If there are other enqueues in progress that preceded us, > - * we need to wait for them to complete > - */ > - while (odp_unlikely(r->prod.tail != prod_head)) > - odp_cpu_pause(); > - > - /* Release our entries and the memory they refer to */ > - __atomic_thread_fence(__ATOMIC_RELEASE); > - r->prod.tail = prod_next; > - return ret; > -} > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - */ > -int __odph_ring_sp_do_enqueue(odph_ring_t *r, void * const *obj_table, > - unsigned n, enum odph_ring_queue_behavior > behavior) > -{ > - uint32_t prod_head, cons_tail; > - uint32_t prod_next, free_entries; > - unsigned i; > - uint32_t mask = r->prod.mask; > - int ret; > - > - prod_head = r->prod.head; > - cons_tail = r->cons.tail; > - /* The subtraction is done between two unsigned 32bits value > - * (the result is always modulo 32 bits even if we have > - * prod_head > cons_tail). So 'free_entries' is always between 0 > - * and size(ring)-1. */ > - free_entries = mask + cons_tail - prod_head; > - > - /* check that we have enough room in ring */ > - if (odp_unlikely(n > free_entries)) { > - if (behavior == ODPH_RING_QUEUE_FIXED) { > - return -ENOBUFS; > - } else { > - /* No free entry available */ > - if (odp_unlikely(free_entries == 0)) > - return 0; > - > - n = free_entries; > - } > - } > - > - prod_next = prod_head + n; > - r->prod.head = prod_next; > - > - /* write entries in ring */ > - ENQUEUE_PTRS(); > - > - /* if we exceed the watermark */ > - if (odp_unlikely(((mask + 1) - free_entries + n) > > r->prod.watermark)) { > - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? -EDQUOT : > - (int)(n | ODPH_RING_QUOT_EXCEED); > - } else { > - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? 0 : n; > - } > - > - /* Release our entries and the memory they refer to */ > - __atomic_thread_fence(__ATOMIC_RELEASE); > - r->prod.tail = prod_next; > - return ret; > -} > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). > - */ > - > -int __odph_ring_mc_do_dequeue(odph_ring_t *r, void **obj_table, > - unsigned n, enum odph_ring_queue_behavior > behavior) > -{ > - uint32_t cons_head, prod_tail; > - uint32_t cons_next, entries; > - const unsigned max = n; > - int success; > - unsigned i; > - uint32_t mask = r->prod.mask; > - > - /* move cons.head atomically */ > - do { > - /* Restore n as it may change every loop */ > - n = max; > - > - cons_head = r->cons.head; > - prod_tail = r->prod.tail; > - /* The subtraction is done between two unsigned 32bits > value > - * (the result is always modulo 32 bits even if we have > - * cons_head > prod_tail). So 'entries' is always between 0 > - * and size(ring)-1. */ > - entries = (prod_tail - cons_head); > - > - /* Set the actual entries for dequeue */ > - if (n > entries) { > - if (behavior == ODPH_RING_QUEUE_FIXED) { > - return -ENOENT; > - } else { > - if (odp_unlikely(entries == 0)) > - return 0; > - > - n = entries; > - } > - } > - > - cons_next = cons_head + n; > - success = __atomic_compare_exchange_n(&r->cons.head, > - &cons_head, > - cons_next, > - false/*strong*/, > - __ATOMIC_ACQUIRE, > - __ATOMIC_RELAXED); > - } while (odp_unlikely(success == 0)); > - > - /* copy in table */ > - DEQUEUE_PTRS(); > - > - /* > - * If there are other dequeues in progress that preceded us, > - * we need to wait for them to complete > - */ > - while (odp_unlikely(r->cons.tail != cons_head)) > - odp_cpu_pause(); > - > - /* Release our entries and the memory they refer to */ > - __atomic_thread_fence(__ATOMIC_RELEASE); > - r->cons.tail = cons_next; > - > - return behavior == ODPH_RING_QUEUE_FIXED ? 0 : n; > -} > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - */ > -int __odph_ring_sc_do_dequeue(odph_ring_t *r, void **obj_table, > - unsigned n, enum odph_ring_queue_behavior > behavior) > -{ > - uint32_t cons_head, prod_tail; > - uint32_t cons_next, entries; > - unsigned i; > - uint32_t mask = r->prod.mask; > - > - cons_head = r->cons.head; > - prod_tail = r->prod.tail; > - /* The subtraction is done between two unsigned 32bits value > - * (the result is always modulo 32 bits even if we have > - * cons_head > prod_tail). So 'entries' is always between 0 > - * and size(ring)-1. */ > - entries = prod_tail - cons_head; > - > - if (n > entries) { > - if (behavior == ODPH_RING_QUEUE_FIXED) { > - return -ENOENT; > - } else { > - if (odp_unlikely(entries == 0)) > - return 0; > - > - n = entries; > - } > - } > - > - cons_next = cons_head + n; > - r->cons.head = cons_next; > - > - /* Acquire the pointers and the memory they refer to */ > - __atomic_thread_fence(__ATOMIC_ACQUIRE); > - /* copy in table */ > - DEQUEUE_PTRS(); > - > - r->cons.tail = cons_next; > - return behavior == ODPH_RING_QUEUE_FIXED ? 0 : n; > -} > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - */ > -int odph_ring_mp_enqueue_bulk(odph_ring_t *r, void * const *obj_table, > - unsigned n) > -{ > - return __odph_ring_mp_do_enqueue(r, obj_table, n, > - ODPH_RING_QUEUE_FIXED); > -} > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - */ > -int odph_ring_sp_enqueue_bulk(odph_ring_t *r, void * const *obj_table, > - unsigned n) > -{ > - return __odph_ring_sp_do_enqueue(r, obj_table, n, > - ODPH_RING_QUEUE_FIXED); > -} > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). > - */ > -int odph_ring_mc_dequeue_bulk(odph_ring_t *r, void **obj_table, unsigned > n) > -{ > - return __odph_ring_mc_do_dequeue(r, obj_table, n, > - ODPH_RING_QUEUE_FIXED); > -} > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - */ > -int odph_ring_sc_dequeue_bulk(odph_ring_t *r, void **obj_table, unsigned > n) > -{ > - return __odph_ring_sc_do_dequeue(r, obj_table, n, > - ODPH_RING_QUEUE_FIXED); > -} > - > -/** > - * Test if a ring is full. > - */ > -int odph_ring_full(const odph_ring_t *r) > -{ > - uint32_t prod_tail = r->prod.tail; > - uint32_t cons_tail = r->cons.tail; > - return (((cons_tail - prod_tail - 1) & r->prod.mask) == 0); > -} > - > -/** > - * Test if a ring is empty. > - */ > -int odph_ring_empty(const odph_ring_t *r) > -{ > - uint32_t prod_tail = r->prod.tail; > - uint32_t cons_tail = r->cons.tail; > - return !!(cons_tail == prod_tail); > -} > - > -/** > - * Return the number of entries in a ring. > - */ > -unsigned odph_ring_count(const odph_ring_t *r) > -{ > - uint32_t prod_tail = r->prod.tail; > - uint32_t cons_tail = r->cons.tail; > - return (prod_tail - cons_tail) & r->prod.mask; > -} > - > -/** > - * Return the number of free entries in a ring. > - */ > -unsigned odph_ring_free_count(const odph_ring_t *r) > -{ > - uint32_t prod_tail = r->prod.tail; > - uint32_t cons_tail = r->cons.tail; > - return (cons_tail - prod_tail - 1) & r->prod.mask; > -} > - > -/* dump the status of the ring on the console */ > -void odph_ring_dump(const odph_ring_t *r) > -{ > - ODPH_DBG("ring <%s>@%p\n", r->name, r); > - ODPH_DBG(" flags=%x\n", r->flags); > - ODPH_DBG(" size=%" PRIu32 "\n", r->prod.size); > - ODPH_DBG(" ct=%" PRIu32 "\n", r->cons.tail); > - ODPH_DBG(" ch=%" PRIu32 "\n", r->cons.head); > - ODPH_DBG(" pt=%" PRIu32 "\n", r->prod.tail); > - ODPH_DBG(" ph=%" PRIu32 "\n", r->prod.head); > - ODPH_DBG(" used=%u\n", odph_ring_count(r)); > - ODPH_DBG(" avail=%u\n", odph_ring_free_count(r)); > - if (r->prod.watermark == r->prod.size) > - ODPH_DBG(" watermark=0\n"); > - else > - ODPH_DBG(" watermark=%" PRIu32 "\n", r->prod.watermark); > -} > - > -/* dump the status of all rings on the console */ > -void odph_ring_list_dump(void) > -{ > - const odph_ring_t *mp = NULL; > - > - odp_rwlock_read_lock(&qlock); > - > - TAILQ_FOREACH(mp, &odp_ring_list, next) { > - odph_ring_dump(mp); > - } > - > - odp_rwlock_read_unlock(&qlock); > -} > - > -/* search a ring from its name */ > -odph_ring_t *odph_ring_lookup(const char *name) > -{ > - odph_ring_t *r; > - > - odp_rwlock_read_lock(&qlock); > - TAILQ_FOREACH(r, &odp_ring_list, next) { > - if (strncmp(name, r->name, ODPH_RING_NAMESIZE) == 0) > - break; > - } > - odp_rwlock_read_unlock(&qlock); > - > - return r; > -} > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - */ > -int odph_ring_mp_enqueue_burst(odph_ring_t *r, void * const *obj_table, > - unsigned n) > -{ > - return __odph_ring_mp_do_enqueue(r, obj_table, n, > - ODPH_RING_QUEUE_VARIABLE); > -} > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - */ > -int odph_ring_sp_enqueue_burst(odph_ring_t *r, void * const *obj_table, > - unsigned n) > -{ > - return __odph_ring_sp_do_enqueue(r, obj_table, n, > - ODPH_RING_QUEUE_VARIABLE); > -} > - > -/** > - * Enqueue several objects on a ring. > - */ > -int odph_ring_enqueue_burst(odph_ring_t *r, void * const *obj_table, > - unsigned n) > -{ > - if (r->prod.sp_enqueue) > - return odph_ring_sp_enqueue_burst(r, obj_table, n); > - else > - return odph_ring_mp_enqueue_burst(r, obj_table, n); > -} > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). > - */ > -int odph_ring_mc_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned > n) > -{ > - return __odph_ring_mc_do_dequeue(r, obj_table, n, > - ODPH_RING_QUEUE_VARIABLE); > -} > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - */ > -int odph_ring_sc_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned > n) > -{ > - return __odph_ring_sc_do_dequeue(r, obj_table, n, > - ODPH_RING_QUEUE_VARIABLE); > -} > - > -/** > - * Dequeue multiple objects from a ring up to a maximum number. > - */ > -int odph_ring_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned n) > -{ > - if (r->cons.sc_dequeue) > - return odph_ring_sc_dequeue_burst(r, obj_table, n); > - else > - return odph_ring_mc_dequeue_burst(r, obj_table, n); > -} > diff --git a/test/Makefile.am b/test/Makefile.am > index 2ba8008..4a75364 100644 > --- a/test/Makefile.am > +++ b/test/Makefile.am > @@ -1,4 +1,4 @@ > -SUBDIRS = api_test performance miscellaneous > +SUBDIRS = performance miscellaneous > > if cunit_support > SUBDIRS += validation > diff --git a/test/api_test/.gitignore b/test/api_test/.gitignore > deleted file mode 100644 > index 950f443..0000000 > --- a/test/api_test/.gitignore > +++ /dev/null > @@ -1,2 +0,0 @@ > -odp_ring > -odp_shm > diff --git a/test/api_test/Makefile.am b/test/api_test/Makefile.am > deleted file mode 100644 > index 97ca5df..0000000 > --- a/test/api_test/Makefile.am > +++ /dev/null > @@ -1,16 +0,0 @@ > -include $(top_srcdir)/test/Makefile.inc > - > -bin_PROGRAMS = odp_ring$(EXEEXT) > - > -odp_ring_CFLAGS = $(AM_CFLAGS) > - > -odp_ring_LDFLAGS = $(AM_LDFLAGS) -static > - > -noinst_HEADERS = \ > - $(top_srcdir)/test/api_test/odp_common.h \ > - $(top_srcdir)/test/test_debug.h > - > -dist_odp_ring_SOURCES = odp_ring_test.c odp_common.c > - > -#The tests will need to retain the deprecated test implementation > -AM_CFLAGS += -Wno-deprecated-declarations > \ No newline at end of file > diff --git a/test/api_test/odp_common.c b/test/api_test/odp_common.c > deleted file mode 100644 > index 70aee96..0000000 > --- a/test/api_test/odp_common.c > +++ /dev/null > @@ -1,91 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/** > - * @file > - * > - * ODP test application common > - */ > - > -#include <string.h> > -#include <odp.h> > -#include <odp/helper/linux.h> > -#include <odp_common.h> > -#include <test_debug.h> > - > -#define MAX_WORKERS 32 /**< Max worker threads */ > - > -/* Globals */ > -static odph_linux_pthread_t thread_tbl[MAX_WORKERS]; /**< worker threads > table*/ > -static int num_workers; /**< number of > workers */ > - > -/** > - * Print system information > - */ > -void odp_print_system_info(void) > -{ > - odp_cpumask_t cpumask; > - char str[ODP_CPUMASK_STR_SIZE]; > - > - memset(str, 1, sizeof(str)); > - > - odp_cpumask_zero(&cpumask); > - > - odp_cpumask_from_str(&cpumask, "0x1"); > - (void)odp_cpumask_to_str(&cpumask, str, sizeof(str)); > - > - printf("\n"); > - printf("ODP system info\n"); > - printf("---------------\n"); > - printf("ODP API version: %s\n", odp_version_api_str()); > - printf("CPU model: %s\n", odp_cpu_model_str()); > - printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz_max()); > - printf("Cache line size: %i\n", odp_sys_cache_line_size()); > - printf("CPU count: %i\n", odp_cpu_count()); > - printf("CPU mask: %s\n", str); > - > - printf("\n"); > -} > - > -/** test init globals and call odp_init_global() */ > -int odp_test_global_init(void) > -{ > - memset(thread_tbl, 0, sizeof(thread_tbl)); > - > - if (odp_init_global(NULL, NULL)) { > - LOG_ERR("ODP global init failed.\n"); > - return -1; > - } > - > - num_workers = odp_cpu_count(); > - /* force to max CPU count */ > - if (num_workers > MAX_WORKERS) > - num_workers = MAX_WORKERS; > - > - return 0; > -} > - > -/** create test thread */ > -int odp_test_thread_create(void *func_ptr(void *), pthrd_arg *arg) > -{ > - odp_cpumask_t cpumask; > - > - /* Create and init additional threads */ > - odp_cpumask_default_worker(&cpumask, arg->numthrds); > - odph_linux_pthread_create(thread_tbl, &cpumask, func_ptr, > - (void *)arg, ODP_THREAD_WORKER); > - > - return 0; > -} > - > -/** exit from test thread */ > -int odp_test_thread_exit(pthrd_arg *arg) > -{ > - /* Wait for other threads to exit */ > - odph_linux_pthread_join(thread_tbl, arg->numthrds); > - > - return 0; > -} > diff --git a/test/api_test/odp_common.h b/test/api_test/odp_common.h > deleted file mode 100644 > index f321b6b..0000000 > --- a/test/api_test/odp_common.h > +++ /dev/null > @@ -1,42 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/** > - * @file > - * > - * ODP test application common headers > - */ > - > -#ifndef ODP_COMMON_H > -#define ODP_COMMON_H > - > -#define MAX_WORKERS 32 /**< Maximum number of work threads */ > - > -/** types of tests */ > -typedef enum { > - ODP_ATOMIC_TEST = 0, > - ODP_SHM_TEST, > - ODP_RING_TEST_BASIC, > - ODP_RING_TEST_STRESS, > - ODP_TIMER_PING_TEST, > - ODP_MAX_TEST > -} odp_test_case_e; > - > -/** > - * Thread argument > - */ > -typedef struct { > - int testcase; /**< specifies which set of API's to exercise */ > - int numthrds; /**< no of pthreads to create */ > -} pthrd_arg; > - > -extern void odp_print_system_info(void); > -extern int odp_test_global_init(void); > -/** create thread fro start_routine function */ > -extern int odp_test_thread_create(void *(*start_routine) (void *), > pthrd_arg *); > -extern int odp_test_thread_exit(pthrd_arg *); > - > -#endif /* ODP_COMMON_H */ > diff --git a/test/api_test/odp_ring_test.c b/test/api_test/odp_ring_test.c > deleted file mode 100644 > index e8a962a..0000000 > --- a/test/api_test/odp_ring_test.c > +++ /dev/null > @@ -1,470 +0,0 @@ > -/* Copyright (c) 2014, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/*- > - * BSD LICENSE > - * > - * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. > - * All rights reserved. > - * > - * Redistribution and use in source and binary forms, with or without > - * modification, are permitted provided that the following conditions > - * are met: > - * > - * * Redistributions of source code must retain the above copyright > - * notice, this list of conditions and the following disclaimer. > - * * 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. > - * * Neither the name of Intel Corporation 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. > - */ > - > - > -/** > - * @file > - * > - * ODP test ring > - */ > - > -#include <stdlib.h> > -#include <stdio.h> > -#include <string.h> > -#include <odp.h> > -#include <odp_common.h> > -#include <odp/helper/ring.h> > -#include <test_debug.h> > - > -#define RING_SIZE 4096 > -#define MAX_BULK 32 > - > -#define RING_TEST_BASIC > - > -static int test_ring_basic(odph_ring_t *r) > -{ > - void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = > NULL; > - int ret; > - unsigned i, num_elems; > - > - /* alloc dummy object pointers */ > - src = malloc(RING_SIZE*2*sizeof(void *)); > - if (src == NULL) { > - LOG_ERR("failed to allocate test ring src memory\n"); > - goto fail; > - } > - for (i = 0; i < RING_SIZE*2; i++) > - src[i] = (void *)(unsigned long)i; > - > - cur_src = src; > - > - /* alloc some room for copied objects */ > - dst = malloc(RING_SIZE*2*sizeof(void *)); > - if (dst == NULL) { > - LOG_ERR("failed to allocate test ring dst memory\n"); > - goto fail; > - } > - > - memset(dst, 0, RING_SIZE*2*sizeof(void *)); > - cur_dst = dst; > - > - printf("Test SP & SC basic functions\n"); > - printf("enqueue 1 obj\n"); > - ret = odph_ring_sp_enqueue_burst(r, cur_src, 1); > - cur_src += 1; > - if ((ret & ODPH_RING_SZ_MASK) != 1) { > - LOG_ERR("sp_enq for 1 obj failed\n"); > - goto fail; > - } > - > - printf("enqueue 2 objs\n"); > - ret = odph_ring_sp_enqueue_burst(r, cur_src, 2); > - cur_src += 2; > - if ((ret & ODPH_RING_SZ_MASK) != 2) { > - LOG_ERR("sp_enq for 2 obj failed\n"); > - goto fail; > - } > - > - printf("enqueue MAX_BULK objs\n"); > - ret = odph_ring_sp_enqueue_burst(r, cur_src, MAX_BULK); > - if ((ret & ODPH_RING_SZ_MASK) != MAX_BULK) { > - LOG_ERR("sp_enq for %d obj failed\n", MAX_BULK); > - goto fail; > - } > - > - printf("dequeue 1 obj\n"); > - ret = odph_ring_sc_dequeue_burst(r, cur_dst, 1); > - cur_dst += 1; > - if ((ret & ODPH_RING_SZ_MASK) != 1) { > - LOG_ERR("sc_deq for 1 obj failed\n"); > - goto fail; > - } > - > - printf("dequeue 2 objs\n"); > - ret = odph_ring_sc_dequeue_burst(r, cur_dst, 2); > - cur_dst += 2; > - if ((ret & ODPH_RING_SZ_MASK) != 2) { > - LOG_ERR("sc_deq for 2 obj failed\n"); > - goto fail; > - } > - > - printf("dequeue MAX_BULK objs\n"); > - ret = odph_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK); > - cur_dst += MAX_BULK; > - if ((ret & ODPH_RING_SZ_MASK) != MAX_BULK) { > - LOG_ERR("sc_deq for %d obj failed\n", MAX_BULK); > - goto fail; > - } > - > - /* check data */ > - if (memcmp(src, dst, cur_dst - dst)) { > - LOG_ERR("data after dequeue is not the same\n"); > - goto fail; > - } > - > - cur_src = src; > - cur_dst = dst; > - > - printf("Test MP & MC basic functions\n"); > - > - printf("enqueue 1 obj\n"); > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, 1); > - cur_src += 1; > - if (ret != 0) { > - LOG_ERR("mp_enq for 1 obj failed\n"); > - goto fail; > - } > - printf("enqueue 2 objs\n"); > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, 2); > - cur_src += 2; > - if (ret != 0) { > - LOG_ERR("mp_enq for 2 obj failed\n"); > - goto fail; > - } > - printf("enqueue MAX_BULK objs\n"); > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK); > - if (ret != 0) { > - LOG_ERR("mp_enq for %d obj failed\n", MAX_BULK); > - goto fail; > - } > - printf("dequeue 1 obj\n"); > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, 1); > - cur_dst += 1; > - if (ret != 0) { > - LOG_ERR("mc_deq for 1 obj failed\n"); > - goto fail; > - } > - printf("dequeue 2 objs\n"); > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, 2); > - cur_dst += 2; > - if (ret != 0) { > - LOG_ERR("mc_deq for 2 obj failed\n"); > - goto fail; > - } > - printf("dequeue MAX_BULK objs\n"); > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK); > - cur_dst += MAX_BULK; > - if (ret != 0) { > - LOG_ERR("mc_deq for %d obj failed\n", MAX_BULK); > - goto fail; > - } > - /* check data */ > - if (memcmp(src, dst, cur_dst - dst)) { > - LOG_ERR("data after dequeue is not the same\n"); > - goto fail; > - } > - > - printf("test watermark and default bulk enqueue / dequeue\n"); > - odph_ring_set_water_mark(r, 20); > - num_elems = 16; > - > - cur_src = src; > - cur_dst = dst; > - > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, num_elems); > - cur_src += num_elems; > - if (ret != 0) { > - LOG_ERR("Cannot enqueue\n"); > - goto fail; > - } > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, num_elems); > - if (ret != -EDQUOT) { > - LOG_ERR("Watermark not exceeded\n"); > - goto fail; > - } > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, num_elems); > - cur_dst += num_elems; > - if (ret != 0) { > - LOG_ERR("Cannot dequeue\n"); > - goto fail; > - } > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, num_elems); > - cur_dst += num_elems; > - if (ret != 0) { > - LOG_ERR("Cannot dequeue2\n"); > - goto fail; > - } > - > - /* check data */ > - if (memcmp(src, dst, cur_dst - dst)) { > - LOG_ERR("data after dequeue is not the same\n"); > - goto fail; > - } > - > - printf("basic enqueu, dequeue test for ring <%s>@%p passed\n", > - r->name, r); > - > - free(src); > - free(dst); > - return 0; > - > -fail: > - free(src); > - free(dst); > - return -1; > -} > - > -/* global shared ring used for stress testing */ > -static odph_ring_t *r_stress; > - > -/* Stress func for Multi producer only */ > -static int producer_fn(void) > -{ > - unsigned i; > - > - void **src = NULL; > - > - /* alloc dummy object pointers */ > - src = malloc(MAX_BULK*2*sizeof(void *)); > - if (src == NULL) { > - LOG_ERR("failed to allocate producer memory.\n"); > - return -1; > - } > - for (i = 0; i < MAX_BULK; i++) > - src[i] = (void *)(unsigned long)i; > - > - do { > - i = odph_ring_mp_enqueue_bulk(r_stress, src, MAX_BULK); > - if (i == 0) { > - free(src); > - return 0; > - } > - } while (1); > -} > - > -/* Stress func for Multi consumer only */ > -static int consumer_fn(void) > -{ > - unsigned i; > - void **src = NULL; > - > - /* alloc dummy object pointers */ > - src = malloc(MAX_BULK*2*sizeof(void *)); > - if (src == NULL) { > - LOG_ERR("failed to allocate consumer memory.\n"); > - return -1; > - } > - > - do { > - i = odph_ring_mc_dequeue_bulk(r_stress, src, MAX_BULK); > - if (i == 0) { > - for (i = 0; i < MAX_BULK; i++) { > - if (src[i] != (void *)(unsigned long)i) { > - free(src); > - printf("data mismatch.. lockless > ops fail\n"); > - return -1; > - } > - } > - free(src); > - printf("\n Test OK !\n"); > - return 0; > - } > - } while (1); > -} > - > - > -/* > - * Note : make sure that both enqueue and dequeue > - * operation starts at same time so to avoid data corruption > - * Its because atomic lock will protect only indexes, but if order of > - * read or write operation incorrect then data mismatch will happen > - * So its resposibility of application develop to take care of order of > - * data read or write. > -*/ > -typedef enum { > - one_enq_one_deq, /* One thread to enqueue one to > - dequeu at same time */ > - one_enq_rest_deq, /* one thread to enq rest to > - dequeue at same time */ > - one_deq_rest_enq, /* one to deq and rest enq at very same > time */ > - multi_enq_multi_deq /* multiple enq,deq */ > -} stress_type_t; > - > -static void test_ring_stress(stress_type_t type) > -{ > - int thr; > - thr = odp_thread_id(); > - > - switch (type) { > - case one_enq_one_deq: > - > - if (thr == 1) > - producer_fn(); > - if (thr == 2) > - consumer_fn(); > - break; > - > - case multi_enq_multi_deq: > - if (thr%2 == 0) > - producer_fn(); > - else > - consumer_fn(); > - break; > - > - case one_deq_rest_enq: > - case one_enq_rest_deq:/*TBD*/ > - default: > - LOG_ERR("Invalid stress type or test case yet not > supported\n"); > - } > -} > - > -/* local struct for ring_thread argument */ > -typedef struct { > - pthrd_arg thrdarg; > - int stress_type; > -} ring_arg_t; > - > - > -static void *test_ring(void *arg) > -{ > - ring_arg_t *parg = (ring_arg_t *)arg; > - int thr; > - char ring_name[ODPH_RING_NAMESIZE]; > - odph_ring_t *r; > - int result = 0; > - > - thr = odp_thread_id(); > - > - printf("Thread %i starts\n", thr); > - > - switch (parg->thrdarg.testcase) { > - case ODP_RING_TEST_BASIC: > - snprintf(ring_name, sizeof(ring_name), "test_ring_%i", > thr); > - > - r = odph_ring_create(ring_name, RING_SIZE, > - 0 /* not used, alignement > - taken care inside func : todo */); > - if (r == NULL) { > - LOG_ERR("ring create failed\n"); > - result = -1; > - break; > - } > - /* lookup ring from its name */ > - if (odph_ring_lookup(ring_name) != r) { > - LOG_ERR("ring lookup failed\n"); > - result = -1; > - break; > - } > - > - /* basic operations */ > - if (test_ring_basic(r) < 0) { > - LOG_ERR("ring basic enqueue/dequeu ops failed\n"); > - result = -1; > - } > - > - /* dump ring stats */ > - odph_ring_list_dump(); > - > - break; > - > - case ODP_RING_TEST_STRESS: > - test_ring_stress(parg->stress_type); > - > - /* dump ring stats */ > - odph_ring_list_dump(); > - break; > - > - default: > - LOG_ERR("Invalid test case [%d]\n", > parg->thrdarg.testcase); > - result = -1; > - break; > - } > - > - LOG_DBG("result = %d\n", result); > - if (result == 0) > - printf("test_ring Result:pass\n"); > - else > - printf("test_ring Result:fail\n"); > - > - fflush(stdout); > - > - return parg; > -} > - > - > -int main(int argc __attribute__((__unused__)), > - char *argv[] __attribute__((__unused__))) > -{ > - ring_arg_t rarg; > - > - if (odp_test_global_init() != 0) > - return -1; > - > - odp_print_system_info(); > - > - odph_ring_tailq_init(); > - > - rarg.thrdarg.numthrds = odp_cpu_count(); > - > -#ifdef RING_TEST_BASIC > - rarg.thrdarg.testcase = ODP_RING_TEST_BASIC; > -#else > - rarg.thrdarg.testcase = ODP_RING_TEST_STRESS; > - rarg.stress_type = one_enq_one_deq; > -/* rarg.stress_type = multi_enq_multi_deq;*/ > - char ring_name[ODPH_RING_NAMESIZE]; > - > - printf("starting stess test type : %d..\n", rarg.stress_type); > - /* create a ring */ > - snprintf(ring_name, sizeof(ring_name), "test_ring_stress"); > - > - r_stress = odph_ring_create(ring_name, RING_SIZE, > - 0 /* not used, alignement > - taken care inside func : todo */); > - if (r_stress == NULL) { > - LOG_ERR("ring create failed\n"); > - goto fail; > - } > - /* lookup ring from its name */ > - if (odph_ring_lookup(ring_name) != r_stress) { > - LOG_ERR("ring lookup failed\n"); > - goto fail; > - } > -#endif > - odp_test_thread_create(test_ring, (pthrd_arg *)&rarg); > - > -#ifndef RING_TEST_BASIC > -fail: > -#endif > - > - odp_test_thread_exit(&rarg.thrdarg); > - > - return 0; > -} > - > -- > 2.7.1.250.gff4ea60 > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > https://lists.linaro.org/mailman/listinfo/lng-odp > -- Mike Holmes Technical Manager - Linaro Networking Group Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs "Work should be fun and collborative, the rest follows"
merged, Maxim. On 02/17/16 21:20, Mike Holmes wrote: > > > On 17 February 2016 at 05:16, Maxim Uvarov <maxim.uvarov@linaro.org > <mailto:maxim.uvarov@linaro.org>> wrote: > > Remove ring and dead api-next code. In api-next pktio ipc patches > moved ring code to linux-generic and updated that test case to > the latest odp api. If we ipc pktio will be accepted to master > than current api-next ring test will be used. > > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org > <mailto:maxim.uvarov@linaro.org>> > > > Reviewed-by Mike Holmes <mike.holmes@linaro.org > <mailto:mike.holmes@linaro.org>> > > --- > configure.ac <http://configure.ac> | 1 - > helper/Makefile.am | 2 - > helper/include/odp/helper/ring.h | 577 > ----------------------------------- > helper/ring.c | 634 > --------------------------------------- > test/Makefile.am | 2 +- > test/api_test/.gitignore | 2 - > test/api_test/Makefile.am | 16 - > test/api_test/odp_common.c | 91 ------ > test/api_test/odp_common.h | 42 --- > test/api_test/odp_ring_test.c | 470 ----------------------------- > 10 files changed, 1 insertion(+), 1836 deletions(-) > delete mode 100644 helper/include/odp/helper/ring.h > delete mode 100644 helper/ring.c > delete mode 100644 test/api_test/.gitignore > delete mode 100644 test/api_test/Makefile.am > delete mode 100644 test/api_test/odp_common.c > delete mode 100644 test/api_test/odp_common.h > delete mode 100644 test/api_test/odp_ring_test.c > > diff --git a/configure.ac <http://configure.ac> b/configure.ac > <http://configure.ac> > index 8108ff2..a7cb035 100644 > --- a/configure.ac <http://configure.ac> > +++ b/configure.ac <http://configure.ac> > @@ -336,7 +336,6 @@ AC_CONFIG_FILES([Makefile > pkgconfig/libodphelper.pc > scripts/Makefile > test/Makefile > - test/api_test/Makefile > test/performance/Makefile > test/validation/Makefile > test/validation/atomic/Makefile > diff --git a/helper/Makefile.am b/helper/Makefile.am > index a8665b2..6557793 100644 > --- a/helper/Makefile.am > +++ b/helper/Makefile.am > @@ -10,7 +10,6 @@ AM_CFLAGS += -I$(top_srcdir)/include > > helperincludedir = $(includedir)/odp/helper/ > helperinclude_HEADERS = \ > - $(srcdir)/include/odp/helper/ring.h \ > $(srcdir)/include/odp/helper/linux.h \ > $(srcdir)/include/odp/helper/chksum.h\ > $(srcdir)/include/odp/helper/eth.h\ > @@ -30,7 +29,6 @@ noinst_HEADERS = \ > > __LIB__libodphelper_la_SOURCES = \ > linux.c \ > - ring.c \ > hashtable.c \ > lineartable.c > > diff --git a/helper/include/odp/helper/ring.h > b/helper/include/odp/helper/ring.h > deleted file mode 100644 > index 65c32ad..0000000 > --- a/helper/include/odp/helper/ring.h > +++ /dev/null > @@ -1,577 +0,0 @@ > -/* Copyright (c) 2014, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/*- > - * BSD LICENSE > - * > - * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. > - * All rights reserved. > - * > - * Redistribution and use in source and binary forms, with or > without > - * modification, are permitted provided that the following > conditions > - * are met: > - * > - * * Redistributions of source code must retain the above > copyright > - * notice, this list of conditions and the following > disclaimer. > - * * 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. > - * * Neither the name of Intel Corporation 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. > - */ > - > -/* > - * Derived from FreeBSD's bufring.c > - * > - > ************************************************************************** > - * > - * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org > <mailto:kmacy@freebsd.org> > - * All rights reserved. > - * > - * 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. The name of Kip Macy nor the names of other > - * 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. > - * > - > ***************************************************************************/ > - > -/** > - * ODP Ring > - * > - * The Ring Manager is a fixed-size queue, implemented as a table of > - * pointers. Head and tail pointers are modified atomically, allowing > - * concurrent access to it. It has the following features: > - * > - * - FIFO (First In First Out) > - * - Maximum size is fixed; the pointers are stored in a table. > - * - Lockless implementation. > - * - Multi- or single-consumer dequeue. > - * - Multi- or single-producer enqueue. > - * - Bulk dequeue. > - * - Bulk enqueue. > - * > - * Note: the ring implementation is not preemptable. A lcore must not > - * be interrupted by another task that uses the same ring. > - * > - */ > - > -#ifndef ODPH_RING_H_ > -#define ODPH_RING_H_ > - > -#ifdef __cplusplus > -extern "C" { > -#endif > - > - > -#include <odp/std_types.h> > -#include <odp/hints.h> > -#include <odp/atomic.h> > -#include <errno.h> > -#include <sys/queue.h> > - > -enum odph_ring_queue_behavior { > - ODPH_RING_QUEUE_FIXED = 0, /**< Enq/Deq a fixed number > - of items from a ring */ > - ODPH_RING_QUEUE_VARIABLE /**< Enq/Deq as many items > - a possible from ring */ > -}; > - > - > -#define ODPH_RING_NAMESIZE 32 /**< The maximum length of a ring > name. */ > - > -/** > - * An ODP ring structure. > - * > - * The producer and the consumer have a head and a tail index. > The particularity > - * of these index is that they are not between 0 and size(ring). > These indexes > - * are between 0 and 2^32, and we mask their value when we access > the ring[] > - * field. Thanks to this assumption, we can do subtractions > between 2 index > - * values in a modulo-32bit base: that's why the overflow of the > indexes is not > - * a problem. > - */ > -typedef struct odph_ring { > - /** @private Next in list. */ > - TAILQ_ENTRY(odph_ring) next; > - > - /** @private Name of the ring. */ > - char name[ODPH_RING_NAMESIZE]; > - /** @private Flags supplied at creation. */ > - int flags; > - > - /** @private Producer */ > - struct prod { > - uint32_t watermark; /* Maximum items */ > - uint32_t sp_enqueue; /* True, if single > producer. */ > - uint32_t size; /* Size of ring. */ > - uint32_t mask; /* Mask (size-1) of ring. */ > - uint32_t head; /* Producer head. */ > - uint32_t tail; /* Producer tail. */ > - } prod ODP_ALIGNED_CACHE; > - > - /** @private Consumer */ > - struct cons { > - uint32_t sc_dequeue; /* True, if single > consumer. */ > - uint32_t size; /* Size of the ring. */ > - uint32_t mask; /* Mask (size-1) of ring. */ > - uint32_t head; /* Consumer head. */ > - uint32_t tail; /* Consumer tail. */ > - } cons ODP_ALIGNED_CACHE; > - > - /** @private Memory space of ring starts here. */ > - void *ring[0] ODP_ALIGNED_CACHE; > -} odph_ring_t; > - > - > -#define ODPH_RING_F_SP_ENQ 0x0001 /* The default enqueue is > "single-producer".*/ > -#define ODPH_RING_F_SC_DEQ 0x0002 /* The default dequeue is > "single-consumer".*/ > -#define ODPH_RING_QUOT_EXCEED (1 << 31) /* Quota exceed for > burst ops */ > -#define ODPH_RING_SZ_MASK (unsigned)(0x0fffffff) /* Ring size > mask */ > - > - > -/** > - * Create a new ring named *name* in memory. > - * > - * This function uses odp_shm_reserve() to allocate memory. Its > size is > - * set to *count*, which must be a power of two. Water marking is > - * disabled by default. Note that the real usable ring size is > count-1 > - * instead of count. > - * > - * @param name > - * The name of the ring. > - * @param count > - * The size of the ring (must be a power of 2). > - * @param socket_id (dummy, not included : todo) > - * @param flags > - * An OR of the following: > - * - RING_F_SP_ENQ: If this flag is set, the default behavior when > - * using ``odp_ring_enqueue()`` or ``odp_ring_enqueue_bulk()`` > - * is "single-producer". Otherwise, it is "multi-producers". > - * - RING_F_SC_DEQ: If this flag is set, the default behavior when > - * using ``odp_ring_dequeue()`` or ``odp_ring_dequeue_bulk()`` > - * is "single-consumer". Otherwise, it is "multi-consumers". > - * @return > - * On success, the pointer to the new allocated ring. NULL on > error with > - * odp_errno set appropriately. Possible errno values include: > - * - EINVAL - count provided is not a power of 2 > - * - ENOSPC - the maximum number of memzones has already been > allocated > - * - EEXIST - a memzone with the same name already exists > - * - ENOMEM - no appropriate memory area found in which to > create memzone > - */ > -odph_ring_t *odph_ring_create(const char *name, unsigned count, > - unsigned flags); > - > - > -/** > - * Change the high water mark. > - * > - * If *count* is 0, water marking is disabled. Otherwise, it is > set to the > - * *count* value. The *count* value must be greater than 0 and less > - * than the ring size. > - * > - * This function can be called at any time (not necessarily at > - * initialization). > - * > - * @param r Pointer to the ring structure. > - * @param count New water mark value. > - * @return 0: Success; water mark changed. > - * -EINVAL: Invalid water mark value. > - */ > -int odph_ring_set_water_mark(odph_ring_t *r, unsigned count); > - > -/** > - * Dump the status of the ring to the console. > - * > - * @param r A pointer to the ring structure. > - */ > -void odph_ring_dump(const odph_ring_t *r); > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - * > - * This function uses a "compare and set" instruction to move the > - * producer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @param behavior > - * ODP_RING_QUEUE_FIXED: Enqueue a fixed number of items > from a ring > - * ODP_RING_QUEUE_VARIABLE: Enqueue as many items a possible > from ring > - * @return > - * Depend on the behavior value > - * if behavior = ODP_RING_QUEUE_FIXED > - * - 0: Success; objects enqueue. > - * - -EDQUOT: Quota exceeded. The objects have been enqueued, > but the > - * high water mark is exceeded. > - * - -ENOBUFS: Not enough room in the ring to enqueue, no > object is enqueued. > - * if behavior = ODP_RING_QUEUE_VARIABLE > - * - n: Actual number of objects enqueued. > - */ > -int __odph_ring_mp_do_enqueue(odph_ring_t *r, void * const > *obj_table, > - unsigned n, > - enum odph_ring_queue_behavior behavior); > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @param behavior > - * ODP_RING_QUEUE_FIXED: Enqueue a fixed number of items > from a ring > - * ODP_RING_QUEUE_VARIABLE: Enqueue as many items a possible > from ring > - * @return > - * Depend on the behavior value > - * if behavior = ODP_RING_QUEUE_FIXED > - * - 0: Success; objects enqueue. > - * - -EDQUOT: Quota exceeded. The objects have been enqueued, > but the > - * high water mark is exceeded. > - * - -ENOBUFS: Not enough room in the ring to enqueue, no > object is enqueued. > - * if behavior = ODP_RING_QUEUE_VARIABLE > - * - n: Actual number of objects enqueued. > - */ > -int __odph_ring_sp_do_enqueue(odph_ring_t *r, void * const > *obj_table, > - unsigned n, > - enum odph_ring_queue_behavior behavior); > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). When > - * the request objects are more than the available objects, only > dequeue the > - * actual number of objects > - * > - * This function uses a "compare and set" instruction to move the > - * consumer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will > be filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @param behavior > - * ODP_RING_QUEUE_FIXED: Dequeue a fixed number of items > from a ring > - * ODP_RING_QUEUE_VARIABLE: Dequeue as many items a possible > from ring > - * @return > - * Depend on the behavior value > - * if behavior = ODP_RING_QUEUE_FIXED > - * - 0: Success; objects dequeued. > - * - -ENOENT: Not enough entries in the ring to dequeue; no > object is > - * dequeued. > - * if behavior = ODP_RING_QUEUE_VARIABLE > - * - n: Actual number of objects dequeued. > - */ > - > -int __odph_ring_mc_do_dequeue(odph_ring_t *r, void **obj_table, > - unsigned n, > - enum odph_ring_queue_behavior behavior); > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - * When the request objects are more than the available objects, > only dequeue > - * the actual number of objects > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will > be filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @param behavior > - * ODP_RING_QUEUE_FIXED: Dequeue a fixed number of items > from a ring > - * ODP_RING_QUEUE_VARIABLE: Dequeue as many items a possible > from ring > - * @return > - * Depend on the behavior value > - * if behavior = ODP_RING_QUEUE_FIXED > - * - 0: Success; objects dequeued. > - * - -ENOENT: Not enough entries in the ring to dequeue; no > object is > - * dequeued. > - * if behavior = ODP_RING_QUEUE_VARIABLE > - * - n: Actual number of objects dequeued. > - */ > -int __odph_ring_sc_do_dequeue(odph_ring_t *r, void **obj_table, > - unsigned n, > - enum odph_ring_queue_behavior behavior); > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - * > - * This function uses a "compare and set" instruction to move the > - * producer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - 0: Success; objects enqueue. > - * - -EDQUOT: Quota exceeded. The objects have been enqueued, > but the > - * high water mark is exceeded. > - * - -ENOBUFS: Not enough room in the ring to enqueue, no > object is enqueued. > - */ > -int odph_ring_mp_enqueue_bulk(odph_ring_t *r, void * const > *obj_table, > - unsigned n); > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - 0: Success; objects enqueued. > - * - -EDQUOT: Quota exceeded. The objects have been enqueued, > but the > - * high water mark is exceeded. > - * - -ENOBUFS: Not enough room in the ring to enqueue; no > object is enqueued. > - */ > -int odph_ring_sp_enqueue_bulk(odph_ring_t *r, void * const > *obj_table, > - unsigned n); > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). > - * > - * This function uses a "compare and set" instruction to move the > - * consumer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will > be filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @return > - * - 0: Success; objects dequeued. > - * - -ENOENT: Not enough entries in the ring to dequeue; no > object is > - * dequeued. > - */ > -int odph_ring_mc_dequeue_bulk(odph_ring_t *r, void **obj_table, > unsigned n); > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will > be filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table, > - * must be strictly positive. > - * @return > - * - 0: Success; objects dequeued. > - * - -ENOENT: Not enough entries in the ring to dequeue; no > object is > - * dequeued. > - */ > -int odph_ring_sc_dequeue_bulk(odph_ring_t *r, void **obj_table, > unsigned n); > - > -/** > - * Test if a ring is full. > - * > - * @param r > - * A pointer to the ring structure. > - * @return > - * - 1: The ring is full. > - * - 0: The ring is not full. > - */ > -int odph_ring_full(const odph_ring_t *r); > - > -/** > - * Test if a ring is empty. > - * > - * @param r > - * A pointer to the ring structure. > - * @return > - * - 1: The ring is empty. > - * - 0: The ring is not empty. > - */ > -int odph_ring_empty(const odph_ring_t *r); > - > -/** > - * Return the number of entries in a ring. > - * > - * @param r > - * A pointer to the ring structure. > - * @return > - * The number of entries in the ring. > - */ > -unsigned odph_ring_count(const odph_ring_t *r); > - > -/** > - * Return the number of free entries in a ring. > - * > - * @param r > - * A pointer to the ring structure. > - * @return > - * The number of free entries in the ring. > - */ > -unsigned odph_ring_free_count(const odph_ring_t *r); > - > -/** > - * search ring by name > - * @param name ring name to search > - * @return pointer to ring otherwise NULL > - */ > -odph_ring_t *odph_ring_lookup(const char *name); > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - * > - * This function uses a "compare and set" instruction to move the > - * producer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - n: Actual number of objects enqueued. > - */ > -int odph_ring_mp_enqueue_burst(odph_ring_t *r, void * const > *obj_table, > - unsigned n); > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - n: Actual number of objects enqueued. > - */ > -int odph_ring_sp_enqueue_burst(odph_ring_t *r, void * const > *obj_table, > - unsigned n); > -/** > - * Enqueue several objects on a ring. > - * > - * This function calls the multi-producer or the single-producer > - * version depending on the default behavior that was specified at > - * ring creation time (see flags). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects). > - * @param n > - * The number of objects to add in the ring from the obj_table. > - * @return > - * - n: Actual number of objects enqueued. > - */ > -int odph_ring_enqueue_burst(odph_ring_t *r, void * const *obj_table, > - unsigned n); > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). > When the request > - * objects are more than the available objects, only dequeue the > actual number > - * of objects > - * > - * This function uses a "compare and set" instruction to move the > - * consumer index atomically. > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will > be filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @return > - * - n: Actual number of objects dequeued, 0 if ring is empty > - */ > -int odph_ring_mc_dequeue_burst(odph_ring_t *r, void **obj_table, > unsigned n); > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers > safe).When the > - * request objects are more than the available objects, only > dequeue the > - * actual number of objects > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will > be filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @return > - * - n: Actual number of objects dequeued, 0 if ring is empty > - */ > -int odph_ring_sc_dequeue_burst(odph_ring_t *r, void **obj_table, > unsigned n); > - > -/** > - * Dequeue multiple objects from a ring up to a maximum number. > - * > - * This function calls the multi-consumers or the single-consumer > - * version, depending on the default behaviour that was specified at > - * ring creation time (see flags). > - * > - * @param r > - * A pointer to the ring structure. > - * @param obj_table > - * A pointer to a table of void * pointers (objects) that will > be filled. > - * @param n > - * The number of objects to dequeue from the ring to the obj_table. > - * @return > - * - Number of objects dequeued, or a negative error code on error > - */ > -int odph_ring_dequeue_burst(odph_ring_t *r, void **obj_table, > unsigned n); > - > -/** > - * dump the status of all rings on the console > - */ > -void odph_ring_list_dump(void); > - > -/** > - * initialise ring tailq > - */ > -void odph_ring_tailq_init(void); > - > -#ifdef __cplusplus > -} > -#endif > - > -#endif > diff --git a/helper/ring.c b/helper/ring.c > deleted file mode 100644 > index 6699186..0000000 > --- a/helper/ring.c > +++ /dev/null > @@ -1,634 +0,0 @@ > -/* Copyright (c) 2014, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/*- > - * BSD LICENSE > - * > - * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. > - * All rights reserved. > - * > - * Redistribution and use in source and binary forms, with or > without > - * modification, are permitted provided that the following > conditions > - * are met: > - * > - * * Redistributions of source code must retain the above > copyright > - * notice, this list of conditions and the following > disclaimer. > - * * 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. > - * * Neither the name of Intel Corporation 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. > - */ > - > -/* > - * Derived from FreeBSD's bufring.c > - * > - > ************************************************************************** > - * > - * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org > <mailto:kmacy@freebsd.org> > - * All rights reserved. > - * > - * 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. The name of Kip Macy nor the names of other > - * 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. > - * > - > ***************************************************************************/ > - > -#include <odp.h> > -#include <fcntl.h> > -#include <stdio.h> > -#include <string.h> > -#include "odph_debug.h" > -#include <odp/helper/ring.h> > - > -static TAILQ_HEAD(, odph_ring) odp_ring_list; > - > -#define RING_VAL_IS_POWER_2(x) ((((x) - 1) & (x)) == 0) > - > -/* > - * the enqueue of pointers on the ring. > - */ > -#define ENQUEUE_PTRS() do { \ > - const uint32_t size = r->prod.size; \ > - uint32_t idx = prod_head & mask; \ > - if (odp_likely(idx + n < size)) { \ > - for (i = 0; i < (n & ((~(unsigned)0x3))); i += 4, > idx += 4) { \ > - r->ring[idx] = obj_table[i]; \ > - r->ring[idx+1] = obj_table[i+1]; \ > - r->ring[idx+2] = obj_table[i+2]; \ > - r->ring[idx+3] = obj_table[i+3]; \ > - } \ > - switch (n & 0x3) { \ > - case 3: \ > - r->ring[idx++] = obj_table[i++]; \ > - case 2: \ > - r->ring[idx++] = obj_table[i++]; \ > - case 1: \ > - r->ring[idx++] = obj_table[i++]; \ > - } \ > - } else { \ > - for (i = 0; idx < size; i++, idx++)\ > - r->ring[idx] = obj_table[i]; \ > - for (idx = 0; i < n; i++, idx++) \ > - r->ring[idx] = obj_table[i]; \ > - } \ > -} while (0) > - > -/* > - * the actual copy of pointers on the ring to obj_table. > - */ > -#define DEQUEUE_PTRS() do { \ > - uint32_t idx = cons_head & mask; \ > - const uint32_t size = r->cons.size; \ > - if (odp_likely(idx + n < size)) { \ > - for (i = 0; i < (n & (~(unsigned)0x3)); i += 4, > idx += 4) {\ > - obj_table[i] = r->ring[idx]; \ > - obj_table[i+1] = r->ring[idx+1]; \ > - obj_table[i+2] = r->ring[idx+2]; \ > - obj_table[i+3] = r->ring[idx+3]; \ > - } \ > - switch (n & 0x3) { \ > - case 3: \ > - obj_table[i++] = r->ring[idx++]; \ > - case 2: \ > - obj_table[i++] = r->ring[idx++]; \ > - case 1: \ > - obj_table[i++] = r->ring[idx++]; \ > - } \ > - } else { \ > - for (i = 0; idx < size; i++, idx++) \ > - obj_table[i] = r->ring[idx]; \ > - for (idx = 0; i < n; i++, idx++) \ > - obj_table[i] = r->ring[idx]; \ > - } \ > -} while (0) > - > -static odp_rwlock_t qlock; /* rings tailq lock */ > - > -/* init tailq_ring */ > -void odph_ring_tailq_init(void) > -{ > - TAILQ_INIT(&odp_ring_list); > - odp_rwlock_init(&qlock); > -} > - > -/* create the ring */ > -odph_ring_t * > -odph_ring_create(const char *name, unsigned count, unsigned flags) > -{ > - char ring_name[ODPH_RING_NAMESIZE]; > - odph_ring_t *r; > - size_t ring_size; > - odp_shm_t shm; > - > - /* count must be a power of 2 */ > - if (!RING_VAL_IS_POWER_2(count) || (count > > ODPH_RING_SZ_MASK)) { > - ODPH_ERR("Requested size is invalid, must be power > of 2, and do not exceed the size limit %u\n", > - ODPH_RING_SZ_MASK); > - return NULL; > - } > - > - snprintf(ring_name, sizeof(ring_name), "%s", name); > - ring_size = count*sizeof(void *)+sizeof(odph_ring_t); > - > - odp_rwlock_write_lock(&qlock); > - /* reserve a memory zone for this ring.*/ > - shm = odp_shm_reserve(ring_name, ring_size, > ODP_CACHE_LINE_SIZE, 0); > - > - r = odp_shm_addr(shm); > - > - if (r != NULL) { > - /* init the ring structure */ > - snprintf(r->name, sizeof(r->name), "%s", name); > - r->flags = flags; > - r->prod.watermark = count; > - r->prod.sp_enqueue = !!(flags & ODPH_RING_F_SP_ENQ); > - r->cons.sc_dequeue = !!(flags & ODPH_RING_F_SC_DEQ); > - r->prod.size = count; > - r->cons.size = count; > - r->prod.mask = count-1; > - r->cons.mask = count-1; > - r->prod.head = 0; > - r->cons.head = 0; > - r->prod.tail = 0; > - r->cons.tail = 0; > - > - TAILQ_INSERT_TAIL(&odp_ring_list, r, next); > - } else { > - ODPH_ERR("Cannot reserve memory\n"); > - } > - > - odp_rwlock_write_unlock(&qlock); > - return r; > -} > - > -/* > - * change the high water mark. If *count* is 0, water marking is > - * disabled > - */ > -int odph_ring_set_water_mark(odph_ring_t *r, unsigned count) > -{ > - if (count >= r->prod.size) > - return -EINVAL; > - > - /* if count is 0, disable the watermarking */ > - if (count == 0) > - count = r->prod.size; > - > - r->prod.watermark = count; > - return 0; > -} > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - */ > -int __odph_ring_mp_do_enqueue(odph_ring_t *r, void * const > *obj_table, > - unsigned n, enum odph_ring_queue_behavior > behavior) > -{ > - uint32_t prod_head, prod_next; > - uint32_t cons_tail, free_entries; > - const unsigned max = n; > - int success; > - unsigned i; > - uint32_t mask = r->prod.mask; > - int ret; > - > - /* move prod.head atomically */ > - do { > - /* Reset n to the initial burst count */ > - n = max; > - > - prod_head = r->prod.head; > - cons_tail = r->cons.tail; > - /* The subtraction is done between two unsigned > 32bits value > - * (the result is always modulo 32 bits even if we > have > - * prod_head > cons_tail). So 'free_entries' is > always between 0 > - * and size(ring)-1. */ > - free_entries = (mask + cons_tail - prod_head); > - > - /* check that we have enough room in ring */ > - if (odp_unlikely(n > free_entries)) { > - if (behavior == ODPH_RING_QUEUE_FIXED) { > - return -ENOBUFS; > - } else { > - /* No free entry available */ > - if (odp_unlikely(free_entries == 0)) > - return 0; > - > - n = free_entries; > - } > - } > - > - prod_next = prod_head + n; > - success = __atomic_compare_exchange_n(&r->prod.head, > - &prod_head, > - prod_next, > - false/*strong*/, > - __ATOMIC_ACQUIRE, > - __ATOMIC_RELAXED); > - } while (odp_unlikely(success == 0)); > - > - /* write entries in ring */ > - ENQUEUE_PTRS(); > - > - /* if we exceed the watermark */ > - if (odp_unlikely(((mask + 1) - free_entries + n) > > r->prod.watermark)) { > - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? -EDQUOT : > - (int)(n | ODPH_RING_QUOT_EXCEED); > - } else { > - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? 0 : n; > - } > - > - /* > - * If there are other enqueues in progress that preceded us, > - * we need to wait for them to complete > - */ > - while (odp_unlikely(r->prod.tail != prod_head)) > - odp_cpu_pause(); > - > - /* Release our entries and the memory they refer to */ > - __atomic_thread_fence(__ATOMIC_RELEASE); > - r->prod.tail = prod_next; > - return ret; > -} > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - */ > -int __odph_ring_sp_do_enqueue(odph_ring_t *r, void * const > *obj_table, > - unsigned n, enum > odph_ring_queue_behavior behavior) > -{ > - uint32_t prod_head, cons_tail; > - uint32_t prod_next, free_entries; > - unsigned i; > - uint32_t mask = r->prod.mask; > - int ret; > - > - prod_head = r->prod.head; > - cons_tail = r->cons.tail; > - /* The subtraction is done between two unsigned 32bits value > - * (the result is always modulo 32 bits even if we have > - * prod_head > cons_tail). So 'free_entries' is always > between 0 > - * and size(ring)-1. */ > - free_entries = mask + cons_tail - prod_head; > - > - /* check that we have enough room in ring */ > - if (odp_unlikely(n > free_entries)) { > - if (behavior == ODPH_RING_QUEUE_FIXED) { > - return -ENOBUFS; > - } else { > - /* No free entry available */ > - if (odp_unlikely(free_entries == 0)) > - return 0; > - > - n = free_entries; > - } > - } > - > - prod_next = prod_head + n; > - r->prod.head = prod_next; > - > - /* write entries in ring */ > - ENQUEUE_PTRS(); > - > - /* if we exceed the watermark */ > - if (odp_unlikely(((mask + 1) - free_entries + n) > > r->prod.watermark)) { > - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? -EDQUOT : > - (int)(n | ODPH_RING_QUOT_EXCEED); > - } else { > - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? 0 : n; > - } > - > - /* Release our entries and the memory they refer to */ > - __atomic_thread_fence(__ATOMIC_RELEASE); > - r->prod.tail = prod_next; > - return ret; > -} > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). > - */ > - > -int __odph_ring_mc_do_dequeue(odph_ring_t *r, void **obj_table, > - unsigned n, enum odph_ring_queue_behavior > behavior) > -{ > - uint32_t cons_head, prod_tail; > - uint32_t cons_next, entries; > - const unsigned max = n; > - int success; > - unsigned i; > - uint32_t mask = r->prod.mask; > - > - /* move cons.head atomically */ > - do { > - /* Restore n as it may change every loop */ > - n = max; > - > - cons_head = r->cons.head; > - prod_tail = r->prod.tail; > - /* The subtraction is done between two unsigned > 32bits value > - * (the result is always modulo 32 bits even if we > have > - * cons_head > prod_tail). So 'entries' is always > between 0 > - * and size(ring)-1. */ > - entries = (prod_tail - cons_head); > - > - /* Set the actual entries for dequeue */ > - if (n > entries) { > - if (behavior == ODPH_RING_QUEUE_FIXED) { > - return -ENOENT; > - } else { > - if (odp_unlikely(entries == 0)) > - return 0; > - > - n = entries; > - } > - } > - > - cons_next = cons_head + n; > - success = __atomic_compare_exchange_n(&r->cons.head, > - &cons_head, > - cons_next, > - false/*strong*/, > - __ATOMIC_ACQUIRE, > - __ATOMIC_RELAXED); > - } while (odp_unlikely(success == 0)); > - > - /* copy in table */ > - DEQUEUE_PTRS(); > - > - /* > - * If there are other dequeues in progress that preceded us, > - * we need to wait for them to complete > - */ > - while (odp_unlikely(r->cons.tail != cons_head)) > - odp_cpu_pause(); > - > - /* Release our entries and the memory they refer to */ > - __atomic_thread_fence(__ATOMIC_RELEASE); > - r->cons.tail = cons_next; > - > - return behavior == ODPH_RING_QUEUE_FIXED ? 0 : n; > -} > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - */ > -int __odph_ring_sc_do_dequeue(odph_ring_t *r, void **obj_table, > - unsigned n, enum > odph_ring_queue_behavior behavior) > -{ > - uint32_t cons_head, prod_tail; > - uint32_t cons_next, entries; > - unsigned i; > - uint32_t mask = r->prod.mask; > - > - cons_head = r->cons.head; > - prod_tail = r->prod.tail; > - /* The subtraction is done between two unsigned 32bits value > - * (the result is always modulo 32 bits even if we have > - * cons_head > prod_tail). So 'entries' is always between 0 > - * and size(ring)-1. */ > - entries = prod_tail - cons_head; > - > - if (n > entries) { > - if (behavior == ODPH_RING_QUEUE_FIXED) { > - return -ENOENT; > - } else { > - if (odp_unlikely(entries == 0)) > - return 0; > - > - n = entries; > - } > - } > - > - cons_next = cons_head + n; > - r->cons.head = cons_next; > - > - /* Acquire the pointers and the memory they refer to */ > - __atomic_thread_fence(__ATOMIC_ACQUIRE); > - /* copy in table */ > - DEQUEUE_PTRS(); > - > - r->cons.tail = cons_next; > - return behavior == ODPH_RING_QUEUE_FIXED ? 0 : n; > -} > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - */ > -int odph_ring_mp_enqueue_bulk(odph_ring_t *r, void * const > *obj_table, > - unsigned n) > -{ > - return __odph_ring_mp_do_enqueue(r, obj_table, n, > - ODPH_RING_QUEUE_FIXED); > -} > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - */ > -int odph_ring_sp_enqueue_bulk(odph_ring_t *r, void * const > *obj_table, > - unsigned n) > -{ > - return __odph_ring_sp_do_enqueue(r, obj_table, n, > - ODPH_RING_QUEUE_FIXED); > -} > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). > - */ > -int odph_ring_mc_dequeue_bulk(odph_ring_t *r, void **obj_table, > unsigned n) > -{ > - return __odph_ring_mc_do_dequeue(r, obj_table, n, > - ODPH_RING_QUEUE_FIXED); > -} > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - */ > -int odph_ring_sc_dequeue_bulk(odph_ring_t *r, void **obj_table, > unsigned n) > -{ > - return __odph_ring_sc_do_dequeue(r, obj_table, n, > - ODPH_RING_QUEUE_FIXED); > -} > - > -/** > - * Test if a ring is full. > - */ > -int odph_ring_full(const odph_ring_t *r) > -{ > - uint32_t prod_tail = r->prod.tail; > - uint32_t cons_tail = r->cons.tail; > - return (((cons_tail - prod_tail - 1) & r->prod.mask) == 0); > -} > - > -/** > - * Test if a ring is empty. > - */ > -int odph_ring_empty(const odph_ring_t *r) > -{ > - uint32_t prod_tail = r->prod.tail; > - uint32_t cons_tail = r->cons.tail; > - return !!(cons_tail == prod_tail); > -} > - > -/** > - * Return the number of entries in a ring. > - */ > -unsigned odph_ring_count(const odph_ring_t *r) > -{ > - uint32_t prod_tail = r->prod.tail; > - uint32_t cons_tail = r->cons.tail; > - return (prod_tail - cons_tail) & r->prod.mask; > -} > - > -/** > - * Return the number of free entries in a ring. > - */ > -unsigned odph_ring_free_count(const odph_ring_t *r) > -{ > - uint32_t prod_tail = r->prod.tail; > - uint32_t cons_tail = r->cons.tail; > - return (cons_tail - prod_tail - 1) & r->prod.mask; > -} > - > -/* dump the status of the ring on the console */ > -void odph_ring_dump(const odph_ring_t *r) > -{ > - ODPH_DBG("ring <%s>@%p\n", r->name, r); > - ODPH_DBG(" flags=%x\n", r->flags); > - ODPH_DBG(" size=%" PRIu32 "\n", r->prod.size); > - ODPH_DBG(" ct=%" PRIu32 "\n", r->cons.tail); > - ODPH_DBG(" ch=%" PRIu32 "\n", r->cons.head); > - ODPH_DBG(" pt=%" PRIu32 "\n", r->prod.tail); > - ODPH_DBG(" ph=%" PRIu32 "\n", r->prod.head); > - ODPH_DBG(" used=%u\n", odph_ring_count(r)); > - ODPH_DBG(" avail=%u\n", odph_ring_free_count(r)); > - if (r->prod.watermark == r->prod.size) > - ODPH_DBG(" watermark=0\n"); > - else > - ODPH_DBG(" watermark=%" PRIu32 "\n", > r->prod.watermark); > -} > - > -/* dump the status of all rings on the console */ > -void odph_ring_list_dump(void) > -{ > - const odph_ring_t *mp = NULL; > - > - odp_rwlock_read_lock(&qlock); > - > - TAILQ_FOREACH(mp, &odp_ring_list, next) { > - odph_ring_dump(mp); > - } > - > - odp_rwlock_read_unlock(&qlock); > -} > - > -/* search a ring from its name */ > -odph_ring_t *odph_ring_lookup(const char *name) > -{ > - odph_ring_t *r; > - > - odp_rwlock_read_lock(&qlock); > - TAILQ_FOREACH(r, &odp_ring_list, next) { > - if (strncmp(name, r->name, ODPH_RING_NAMESIZE) == 0) > - break; > - } > - odp_rwlock_read_unlock(&qlock); > - > - return r; > -} > - > -/** > - * Enqueue several objects on the ring (multi-producers safe). > - */ > -int odph_ring_mp_enqueue_burst(odph_ring_t *r, void * const > *obj_table, > - unsigned n) > -{ > - return __odph_ring_mp_do_enqueue(r, obj_table, n, > - ODPH_RING_QUEUE_VARIABLE); > -} > - > -/** > - * Enqueue several objects on a ring (NOT multi-producers safe). > - */ > -int odph_ring_sp_enqueue_burst(odph_ring_t *r, void * const > *obj_table, > - unsigned n) > -{ > - return __odph_ring_sp_do_enqueue(r, obj_table, n, > - ODPH_RING_QUEUE_VARIABLE); > -} > - > -/** > - * Enqueue several objects on a ring. > - */ > -int odph_ring_enqueue_burst(odph_ring_t *r, void * const *obj_table, > - unsigned n) > -{ > - if (r->prod.sp_enqueue) > - return odph_ring_sp_enqueue_burst(r, obj_table, n); > - else > - return odph_ring_mp_enqueue_burst(r, obj_table, n); > -} > - > -/** > - * Dequeue several objects from a ring (multi-consumers safe). > - */ > -int odph_ring_mc_dequeue_burst(odph_ring_t *r, void **obj_table, > unsigned n) > -{ > - return __odph_ring_mc_do_dequeue(r, obj_table, n, > - ODPH_RING_QUEUE_VARIABLE); > -} > - > -/** > - * Dequeue several objects from a ring (NOT multi-consumers safe). > - */ > -int odph_ring_sc_dequeue_burst(odph_ring_t *r, void **obj_table, > unsigned n) > -{ > - return __odph_ring_sc_do_dequeue(r, obj_table, n, > - ODPH_RING_QUEUE_VARIABLE); > -} > - > -/** > - * Dequeue multiple objects from a ring up to a maximum number. > - */ > -int odph_ring_dequeue_burst(odph_ring_t *r, void **obj_table, > unsigned n) > -{ > - if (r->cons.sc_dequeue) > - return odph_ring_sc_dequeue_burst(r, obj_table, n); > - else > - return odph_ring_mc_dequeue_burst(r, obj_table, n); > -} > diff --git a/test/Makefile.am b/test/Makefile.am > index 2ba8008..4a75364 100644 > --- a/test/Makefile.am > +++ b/test/Makefile.am > @@ -1,4 +1,4 @@ > -SUBDIRS = api_test performance miscellaneous > +SUBDIRS = performance miscellaneous > > if cunit_support > SUBDIRS += validation > diff --git a/test/api_test/.gitignore b/test/api_test/.gitignore > deleted file mode 100644 > index 950f443..0000000 > --- a/test/api_test/.gitignore > +++ /dev/null > @@ -1,2 +0,0 @@ > -odp_ring > -odp_shm > diff --git a/test/api_test/Makefile.am b/test/api_test/Makefile.am > deleted file mode 100644 > index 97ca5df..0000000 > --- a/test/api_test/Makefile.am > +++ /dev/null > @@ -1,16 +0,0 @@ > -include $(top_srcdir)/test/Makefile.inc > - > -bin_PROGRAMS = odp_ring$(EXEEXT) > - > -odp_ring_CFLAGS = $(AM_CFLAGS) > - > -odp_ring_LDFLAGS = $(AM_LDFLAGS) -static > - > -noinst_HEADERS = \ > - $(top_srcdir)/test/api_test/odp_common.h \ > - $(top_srcdir)/test/test_debug.h > - > -dist_odp_ring_SOURCES = odp_ring_test.c odp_common.c > - > -#The tests will need to retain the deprecated test implementation > -AM_CFLAGS += -Wno-deprecated-declarations > \ No newline at end of file > diff --git a/test/api_test/odp_common.c b/test/api_test/odp_common.c > deleted file mode 100644 > index 70aee96..0000000 > --- a/test/api_test/odp_common.c > +++ /dev/null > @@ -1,91 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/** > - * @file > - * > - * ODP test application common > - */ > - > -#include <string.h> > -#include <odp.h> > -#include <odp/helper/linux.h> > -#include <odp_common.h> > -#include <test_debug.h> > - > -#define MAX_WORKERS 32 /**< Max worker > threads */ > - > -/* Globals */ > -static odph_linux_pthread_t thread_tbl[MAX_WORKERS]; /**< worker > threads table*/ > -static int num_workers; /**< number of workers */ > - > -/** > - * Print system information > - */ > -void odp_print_system_info(void) > -{ > - odp_cpumask_t cpumask; > - char str[ODP_CPUMASK_STR_SIZE]; > - > - memset(str, 1, sizeof(str)); > - > - odp_cpumask_zero(&cpumask); > - > - odp_cpumask_from_str(&cpumask, "0x1"); > - (void)odp_cpumask_to_str(&cpumask, str, sizeof(str)); > - > - printf("\n"); > - printf("ODP system info\n"); > - printf("---------------\n"); > - printf("ODP API version: %s\n", odp_version_api_str()); > - printf("CPU model: %s\n", odp_cpu_model_str()); > - printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz_max()); > - printf("Cache line size: %i\n", odp_sys_cache_line_size()); > - printf("CPU count: %i\n", odp_cpu_count()); > - printf("CPU mask: %s\n", str); > - > - printf("\n"); > -} > - > -/** test init globals and call odp_init_global() */ > -int odp_test_global_init(void) > -{ > - memset(thread_tbl, 0, sizeof(thread_tbl)); > - > - if (odp_init_global(NULL, NULL)) { > - LOG_ERR("ODP global init failed.\n"); > - return -1; > - } > - > - num_workers = odp_cpu_count(); > - /* force to max CPU count */ > - if (num_workers > MAX_WORKERS) > - num_workers = MAX_WORKERS; > - > - return 0; > -} > - > -/** create test thread */ > -int odp_test_thread_create(void *func_ptr(void *), pthrd_arg *arg) > -{ > - odp_cpumask_t cpumask; > - > - /* Create and init additional threads */ > - odp_cpumask_default_worker(&cpumask, arg->numthrds); > - odph_linux_pthread_create(thread_tbl, &cpumask, func_ptr, > - (void *)arg, ODP_THREAD_WORKER); > - > - return 0; > -} > - > -/** exit from test thread */ > -int odp_test_thread_exit(pthrd_arg *arg) > -{ > - /* Wait for other threads to exit */ > - odph_linux_pthread_join(thread_tbl, arg->numthrds); > - > - return 0; > -} > diff --git a/test/api_test/odp_common.h b/test/api_test/odp_common.h > deleted file mode 100644 > index f321b6b..0000000 > --- a/test/api_test/odp_common.h > +++ /dev/null > @@ -1,42 +0,0 @@ > -/* Copyright (c) 2013, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/** > - * @file > - * > - * ODP test application common headers > - */ > - > -#ifndef ODP_COMMON_H > -#define ODP_COMMON_H > - > -#define MAX_WORKERS 32 /**< Maximum number of work threads */ > - > -/** types of tests */ > -typedef enum { > - ODP_ATOMIC_TEST = 0, > - ODP_SHM_TEST, > - ODP_RING_TEST_BASIC, > - ODP_RING_TEST_STRESS, > - ODP_TIMER_PING_TEST, > - ODP_MAX_TEST > -} odp_test_case_e; > - > -/** > - * Thread argument > - */ > -typedef struct { > - int testcase; /**< specifies which set of API's to exercise */ > - int numthrds; /**< no of pthreads to create */ > -} pthrd_arg; > - > -extern void odp_print_system_info(void); > -extern int odp_test_global_init(void); > -/** create thread fro start_routine function */ > -extern int odp_test_thread_create(void *(*start_routine) (void > *), pthrd_arg *); > -extern int odp_test_thread_exit(pthrd_arg *); > - > -#endif /* ODP_COMMON_H */ > diff --git a/test/api_test/odp_ring_test.c > b/test/api_test/odp_ring_test.c > deleted file mode 100644 > index e8a962a..0000000 > --- a/test/api_test/odp_ring_test.c > +++ /dev/null > @@ -1,470 +0,0 @@ > -/* Copyright (c) 2014, Linaro Limited > - * All rights reserved. > - * > - * SPDX-License-Identifier: BSD-3-Clause > - */ > - > -/*- > - * BSD LICENSE > - * > - * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. > - * All rights reserved. > - * > - * Redistribution and use in source and binary forms, with or > without > - * modification, are permitted provided that the following > conditions > - * are met: > - * > - * * Redistributions of source code must retain the above > copyright > - * notice, this list of conditions and the following > disclaimer. > - * * 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. > - * * Neither the name of Intel Corporation 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. > - */ > - > - > -/** > - * @file > - * > - * ODP test ring > - */ > - > -#include <stdlib.h> > -#include <stdio.h> > -#include <string.h> > -#include <odp.h> > -#include <odp_common.h> > -#include <odp/helper/ring.h> > -#include <test_debug.h> > - > -#define RING_SIZE 4096 > -#define MAX_BULK 32 > - > -#define RING_TEST_BASIC > - > -static int test_ring_basic(odph_ring_t *r) > -{ > - void **src = NULL, **cur_src = NULL, **dst = NULL, > **cur_dst = NULL; > - int ret; > - unsigned i, num_elems; > - > - /* alloc dummy object pointers */ > - src = malloc(RING_SIZE*2*sizeof(void *)); > - if (src == NULL) { > - LOG_ERR("failed to allocate test ring src memory\n"); > - goto fail; > - } > - for (i = 0; i < RING_SIZE*2; i++) > - src[i] = (void *)(unsigned long)i; > - > - cur_src = src; > - > - /* alloc some room for copied objects */ > - dst = malloc(RING_SIZE*2*sizeof(void *)); > - if (dst == NULL) { > - LOG_ERR("failed to allocate test ring dst memory\n"); > - goto fail; > - } > - > - memset(dst, 0, RING_SIZE*2*sizeof(void *)); > - cur_dst = dst; > - > - printf("Test SP & SC basic functions\n"); > - printf("enqueue 1 obj\n"); > - ret = odph_ring_sp_enqueue_burst(r, cur_src, 1); > - cur_src += 1; > - if ((ret & ODPH_RING_SZ_MASK) != 1) { > - LOG_ERR("sp_enq for 1 obj failed\n"); > - goto fail; > - } > - > - printf("enqueue 2 objs\n"); > - ret = odph_ring_sp_enqueue_burst(r, cur_src, 2); > - cur_src += 2; > - if ((ret & ODPH_RING_SZ_MASK) != 2) { > - LOG_ERR("sp_enq for 2 obj failed\n"); > - goto fail; > - } > - > - printf("enqueue MAX_BULK objs\n"); > - ret = odph_ring_sp_enqueue_burst(r, cur_src, MAX_BULK); > - if ((ret & ODPH_RING_SZ_MASK) != MAX_BULK) { > - LOG_ERR("sp_enq for %d obj failed\n", MAX_BULK); > - goto fail; > - } > - > - printf("dequeue 1 obj\n"); > - ret = odph_ring_sc_dequeue_burst(r, cur_dst, 1); > - cur_dst += 1; > - if ((ret & ODPH_RING_SZ_MASK) != 1) { > - LOG_ERR("sc_deq for 1 obj failed\n"); > - goto fail; > - } > - > - printf("dequeue 2 objs\n"); > - ret = odph_ring_sc_dequeue_burst(r, cur_dst, 2); > - cur_dst += 2; > - if ((ret & ODPH_RING_SZ_MASK) != 2) { > - LOG_ERR("sc_deq for 2 obj failed\n"); > - goto fail; > - } > - > - printf("dequeue MAX_BULK objs\n"); > - ret = odph_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK); > - cur_dst += MAX_BULK; > - if ((ret & ODPH_RING_SZ_MASK) != MAX_BULK) { > - LOG_ERR("sc_deq for %d obj failed\n", MAX_BULK); > - goto fail; > - } > - > - /* check data */ > - if (memcmp(src, dst, cur_dst - dst)) { > - LOG_ERR("data after dequeue is not the same\n"); > - goto fail; > - } > - > - cur_src = src; > - cur_dst = dst; > - > - printf("Test MP & MC basic functions\n"); > - > - printf("enqueue 1 obj\n"); > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, 1); > - cur_src += 1; > - if (ret != 0) { > - LOG_ERR("mp_enq for 1 obj failed\n"); > - goto fail; > - } > - printf("enqueue 2 objs\n"); > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, 2); > - cur_src += 2; > - if (ret != 0) { > - LOG_ERR("mp_enq for 2 obj failed\n"); > - goto fail; > - } > - printf("enqueue MAX_BULK objs\n"); > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK); > - if (ret != 0) { > - LOG_ERR("mp_enq for %d obj failed\n", MAX_BULK); > - goto fail; > - } > - printf("dequeue 1 obj\n"); > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, 1); > - cur_dst += 1; > - if (ret != 0) { > - LOG_ERR("mc_deq for 1 obj failed\n"); > - goto fail; > - } > - printf("dequeue 2 objs\n"); > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, 2); > - cur_dst += 2; > - if (ret != 0) { > - LOG_ERR("mc_deq for 2 obj failed\n"); > - goto fail; > - } > - printf("dequeue MAX_BULK objs\n"); > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK); > - cur_dst += MAX_BULK; > - if (ret != 0) { > - LOG_ERR("mc_deq for %d obj failed\n", MAX_BULK); > - goto fail; > - } > - /* check data */ > - if (memcmp(src, dst, cur_dst - dst)) { > - LOG_ERR("data after dequeue is not the same\n"); > - goto fail; > - } > - > - printf("test watermark and default bulk enqueue / dequeue\n"); > - odph_ring_set_water_mark(r, 20); > - num_elems = 16; > - > - cur_src = src; > - cur_dst = dst; > - > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, num_elems); > - cur_src += num_elems; > - if (ret != 0) { > - LOG_ERR("Cannot enqueue\n"); > - goto fail; > - } > - ret = odph_ring_mp_enqueue_bulk(r, cur_src, num_elems); > - if (ret != -EDQUOT) { > - LOG_ERR("Watermark not exceeded\n"); > - goto fail; > - } > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, num_elems); > - cur_dst += num_elems; > - if (ret != 0) { > - LOG_ERR("Cannot dequeue\n"); > - goto fail; > - } > - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, num_elems); > - cur_dst += num_elems; > - if (ret != 0) { > - LOG_ERR("Cannot dequeue2\n"); > - goto fail; > - } > - > - /* check data */ > - if (memcmp(src, dst, cur_dst - dst)) { > - LOG_ERR("data after dequeue is not the same\n"); > - goto fail; > - } > - > - printf("basic enqueu, dequeue test for ring <%s>@%p passed\n", > - r->name, r); > - > - free(src); > - free(dst); > - return 0; > - > -fail: > - free(src); > - free(dst); > - return -1; > -} > - > -/* global shared ring used for stress testing */ > -static odph_ring_t *r_stress; > - > -/* Stress func for Multi producer only */ > -static int producer_fn(void) > -{ > - unsigned i; > - > - void **src = NULL; > - > - /* alloc dummy object pointers */ > - src = malloc(MAX_BULK*2*sizeof(void *)); > - if (src == NULL) { > - LOG_ERR("failed to allocate producer memory.\n"); > - return -1; > - } > - for (i = 0; i < MAX_BULK; i++) > - src[i] = (void *)(unsigned long)i; > - > - do { > - i = odph_ring_mp_enqueue_bulk(r_stress, src, > MAX_BULK); > - if (i == 0) { > - free(src); > - return 0; > - } > - } while (1); > -} > - > -/* Stress func for Multi consumer only */ > -static int consumer_fn(void) > -{ > - unsigned i; > - void **src = NULL; > - > - /* alloc dummy object pointers */ > - src = malloc(MAX_BULK*2*sizeof(void *)); > - if (src == NULL) { > - LOG_ERR("failed to allocate consumer memory.\n"); > - return -1; > - } > - > - do { > - i = odph_ring_mc_dequeue_bulk(r_stress, src, > MAX_BULK); > - if (i == 0) { > - for (i = 0; i < MAX_BULK; i++) { > - if (src[i] != (void *)(unsigned > long)i) { > - free(src); > - printf("data mismatch.. > lockless ops fail\n"); > - return -1; > - } > - } > - free(src); > - printf("\n Test OK !\n"); > - return 0; > - } > - } while (1); > -} > - > - > -/* > - * Note : make sure that both enqueue and dequeue > - * operation starts at same time so to avoid data corruption > - * Its because atomic lock will protect only indexes, but if order of > - * read or write operation incorrect then data mismatch will happen > - * So its resposibility of application develop to take care of > order of > - * data read or write. > -*/ > -typedef enum { > - one_enq_one_deq, /* One thread to enqueue one to > - dequeu at same time */ > - one_enq_rest_deq, /* one thread to enq rest to > - dequeue at same time */ > - one_deq_rest_enq, /* one to deq and rest enq at very > same time */ > - multi_enq_multi_deq /* multiple enq,deq */ > -} stress_type_t; > - > -static void test_ring_stress(stress_type_t type) > -{ > - int thr; > - thr = odp_thread_id(); > - > - switch (type) { > - case one_enq_one_deq: > - > - if (thr == 1) > - producer_fn(); > - if (thr == 2) > - consumer_fn(); > - break; > - > - case multi_enq_multi_deq: > - if (thr%2 == 0) > - producer_fn(); > - else > - consumer_fn(); > - break; > - > - case one_deq_rest_enq: > - case one_enq_rest_deq:/*TBD*/ > - default: > - LOG_ERR("Invalid stress type or test case yet not > supported\n"); > - } > -} > - > -/* local struct for ring_thread argument */ > -typedef struct { > - pthrd_arg thrdarg; > - int stress_type; > -} ring_arg_t; > - > - > -static void *test_ring(void *arg) > -{ > - ring_arg_t *parg = (ring_arg_t *)arg; > - int thr; > - char ring_name[ODPH_RING_NAMESIZE]; > - odph_ring_t *r; > - int result = 0; > - > - thr = odp_thread_id(); > - > - printf("Thread %i starts\n", thr); > - > - switch (parg->thrdarg.testcase) { > - case ODP_RING_TEST_BASIC: > - snprintf(ring_name, sizeof(ring_name), > "test_ring_%i", thr); > - > - r = odph_ring_create(ring_name, RING_SIZE, > - 0 /* not used, alignement > - taken care inside func : > todo */); > - if (r == NULL) { > - LOG_ERR("ring create failed\n"); > - result = -1; > - break; > - } > - /* lookup ring from its name */ > - if (odph_ring_lookup(ring_name) != r) { > - LOG_ERR("ring lookup failed\n"); > - result = -1; > - break; > - } > - > - /* basic operations */ > - if (test_ring_basic(r) < 0) { > - LOG_ERR("ring basic enqueue/dequeu ops > failed\n"); > - result = -1; > - } > - > - /* dump ring stats */ > - odph_ring_list_dump(); > - > - break; > - > - case ODP_RING_TEST_STRESS: > - test_ring_stress(parg->stress_type); > - > - /* dump ring stats */ > - odph_ring_list_dump(); > - break; > - > - default: > - LOG_ERR("Invalid test case [%d]\n", > parg->thrdarg.testcase); > - result = -1; > - break; > - } > - > - LOG_DBG("result = %d\n", result); > - if (result == 0) > - printf("test_ring Result:pass\n"); > - else > - printf("test_ring Result:fail\n"); > - > - fflush(stdout); > - > - return parg; > -} > - > - > -int main(int argc __attribute__((__unused__)), > - char *argv[] __attribute__((__unused__))) > -{ > - ring_arg_t rarg; > - > - if (odp_test_global_init() != 0) > - return -1; > - > - odp_print_system_info(); > - > - odph_ring_tailq_init(); > - > - rarg.thrdarg.numthrds = odp_cpu_count(); > - > -#ifdef RING_TEST_BASIC > - rarg.thrdarg.testcase = ODP_RING_TEST_BASIC; > -#else > - rarg.thrdarg.testcase = ODP_RING_TEST_STRESS; > - rarg.stress_type = one_enq_one_deq; > -/* rarg.stress_type = multi_enq_multi_deq;*/ > - char ring_name[ODPH_RING_NAMESIZE]; > - > - printf("starting stess test type : %d..\n", rarg.stress_type); > - /* create a ring */ > - snprintf(ring_name, sizeof(ring_name), "test_ring_stress"); > - > - r_stress = odph_ring_create(ring_name, RING_SIZE, > - 0 /* not used, alignement > - taken care inside func : todo */); > - if (r_stress == NULL) { > - LOG_ERR("ring create failed\n"); > - goto fail; > - } > - /* lookup ring from its name */ > - if (odph_ring_lookup(ring_name) != r_stress) { > - LOG_ERR("ring lookup failed\n"); > - goto fail; > - } > -#endif > - odp_test_thread_create(test_ring, (pthrd_arg *)&rarg); > - > -#ifndef RING_TEST_BASIC > -fail: > -#endif > - > - odp_test_thread_exit(&rarg.thrdarg); > - > - return 0; > -} > - > -- > 2.7.1.250.gff4ea60 > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org> > https://lists.linaro.org/mailman/listinfo/lng-odp > > > > > -- > Mike Holmes > Technical Manager - Linaro Networking Group > Linaro.org <http://www.linaro.org/>***│ *Open source software for ARM SoCs > "Work should be fun and collborative, the rest follows" >
diff --git a/configure.ac b/configure.ac index 8108ff2..a7cb035 100644 --- a/configure.ac +++ b/configure.ac @@ -336,7 +336,6 @@ AC_CONFIG_FILES([Makefile pkgconfig/libodphelper.pc scripts/Makefile test/Makefile - test/api_test/Makefile test/performance/Makefile test/validation/Makefile test/validation/atomic/Makefile diff --git a/helper/Makefile.am b/helper/Makefile.am index a8665b2..6557793 100644 --- a/helper/Makefile.am +++ b/helper/Makefile.am @@ -10,7 +10,6 @@ AM_CFLAGS += -I$(top_srcdir)/include helperincludedir = $(includedir)/odp/helper/ helperinclude_HEADERS = \ - $(srcdir)/include/odp/helper/ring.h \ $(srcdir)/include/odp/helper/linux.h \ $(srcdir)/include/odp/helper/chksum.h\ $(srcdir)/include/odp/helper/eth.h\ @@ -30,7 +29,6 @@ noinst_HEADERS = \ __LIB__libodphelper_la_SOURCES = \ linux.c \ - ring.c \ hashtable.c \ lineartable.c diff --git a/helper/include/odp/helper/ring.h b/helper/include/odp/helper/ring.h deleted file mode 100644 index 65c32ad..0000000 --- a/helper/include/odp/helper/ring.h +++ /dev/null @@ -1,577 +0,0 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Intel Corporation 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. - */ - -/* - * Derived from FreeBSD's bufring.c - * - ************************************************************************** - * - * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org - * All rights reserved. - * - * 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. The name of Kip Macy nor the names of other - * 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. - * - ***************************************************************************/ - -/** - * ODP Ring - * - * The Ring Manager is a fixed-size queue, implemented as a table of - * pointers. Head and tail pointers are modified atomically, allowing - * concurrent access to it. It has the following features: - * - * - FIFO (First In First Out) - * - Maximum size is fixed; the pointers are stored in a table. - * - Lockless implementation. - * - Multi- or single-consumer dequeue. - * - Multi- or single-producer enqueue. - * - Bulk dequeue. - * - Bulk enqueue. - * - * Note: the ring implementation is not preemptable. A lcore must not - * be interrupted by another task that uses the same ring. - * - */ - -#ifndef ODPH_RING_H_ -#define ODPH_RING_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - -#include <odp/std_types.h> -#include <odp/hints.h> -#include <odp/atomic.h> -#include <errno.h> -#include <sys/queue.h> - -enum odph_ring_queue_behavior { - ODPH_RING_QUEUE_FIXED = 0, /**< Enq/Deq a fixed number - of items from a ring */ - ODPH_RING_QUEUE_VARIABLE /**< Enq/Deq as many items - a possible from ring */ -}; - - -#define ODPH_RING_NAMESIZE 32 /**< The maximum length of a ring name. */ - -/** - * An ODP ring structure. - * - * The producer and the consumer have a head and a tail index. The particularity - * of these index is that they are not between 0 and size(ring). These indexes - * are between 0 and 2^32, and we mask their value when we access the ring[] - * field. Thanks to this assumption, we can do subtractions between 2 index - * values in a modulo-32bit base: that's why the overflow of the indexes is not - * a problem. - */ -typedef struct odph_ring { - /** @private Next in list. */ - TAILQ_ENTRY(odph_ring) next; - - /** @private Name of the ring. */ - char name[ODPH_RING_NAMESIZE]; - /** @private Flags supplied at creation. */ - int flags; - - /** @private Producer */ - struct prod { - uint32_t watermark; /* Maximum items */ - uint32_t sp_enqueue; /* True, if single producer. */ - uint32_t size; /* Size of ring. */ - uint32_t mask; /* Mask (size-1) of ring. */ - uint32_t head; /* Producer head. */ - uint32_t tail; /* Producer tail. */ - } prod ODP_ALIGNED_CACHE; - - /** @private Consumer */ - struct cons { - uint32_t sc_dequeue; /* True, if single consumer. */ - uint32_t size; /* Size of the ring. */ - uint32_t mask; /* Mask (size-1) of ring. */ - uint32_t head; /* Consumer head. */ - uint32_t tail; /* Consumer tail. */ - } cons ODP_ALIGNED_CACHE; - - /** @private Memory space of ring starts here. */ - void *ring[0] ODP_ALIGNED_CACHE; -} odph_ring_t; - - -#define ODPH_RING_F_SP_ENQ 0x0001 /* The default enqueue is "single-producer".*/ -#define ODPH_RING_F_SC_DEQ 0x0002 /* The default dequeue is "single-consumer".*/ -#define ODPH_RING_QUOT_EXCEED (1 << 31) /* Quota exceed for burst ops */ -#define ODPH_RING_SZ_MASK (unsigned)(0x0fffffff) /* Ring size mask */ - - -/** - * Create a new ring named *name* in memory. - * - * This function uses odp_shm_reserve() to allocate memory. Its size is - * set to *count*, which must be a power of two. Water marking is - * disabled by default. Note that the real usable ring size is count-1 - * instead of count. - * - * @param name - * The name of the ring. - * @param count - * The size of the ring (must be a power of 2). - * @param socket_id (dummy, not included : todo) - * @param flags - * An OR of the following: - * - RING_F_SP_ENQ: If this flag is set, the default behavior when - * using ``odp_ring_enqueue()`` or ``odp_ring_enqueue_bulk()`` - * is "single-producer". Otherwise, it is "multi-producers". - * - RING_F_SC_DEQ: If this flag is set, the default behavior when - * using ``odp_ring_dequeue()`` or ``odp_ring_dequeue_bulk()`` - * is "single-consumer". Otherwise, it is "multi-consumers". - * @return - * On success, the pointer to the new allocated ring. NULL on error with - * odp_errno set appropriately. Possible errno values include: - * - EINVAL - count provided is not a power of 2 - * - ENOSPC - the maximum number of memzones has already been allocated - * - EEXIST - a memzone with the same name already exists - * - ENOMEM - no appropriate memory area found in which to create memzone - */ -odph_ring_t *odph_ring_create(const char *name, unsigned count, - unsigned flags); - - -/** - * Change the high water mark. - * - * If *count* is 0, water marking is disabled. Otherwise, it is set to the - * *count* value. The *count* value must be greater than 0 and less - * than the ring size. - * - * This function can be called at any time (not necessarily at - * initialization). - * - * @param r Pointer to the ring structure. - * @param count New water mark value. - * @return 0: Success; water mark changed. - * -EINVAL: Invalid water mark value. - */ -int odph_ring_set_water_mark(odph_ring_t *r, unsigned count); - -/** - * Dump the status of the ring to the console. - * - * @param r A pointer to the ring structure. - */ -void odph_ring_dump(const odph_ring_t *r); - -/** - * Enqueue several objects on the ring (multi-producers safe). - * - * This function uses a "compare and set" instruction to move the - * producer index atomically. - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects). - * @param n - * The number of objects to add in the ring from the obj_table. - * @param behavior - * ODP_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring - * ODP_RING_QUEUE_VARIABLE: Enqueue as many items a possible from ring - * @return - * Depend on the behavior value - * if behavior = ODP_RING_QUEUE_FIXED - * - 0: Success; objects enqueue. - * - -EDQUOT: Quota exceeded. The objects have been enqueued, but the - * high water mark is exceeded. - * - -ENOBUFS: Not enough room in the ring to enqueue, no object is enqueued. - * if behavior = ODP_RING_QUEUE_VARIABLE - * - n: Actual number of objects enqueued. - */ -int __odph_ring_mp_do_enqueue(odph_ring_t *r, void * const *obj_table, - unsigned n, - enum odph_ring_queue_behavior behavior); - -/** - * Enqueue several objects on a ring (NOT multi-producers safe). - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects). - * @param n - * The number of objects to add in the ring from the obj_table. - * @param behavior - * ODP_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring - * ODP_RING_QUEUE_VARIABLE: Enqueue as many items a possible from ring - * @return - * Depend on the behavior value - * if behavior = ODP_RING_QUEUE_FIXED - * - 0: Success; objects enqueue. - * - -EDQUOT: Quota exceeded. The objects have been enqueued, but the - * high water mark is exceeded. - * - -ENOBUFS: Not enough room in the ring to enqueue, no object is enqueued. - * if behavior = ODP_RING_QUEUE_VARIABLE - * - n: Actual number of objects enqueued. - */ -int __odph_ring_sp_do_enqueue(odph_ring_t *r, void * const *obj_table, - unsigned n, - enum odph_ring_queue_behavior behavior); - -/** - * Dequeue several objects from a ring (multi-consumers safe). When - * the request objects are more than the available objects, only dequeue the - * actual number of objects - * - * This function uses a "compare and set" instruction to move the - * consumer index atomically. - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects) that will be filled. - * @param n - * The number of objects to dequeue from the ring to the obj_table. - * @param behavior - * ODP_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring - * ODP_RING_QUEUE_VARIABLE: Dequeue as many items a possible from ring - * @return - * Depend on the behavior value - * if behavior = ODP_RING_QUEUE_FIXED - * - 0: Success; objects dequeued. - * - -ENOENT: Not enough entries in the ring to dequeue; no object is - * dequeued. - * if behavior = ODP_RING_QUEUE_VARIABLE - * - n: Actual number of objects dequeued. - */ - -int __odph_ring_mc_do_dequeue(odph_ring_t *r, void **obj_table, - unsigned n, - enum odph_ring_queue_behavior behavior); - -/** - * Dequeue several objects from a ring (NOT multi-consumers safe). - * When the request objects are more than the available objects, only dequeue - * the actual number of objects - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects) that will be filled. - * @param n - * The number of objects to dequeue from the ring to the obj_table. - * @param behavior - * ODP_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring - * ODP_RING_QUEUE_VARIABLE: Dequeue as many items a possible from ring - * @return - * Depend on the behavior value - * if behavior = ODP_RING_QUEUE_FIXED - * - 0: Success; objects dequeued. - * - -ENOENT: Not enough entries in the ring to dequeue; no object is - * dequeued. - * if behavior = ODP_RING_QUEUE_VARIABLE - * - n: Actual number of objects dequeued. - */ -int __odph_ring_sc_do_dequeue(odph_ring_t *r, void **obj_table, - unsigned n, - enum odph_ring_queue_behavior behavior); - -/** - * Enqueue several objects on the ring (multi-producers safe). - * - * This function uses a "compare and set" instruction to move the - * producer index atomically. - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects). - * @param n - * The number of objects to add in the ring from the obj_table. - * @return - * - 0: Success; objects enqueue. - * - -EDQUOT: Quota exceeded. The objects have been enqueued, but the - * high water mark is exceeded. - * - -ENOBUFS: Not enough room in the ring to enqueue, no object is enqueued. - */ -int odph_ring_mp_enqueue_bulk(odph_ring_t *r, void * const *obj_table, - unsigned n); - -/** - * Enqueue several objects on a ring (NOT multi-producers safe). - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects). - * @param n - * The number of objects to add in the ring from the obj_table. - * @return - * - 0: Success; objects enqueued. - * - -EDQUOT: Quota exceeded. The objects have been enqueued, but the - * high water mark is exceeded. - * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued. - */ -int odph_ring_sp_enqueue_bulk(odph_ring_t *r, void * const *obj_table, - unsigned n); - -/** - * Dequeue several objects from a ring (multi-consumers safe). - * - * This function uses a "compare and set" instruction to move the - * consumer index atomically. - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects) that will be filled. - * @param n - * The number of objects to dequeue from the ring to the obj_table. - * @return - * - 0: Success; objects dequeued. - * - -ENOENT: Not enough entries in the ring to dequeue; no object is - * dequeued. - */ -int odph_ring_mc_dequeue_bulk(odph_ring_t *r, void **obj_table, unsigned n); - -/** - * Dequeue several objects from a ring (NOT multi-consumers safe). - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects) that will be filled. - * @param n - * The number of objects to dequeue from the ring to the obj_table, - * must be strictly positive. - * @return - * - 0: Success; objects dequeued. - * - -ENOENT: Not enough entries in the ring to dequeue; no object is - * dequeued. - */ -int odph_ring_sc_dequeue_bulk(odph_ring_t *r, void **obj_table, unsigned n); - -/** - * Test if a ring is full. - * - * @param r - * A pointer to the ring structure. - * @return - * - 1: The ring is full. - * - 0: The ring is not full. - */ -int odph_ring_full(const odph_ring_t *r); - -/** - * Test if a ring is empty. - * - * @param r - * A pointer to the ring structure. - * @return - * - 1: The ring is empty. - * - 0: The ring is not empty. - */ -int odph_ring_empty(const odph_ring_t *r); - -/** - * Return the number of entries in a ring. - * - * @param r - * A pointer to the ring structure. - * @return - * The number of entries in the ring. - */ -unsigned odph_ring_count(const odph_ring_t *r); - -/** - * Return the number of free entries in a ring. - * - * @param r - * A pointer to the ring structure. - * @return - * The number of free entries in the ring. - */ -unsigned odph_ring_free_count(const odph_ring_t *r); - -/** - * search ring by name - * @param name ring name to search - * @return pointer to ring otherwise NULL - */ -odph_ring_t *odph_ring_lookup(const char *name); - -/** - * Enqueue several objects on the ring (multi-producers safe). - * - * This function uses a "compare and set" instruction to move the - * producer index atomically. - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects). - * @param n - * The number of objects to add in the ring from the obj_table. - * @return - * - n: Actual number of objects enqueued. - */ -int odph_ring_mp_enqueue_burst(odph_ring_t *r, void * const *obj_table, - unsigned n); - -/** - * Enqueue several objects on a ring (NOT multi-producers safe). - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects). - * @param n - * The number of objects to add in the ring from the obj_table. - * @return - * - n: Actual number of objects enqueued. - */ -int odph_ring_sp_enqueue_burst(odph_ring_t *r, void * const *obj_table, - unsigned n); -/** - * Enqueue several objects on a ring. - * - * This function calls the multi-producer or the single-producer - * version depending on the default behavior that was specified at - * ring creation time (see flags). - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects). - * @param n - * The number of objects to add in the ring from the obj_table. - * @return - * - n: Actual number of objects enqueued. - */ -int odph_ring_enqueue_burst(odph_ring_t *r, void * const *obj_table, - unsigned n); - -/** - * Dequeue several objects from a ring (multi-consumers safe). When the request - * objects are more than the available objects, only dequeue the actual number - * of objects - * - * This function uses a "compare and set" instruction to move the - * consumer index atomically. - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects) that will be filled. - * @param n - * The number of objects to dequeue from the ring to the obj_table. - * @return - * - n: Actual number of objects dequeued, 0 if ring is empty - */ -int odph_ring_mc_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned n); - -/** - * Dequeue several objects from a ring (NOT multi-consumers safe).When the - * request objects are more than the available objects, only dequeue the - * actual number of objects - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects) that will be filled. - * @param n - * The number of objects to dequeue from the ring to the obj_table. - * @return - * - n: Actual number of objects dequeued, 0 if ring is empty - */ -int odph_ring_sc_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned n); - -/** - * Dequeue multiple objects from a ring up to a maximum number. - * - * This function calls the multi-consumers or the single-consumer - * version, depending on the default behaviour that was specified at - * ring creation time (see flags). - * - * @param r - * A pointer to the ring structure. - * @param obj_table - * A pointer to a table of void * pointers (objects) that will be filled. - * @param n - * The number of objects to dequeue from the ring to the obj_table. - * @return - * - Number of objects dequeued, or a negative error code on error - */ -int odph_ring_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned n); - -/** - * dump the status of all rings on the console - */ -void odph_ring_list_dump(void); - -/** - * initialise ring tailq - */ -void odph_ring_tailq_init(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/helper/ring.c b/helper/ring.c deleted file mode 100644 index 6699186..0000000 --- a/helper/ring.c +++ /dev/null @@ -1,634 +0,0 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Intel Corporation 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. - */ - -/* - * Derived from FreeBSD's bufring.c - * - ************************************************************************** - * - * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org - * All rights reserved. - * - * 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. The name of Kip Macy nor the names of other - * 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. - * - ***************************************************************************/ - -#include <odp.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include "odph_debug.h" -#include <odp/helper/ring.h> - -static TAILQ_HEAD(, odph_ring) odp_ring_list; - -#define RING_VAL_IS_POWER_2(x) ((((x) - 1) & (x)) == 0) - -/* - * the enqueue of pointers on the ring. - */ -#define ENQUEUE_PTRS() do { \ - const uint32_t size = r->prod.size; \ - uint32_t idx = prod_head & mask; \ - if (odp_likely(idx + n < size)) { \ - for (i = 0; i < (n & ((~(unsigned)0x3))); i += 4, idx += 4) { \ - r->ring[idx] = obj_table[i]; \ - r->ring[idx+1] = obj_table[i+1]; \ - r->ring[idx+2] = obj_table[i+2]; \ - r->ring[idx+3] = obj_table[i+3]; \ - } \ - switch (n & 0x3) { \ - case 3: \ - r->ring[idx++] = obj_table[i++]; \ - case 2: \ - r->ring[idx++] = obj_table[i++]; \ - case 1: \ - r->ring[idx++] = obj_table[i++]; \ - } \ - } else { \ - for (i = 0; idx < size; i++, idx++)\ - r->ring[idx] = obj_table[i]; \ - for (idx = 0; i < n; i++, idx++) \ - r->ring[idx] = obj_table[i]; \ - } \ -} while (0) - -/* - * the actual copy of pointers on the ring to obj_table. - */ -#define DEQUEUE_PTRS() do { \ - uint32_t idx = cons_head & mask; \ - const uint32_t size = r->cons.size; \ - if (odp_likely(idx + n < size)) { \ - for (i = 0; i < (n & (~(unsigned)0x3)); i += 4, idx += 4) {\ - obj_table[i] = r->ring[idx]; \ - obj_table[i+1] = r->ring[idx+1]; \ - obj_table[i+2] = r->ring[idx+2]; \ - obj_table[i+3] = r->ring[idx+3]; \ - } \ - switch (n & 0x3) { \ - case 3: \ - obj_table[i++] = r->ring[idx++]; \ - case 2: \ - obj_table[i++] = r->ring[idx++]; \ - case 1: \ - obj_table[i++] = r->ring[idx++]; \ - } \ - } else { \ - for (i = 0; idx < size; i++, idx++) \ - obj_table[i] = r->ring[idx]; \ - for (idx = 0; i < n; i++, idx++) \ - obj_table[i] = r->ring[idx]; \ - } \ -} while (0) - -static odp_rwlock_t qlock; /* rings tailq lock */ - -/* init tailq_ring */ -void odph_ring_tailq_init(void) -{ - TAILQ_INIT(&odp_ring_list); - odp_rwlock_init(&qlock); -} - -/* create the ring */ -odph_ring_t * -odph_ring_create(const char *name, unsigned count, unsigned flags) -{ - char ring_name[ODPH_RING_NAMESIZE]; - odph_ring_t *r; - size_t ring_size; - odp_shm_t shm; - - /* count must be a power of 2 */ - if (!RING_VAL_IS_POWER_2(count) || (count > ODPH_RING_SZ_MASK)) { - ODPH_ERR("Requested size is invalid, must be power of 2, and do not exceed the size limit %u\n", - ODPH_RING_SZ_MASK); - return NULL; - } - - snprintf(ring_name, sizeof(ring_name), "%s", name); - ring_size = count*sizeof(void *)+sizeof(odph_ring_t); - - odp_rwlock_write_lock(&qlock); - /* reserve a memory zone for this ring.*/ - shm = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE, 0); - - r = odp_shm_addr(shm); - - if (r != NULL) { - /* init the ring structure */ - snprintf(r->name, sizeof(r->name), "%s", name); - r->flags = flags; - r->prod.watermark = count; - r->prod.sp_enqueue = !!(flags & ODPH_RING_F_SP_ENQ); - r->cons.sc_dequeue = !!(flags & ODPH_RING_F_SC_DEQ); - r->prod.size = count; - r->cons.size = count; - r->prod.mask = count-1; - r->cons.mask = count-1; - r->prod.head = 0; - r->cons.head = 0; - r->prod.tail = 0; - r->cons.tail = 0; - - TAILQ_INSERT_TAIL(&odp_ring_list, r, next); - } else { - ODPH_ERR("Cannot reserve memory\n"); - } - - odp_rwlock_write_unlock(&qlock); - return r; -} - -/* - * change the high water mark. If *count* is 0, water marking is - * disabled - */ -int odph_ring_set_water_mark(odph_ring_t *r, unsigned count) -{ - if (count >= r->prod.size) - return -EINVAL; - - /* if count is 0, disable the watermarking */ - if (count == 0) - count = r->prod.size; - - r->prod.watermark = count; - return 0; -} - -/** - * Enqueue several objects on the ring (multi-producers safe). - */ -int __odph_ring_mp_do_enqueue(odph_ring_t *r, void * const *obj_table, - unsigned n, enum odph_ring_queue_behavior behavior) -{ - uint32_t prod_head, prod_next; - uint32_t cons_tail, free_entries; - const unsigned max = n; - int success; - unsigned i; - uint32_t mask = r->prod.mask; - int ret; - - /* move prod.head atomically */ - do { - /* Reset n to the initial burst count */ - n = max; - - prod_head = r->prod.head; - cons_tail = r->cons.tail; - /* The subtraction is done between two unsigned 32bits value - * (the result is always modulo 32 bits even if we have - * prod_head > cons_tail). So 'free_entries' is always between 0 - * and size(ring)-1. */ - free_entries = (mask + cons_tail - prod_head); - - /* check that we have enough room in ring */ - if (odp_unlikely(n > free_entries)) { - if (behavior == ODPH_RING_QUEUE_FIXED) { - return -ENOBUFS; - } else { - /* No free entry available */ - if (odp_unlikely(free_entries == 0)) - return 0; - - n = free_entries; - } - } - - prod_next = prod_head + n; - success = __atomic_compare_exchange_n(&r->prod.head, - &prod_head, - prod_next, - false/*strong*/, - __ATOMIC_ACQUIRE, - __ATOMIC_RELAXED); - } while (odp_unlikely(success == 0)); - - /* write entries in ring */ - ENQUEUE_PTRS(); - - /* if we exceed the watermark */ - if (odp_unlikely(((mask + 1) - free_entries + n) > r->prod.watermark)) { - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? -EDQUOT : - (int)(n | ODPH_RING_QUOT_EXCEED); - } else { - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? 0 : n; - } - - /* - * If there are other enqueues in progress that preceded us, - * we need to wait for them to complete - */ - while (odp_unlikely(r->prod.tail != prod_head)) - odp_cpu_pause(); - - /* Release our entries and the memory they refer to */ - __atomic_thread_fence(__ATOMIC_RELEASE); - r->prod.tail = prod_next; - return ret; -} - -/** - * Enqueue several objects on a ring (NOT multi-producers safe). - */ -int __odph_ring_sp_do_enqueue(odph_ring_t *r, void * const *obj_table, - unsigned n, enum odph_ring_queue_behavior behavior) -{ - uint32_t prod_head, cons_tail; - uint32_t prod_next, free_entries; - unsigned i; - uint32_t mask = r->prod.mask; - int ret; - - prod_head = r->prod.head; - cons_tail = r->cons.tail; - /* The subtraction is done between two unsigned 32bits value - * (the result is always modulo 32 bits even if we have - * prod_head > cons_tail). So 'free_entries' is always between 0 - * and size(ring)-1. */ - free_entries = mask + cons_tail - prod_head; - - /* check that we have enough room in ring */ - if (odp_unlikely(n > free_entries)) { - if (behavior == ODPH_RING_QUEUE_FIXED) { - return -ENOBUFS; - } else { - /* No free entry available */ - if (odp_unlikely(free_entries == 0)) - return 0; - - n = free_entries; - } - } - - prod_next = prod_head + n; - r->prod.head = prod_next; - - /* write entries in ring */ - ENQUEUE_PTRS(); - - /* if we exceed the watermark */ - if (odp_unlikely(((mask + 1) - free_entries + n) > r->prod.watermark)) { - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? -EDQUOT : - (int)(n | ODPH_RING_QUOT_EXCEED); - } else { - ret = (behavior == ODPH_RING_QUEUE_FIXED) ? 0 : n; - } - - /* Release our entries and the memory they refer to */ - __atomic_thread_fence(__ATOMIC_RELEASE); - r->prod.tail = prod_next; - return ret; -} - -/** - * Dequeue several objects from a ring (multi-consumers safe). - */ - -int __odph_ring_mc_do_dequeue(odph_ring_t *r, void **obj_table, - unsigned n, enum odph_ring_queue_behavior behavior) -{ - uint32_t cons_head, prod_tail; - uint32_t cons_next, entries; - const unsigned max = n; - int success; - unsigned i; - uint32_t mask = r->prod.mask; - - /* move cons.head atomically */ - do { - /* Restore n as it may change every loop */ - n = max; - - cons_head = r->cons.head; - prod_tail = r->prod.tail; - /* The subtraction is done between two unsigned 32bits value - * (the result is always modulo 32 bits even if we have - * cons_head > prod_tail). So 'entries' is always between 0 - * and size(ring)-1. */ - entries = (prod_tail - cons_head); - - /* Set the actual entries for dequeue */ - if (n > entries) { - if (behavior == ODPH_RING_QUEUE_FIXED) { - return -ENOENT; - } else { - if (odp_unlikely(entries == 0)) - return 0; - - n = entries; - } - } - - cons_next = cons_head + n; - success = __atomic_compare_exchange_n(&r->cons.head, - &cons_head, - cons_next, - false/*strong*/, - __ATOMIC_ACQUIRE, - __ATOMIC_RELAXED); - } while (odp_unlikely(success == 0)); - - /* copy in table */ - DEQUEUE_PTRS(); - - /* - * If there are other dequeues in progress that preceded us, - * we need to wait for them to complete - */ - while (odp_unlikely(r->cons.tail != cons_head)) - odp_cpu_pause(); - - /* Release our entries and the memory they refer to */ - __atomic_thread_fence(__ATOMIC_RELEASE); - r->cons.tail = cons_next; - - return behavior == ODPH_RING_QUEUE_FIXED ? 0 : n; -} - -/** - * Dequeue several objects from a ring (NOT multi-consumers safe). - */ -int __odph_ring_sc_do_dequeue(odph_ring_t *r, void **obj_table, - unsigned n, enum odph_ring_queue_behavior behavior) -{ - uint32_t cons_head, prod_tail; - uint32_t cons_next, entries; - unsigned i; - uint32_t mask = r->prod.mask; - - cons_head = r->cons.head; - prod_tail = r->prod.tail; - /* The subtraction is done between two unsigned 32bits value - * (the result is always modulo 32 bits even if we have - * cons_head > prod_tail). So 'entries' is always between 0 - * and size(ring)-1. */ - entries = prod_tail - cons_head; - - if (n > entries) { - if (behavior == ODPH_RING_QUEUE_FIXED) { - return -ENOENT; - } else { - if (odp_unlikely(entries == 0)) - return 0; - - n = entries; - } - } - - cons_next = cons_head + n; - r->cons.head = cons_next; - - /* Acquire the pointers and the memory they refer to */ - __atomic_thread_fence(__ATOMIC_ACQUIRE); - /* copy in table */ - DEQUEUE_PTRS(); - - r->cons.tail = cons_next; - return behavior == ODPH_RING_QUEUE_FIXED ? 0 : n; -} - -/** - * Enqueue several objects on the ring (multi-producers safe). - */ -int odph_ring_mp_enqueue_bulk(odph_ring_t *r, void * const *obj_table, - unsigned n) -{ - return __odph_ring_mp_do_enqueue(r, obj_table, n, - ODPH_RING_QUEUE_FIXED); -} - -/** - * Enqueue several objects on a ring (NOT multi-producers safe). - */ -int odph_ring_sp_enqueue_bulk(odph_ring_t *r, void * const *obj_table, - unsigned n) -{ - return __odph_ring_sp_do_enqueue(r, obj_table, n, - ODPH_RING_QUEUE_FIXED); -} - -/** - * Dequeue several objects from a ring (multi-consumers safe). - */ -int odph_ring_mc_dequeue_bulk(odph_ring_t *r, void **obj_table, unsigned n) -{ - return __odph_ring_mc_do_dequeue(r, obj_table, n, - ODPH_RING_QUEUE_FIXED); -} - -/** - * Dequeue several objects from a ring (NOT multi-consumers safe). - */ -int odph_ring_sc_dequeue_bulk(odph_ring_t *r, void **obj_table, unsigned n) -{ - return __odph_ring_sc_do_dequeue(r, obj_table, n, - ODPH_RING_QUEUE_FIXED); -} - -/** - * Test if a ring is full. - */ -int odph_ring_full(const odph_ring_t *r) -{ - uint32_t prod_tail = r->prod.tail; - uint32_t cons_tail = r->cons.tail; - return (((cons_tail - prod_tail - 1) & r->prod.mask) == 0); -} - -/** - * Test if a ring is empty. - */ -int odph_ring_empty(const odph_ring_t *r) -{ - uint32_t prod_tail = r->prod.tail; - uint32_t cons_tail = r->cons.tail; - return !!(cons_tail == prod_tail); -} - -/** - * Return the number of entries in a ring. - */ -unsigned odph_ring_count(const odph_ring_t *r) -{ - uint32_t prod_tail = r->prod.tail; - uint32_t cons_tail = r->cons.tail; - return (prod_tail - cons_tail) & r->prod.mask; -} - -/** - * Return the number of free entries in a ring. - */ -unsigned odph_ring_free_count(const odph_ring_t *r) -{ - uint32_t prod_tail = r->prod.tail; - uint32_t cons_tail = r->cons.tail; - return (cons_tail - prod_tail - 1) & r->prod.mask; -} - -/* dump the status of the ring on the console */ -void odph_ring_dump(const odph_ring_t *r) -{ - ODPH_DBG("ring <%s>@%p\n", r->name, r); - ODPH_DBG(" flags=%x\n", r->flags); - ODPH_DBG(" size=%" PRIu32 "\n", r->prod.size); - ODPH_DBG(" ct=%" PRIu32 "\n", r->cons.tail); - ODPH_DBG(" ch=%" PRIu32 "\n", r->cons.head); - ODPH_DBG(" pt=%" PRIu32 "\n", r->prod.tail); - ODPH_DBG(" ph=%" PRIu32 "\n", r->prod.head); - ODPH_DBG(" used=%u\n", odph_ring_count(r)); - ODPH_DBG(" avail=%u\n", odph_ring_free_count(r)); - if (r->prod.watermark == r->prod.size) - ODPH_DBG(" watermark=0\n"); - else - ODPH_DBG(" watermark=%" PRIu32 "\n", r->prod.watermark); -} - -/* dump the status of all rings on the console */ -void odph_ring_list_dump(void) -{ - const odph_ring_t *mp = NULL; - - odp_rwlock_read_lock(&qlock); - - TAILQ_FOREACH(mp, &odp_ring_list, next) { - odph_ring_dump(mp); - } - - odp_rwlock_read_unlock(&qlock); -} - -/* search a ring from its name */ -odph_ring_t *odph_ring_lookup(const char *name) -{ - odph_ring_t *r; - - odp_rwlock_read_lock(&qlock); - TAILQ_FOREACH(r, &odp_ring_list, next) { - if (strncmp(name, r->name, ODPH_RING_NAMESIZE) == 0) - break; - } - odp_rwlock_read_unlock(&qlock); - - return r; -} - -/** - * Enqueue several objects on the ring (multi-producers safe). - */ -int odph_ring_mp_enqueue_burst(odph_ring_t *r, void * const *obj_table, - unsigned n) -{ - return __odph_ring_mp_do_enqueue(r, obj_table, n, - ODPH_RING_QUEUE_VARIABLE); -} - -/** - * Enqueue several objects on a ring (NOT multi-producers safe). - */ -int odph_ring_sp_enqueue_burst(odph_ring_t *r, void * const *obj_table, - unsigned n) -{ - return __odph_ring_sp_do_enqueue(r, obj_table, n, - ODPH_RING_QUEUE_VARIABLE); -} - -/** - * Enqueue several objects on a ring. - */ -int odph_ring_enqueue_burst(odph_ring_t *r, void * const *obj_table, - unsigned n) -{ - if (r->prod.sp_enqueue) - return odph_ring_sp_enqueue_burst(r, obj_table, n); - else - return odph_ring_mp_enqueue_burst(r, obj_table, n); -} - -/** - * Dequeue several objects from a ring (multi-consumers safe). - */ -int odph_ring_mc_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned n) -{ - return __odph_ring_mc_do_dequeue(r, obj_table, n, - ODPH_RING_QUEUE_VARIABLE); -} - -/** - * Dequeue several objects from a ring (NOT multi-consumers safe). - */ -int odph_ring_sc_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned n) -{ - return __odph_ring_sc_do_dequeue(r, obj_table, n, - ODPH_RING_QUEUE_VARIABLE); -} - -/** - * Dequeue multiple objects from a ring up to a maximum number. - */ -int odph_ring_dequeue_burst(odph_ring_t *r, void **obj_table, unsigned n) -{ - if (r->cons.sc_dequeue) - return odph_ring_sc_dequeue_burst(r, obj_table, n); - else - return odph_ring_mc_dequeue_burst(r, obj_table, n); -} diff --git a/test/Makefile.am b/test/Makefile.am index 2ba8008..4a75364 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = api_test performance miscellaneous +SUBDIRS = performance miscellaneous if cunit_support SUBDIRS += validation diff --git a/test/api_test/.gitignore b/test/api_test/.gitignore deleted file mode 100644 index 950f443..0000000 --- a/test/api_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -odp_ring -odp_shm diff --git a/test/api_test/Makefile.am b/test/api_test/Makefile.am deleted file mode 100644 index 97ca5df..0000000 --- a/test/api_test/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -include $(top_srcdir)/test/Makefile.inc - -bin_PROGRAMS = odp_ring$(EXEEXT) - -odp_ring_CFLAGS = $(AM_CFLAGS) - -odp_ring_LDFLAGS = $(AM_LDFLAGS) -static - -noinst_HEADERS = \ - $(top_srcdir)/test/api_test/odp_common.h \ - $(top_srcdir)/test/test_debug.h - -dist_odp_ring_SOURCES = odp_ring_test.c odp_common.c - -#The tests will need to retain the deprecated test implementation -AM_CFLAGS += -Wno-deprecated-declarations \ No newline at end of file diff --git a/test/api_test/odp_common.c b/test/api_test/odp_common.c deleted file mode 100644 index 70aee96..0000000 --- a/test/api_test/odp_common.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP test application common - */ - -#include <string.h> -#include <odp.h> -#include <odp/helper/linux.h> -#include <odp_common.h> -#include <test_debug.h> - -#define MAX_WORKERS 32 /**< Max worker threads */ - -/* Globals */ -static odph_linux_pthread_t thread_tbl[MAX_WORKERS]; /**< worker threads table*/ -static int num_workers; /**< number of workers */ - -/** - * Print system information - */ -void odp_print_system_info(void) -{ - odp_cpumask_t cpumask; - char str[ODP_CPUMASK_STR_SIZE]; - - memset(str, 1, sizeof(str)); - - odp_cpumask_zero(&cpumask); - - odp_cpumask_from_str(&cpumask, "0x1"); - (void)odp_cpumask_to_str(&cpumask, str, sizeof(str)); - - printf("\n"); - printf("ODP system info\n"); - printf("---------------\n"); - printf("ODP API version: %s\n", odp_version_api_str()); - printf("CPU model: %s\n", odp_cpu_model_str()); - printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz_max()); - printf("Cache line size: %i\n", odp_sys_cache_line_size()); - printf("CPU count: %i\n", odp_cpu_count()); - printf("CPU mask: %s\n", str); - - printf("\n"); -} - -/** test init globals and call odp_init_global() */ -int odp_test_global_init(void) -{ - memset(thread_tbl, 0, sizeof(thread_tbl)); - - if (odp_init_global(NULL, NULL)) { - LOG_ERR("ODP global init failed.\n"); - return -1; - } - - num_workers = odp_cpu_count(); - /* force to max CPU count */ - if (num_workers > MAX_WORKERS) - num_workers = MAX_WORKERS; - - return 0; -} - -/** create test thread */ -int odp_test_thread_create(void *func_ptr(void *), pthrd_arg *arg) -{ - odp_cpumask_t cpumask; - - /* Create and init additional threads */ - odp_cpumask_default_worker(&cpumask, arg->numthrds); - odph_linux_pthread_create(thread_tbl, &cpumask, func_ptr, - (void *)arg, ODP_THREAD_WORKER); - - return 0; -} - -/** exit from test thread */ -int odp_test_thread_exit(pthrd_arg *arg) -{ - /* Wait for other threads to exit */ - odph_linux_pthread_join(thread_tbl, arg->numthrds); - - return 0; -} diff --git a/test/api_test/odp_common.h b/test/api_test/odp_common.h deleted file mode 100644 index f321b6b..0000000 --- a/test/api_test/odp_common.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP test application common headers - */ - -#ifndef ODP_COMMON_H -#define ODP_COMMON_H - -#define MAX_WORKERS 32 /**< Maximum number of work threads */ - -/** types of tests */ -typedef enum { - ODP_ATOMIC_TEST = 0, - ODP_SHM_TEST, - ODP_RING_TEST_BASIC, - ODP_RING_TEST_STRESS, - ODP_TIMER_PING_TEST, - ODP_MAX_TEST -} odp_test_case_e; - -/** - * Thread argument - */ -typedef struct { - int testcase; /**< specifies which set of API's to exercise */ - int numthrds; /**< no of pthreads to create */ -} pthrd_arg; - -extern void odp_print_system_info(void); -extern int odp_test_global_init(void); -/** create thread fro start_routine function */ -extern int odp_test_thread_create(void *(*start_routine) (void *), pthrd_arg *); -extern int odp_test_thread_exit(pthrd_arg *); - -#endif /* ODP_COMMON_H */ diff --git a/test/api_test/odp_ring_test.c b/test/api_test/odp_ring_test.c deleted file mode 100644 index e8a962a..0000000 --- a/test/api_test/odp_ring_test.c +++ /dev/null @@ -1,470 +0,0 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Intel Corporation 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. - */ - - -/** - * @file - * - * ODP test ring - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <odp.h> -#include <odp_common.h> -#include <odp/helper/ring.h> -#include <test_debug.h> - -#define RING_SIZE 4096 -#define MAX_BULK 32 - -#define RING_TEST_BASIC - -static int test_ring_basic(odph_ring_t *r) -{ - void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL; - int ret; - unsigned i, num_elems; - - /* alloc dummy object pointers */ - src = malloc(RING_SIZE*2*sizeof(void *)); - if (src == NULL) { - LOG_ERR("failed to allocate test ring src memory\n"); - goto fail; - } - for (i = 0; i < RING_SIZE*2; i++) - src[i] = (void *)(unsigned long)i; - - cur_src = src; - - /* alloc some room for copied objects */ - dst = malloc(RING_SIZE*2*sizeof(void *)); - if (dst == NULL) { - LOG_ERR("failed to allocate test ring dst memory\n"); - goto fail; - } - - memset(dst, 0, RING_SIZE*2*sizeof(void *)); - cur_dst = dst; - - printf("Test SP & SC basic functions\n"); - printf("enqueue 1 obj\n"); - ret = odph_ring_sp_enqueue_burst(r, cur_src, 1); - cur_src += 1; - if ((ret & ODPH_RING_SZ_MASK) != 1) { - LOG_ERR("sp_enq for 1 obj failed\n"); - goto fail; - } - - printf("enqueue 2 objs\n"); - ret = odph_ring_sp_enqueue_burst(r, cur_src, 2); - cur_src += 2; - if ((ret & ODPH_RING_SZ_MASK) != 2) { - LOG_ERR("sp_enq for 2 obj failed\n"); - goto fail; - } - - printf("enqueue MAX_BULK objs\n"); - ret = odph_ring_sp_enqueue_burst(r, cur_src, MAX_BULK); - if ((ret & ODPH_RING_SZ_MASK) != MAX_BULK) { - LOG_ERR("sp_enq for %d obj failed\n", MAX_BULK); - goto fail; - } - - printf("dequeue 1 obj\n"); - ret = odph_ring_sc_dequeue_burst(r, cur_dst, 1); - cur_dst += 1; - if ((ret & ODPH_RING_SZ_MASK) != 1) { - LOG_ERR("sc_deq for 1 obj failed\n"); - goto fail; - } - - printf("dequeue 2 objs\n"); - ret = odph_ring_sc_dequeue_burst(r, cur_dst, 2); - cur_dst += 2; - if ((ret & ODPH_RING_SZ_MASK) != 2) { - LOG_ERR("sc_deq for 2 obj failed\n"); - goto fail; - } - - printf("dequeue MAX_BULK objs\n"); - ret = odph_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK); - cur_dst += MAX_BULK; - if ((ret & ODPH_RING_SZ_MASK) != MAX_BULK) { - LOG_ERR("sc_deq for %d obj failed\n", MAX_BULK); - goto fail; - } - - /* check data */ - if (memcmp(src, dst, cur_dst - dst)) { - LOG_ERR("data after dequeue is not the same\n"); - goto fail; - } - - cur_src = src; - cur_dst = dst; - - printf("Test MP & MC basic functions\n"); - - printf("enqueue 1 obj\n"); - ret = odph_ring_mp_enqueue_bulk(r, cur_src, 1); - cur_src += 1; - if (ret != 0) { - LOG_ERR("mp_enq for 1 obj failed\n"); - goto fail; - } - printf("enqueue 2 objs\n"); - ret = odph_ring_mp_enqueue_bulk(r, cur_src, 2); - cur_src += 2; - if (ret != 0) { - LOG_ERR("mp_enq for 2 obj failed\n"); - goto fail; - } - printf("enqueue MAX_BULK objs\n"); - ret = odph_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK); - if (ret != 0) { - LOG_ERR("mp_enq for %d obj failed\n", MAX_BULK); - goto fail; - } - printf("dequeue 1 obj\n"); - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, 1); - cur_dst += 1; - if (ret != 0) { - LOG_ERR("mc_deq for 1 obj failed\n"); - goto fail; - } - printf("dequeue 2 objs\n"); - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, 2); - cur_dst += 2; - if (ret != 0) { - LOG_ERR("mc_deq for 2 obj failed\n"); - goto fail; - } - printf("dequeue MAX_BULK objs\n"); - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK); - cur_dst += MAX_BULK; - if (ret != 0) { - LOG_ERR("mc_deq for %d obj failed\n", MAX_BULK); - goto fail; - } - /* check data */ - if (memcmp(src, dst, cur_dst - dst)) { - LOG_ERR("data after dequeue is not the same\n"); - goto fail; - } - - printf("test watermark and default bulk enqueue / dequeue\n"); - odph_ring_set_water_mark(r, 20); - num_elems = 16; - - cur_src = src; - cur_dst = dst; - - ret = odph_ring_mp_enqueue_bulk(r, cur_src, num_elems); - cur_src += num_elems; - if (ret != 0) { - LOG_ERR("Cannot enqueue\n"); - goto fail; - } - ret = odph_ring_mp_enqueue_bulk(r, cur_src, num_elems); - if (ret != -EDQUOT) { - LOG_ERR("Watermark not exceeded\n"); - goto fail; - } - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, num_elems); - cur_dst += num_elems; - if (ret != 0) { - LOG_ERR("Cannot dequeue\n"); - goto fail; - } - ret = odph_ring_mc_dequeue_bulk(r, cur_dst, num_elems); - cur_dst += num_elems; - if (ret != 0) { - LOG_ERR("Cannot dequeue2\n"); - goto fail; - } - - /* check data */ - if (memcmp(src, dst, cur_dst - dst)) { - LOG_ERR("data after dequeue is not the same\n"); - goto fail; - } - - printf("basic enqueu, dequeue test for ring <%s>@%p passed\n", - r->name, r); - - free(src); - free(dst); - return 0; - -fail: - free(src); - free(dst); - return -1; -} - -/* global shared ring used for stress testing */ -static odph_ring_t *r_stress; - -/* Stress func for Multi producer only */ -static int producer_fn(void) -{ - unsigned i; - - void **src = NULL; - - /* alloc dummy object pointers */ - src = malloc(MAX_BULK*2*sizeof(void *)); - if (src == NULL) { - LOG_ERR("failed to allocate producer memory.\n"); - return -1; - } - for (i = 0; i < MAX_BULK; i++) - src[i] = (void *)(unsigned long)i; - - do { - i = odph_ring_mp_enqueue_bulk(r_stress, src, MAX_BULK); - if (i == 0) { - free(src); - return 0; - } - } while (1); -} - -/* Stress func for Multi consumer only */ -static int consumer_fn(void) -{ - unsigned i; - void **src = NULL; - - /* alloc dummy object pointers */ - src = malloc(MAX_BULK*2*sizeof(void *)); - if (src == NULL) { - LOG_ERR("failed to allocate consumer memory.\n"); - return -1; - } - - do { - i = odph_ring_mc_dequeue_bulk(r_stress, src, MAX_BULK); - if (i == 0) { - for (i = 0; i < MAX_BULK; i++) { - if (src[i] != (void *)(unsigned long)i) { - free(src); - printf("data mismatch.. lockless ops fail\n"); - return -1; - } - } - free(src); - printf("\n Test OK !\n"); - return 0; - } - } while (1); -} - - -/* - * Note : make sure that both enqueue and dequeue - * operation starts at same time so to avoid data corruption - * Its because atomic lock will protect only indexes, but if order of - * read or write operation incorrect then data mismatch will happen - * So its resposibility of application develop to take care of order of - * data read or write. -*/ -typedef enum { - one_enq_one_deq, /* One thread to enqueue one to - dequeu at same time */ - one_enq_rest_deq, /* one thread to enq rest to - dequeue at same time */ - one_deq_rest_enq, /* one to deq and rest enq at very same time */ - multi_enq_multi_deq /* multiple enq,deq */ -} stress_type_t; - -static void test_ring_stress(stress_type_t type) -{ - int thr; - thr = odp_thread_id(); - - switch (type) { - case one_enq_one_deq: - - if (thr == 1) - producer_fn(); - if (thr == 2) - consumer_fn(); - break; - - case multi_enq_multi_deq: - if (thr%2 == 0) - producer_fn(); - else - consumer_fn(); - break; - - case one_deq_rest_enq: - case one_enq_rest_deq:/*TBD*/ - default: - LOG_ERR("Invalid stress type or test case yet not supported\n"); - } -} - -/* local struct for ring_thread argument */ -typedef struct { - pthrd_arg thrdarg; - int stress_type; -} ring_arg_t; - - -static void *test_ring(void *arg) -{ - ring_arg_t *parg = (ring_arg_t *)arg; - int thr; - char ring_name[ODPH_RING_NAMESIZE]; - odph_ring_t *r; - int result = 0; - - thr = odp_thread_id(); - - printf("Thread %i starts\n", thr); - - switch (parg->thrdarg.testcase) { - case ODP_RING_TEST_BASIC: - snprintf(ring_name, sizeof(ring_name), "test_ring_%i", thr); - - r = odph_ring_create(ring_name, RING_SIZE, - 0 /* not used, alignement - taken care inside func : todo */); - if (r == NULL) { - LOG_ERR("ring create failed\n"); - result = -1; - break; - } - /* lookup ring from its name */ - if (odph_ring_lookup(ring_name) != r) { - LOG_ERR("ring lookup failed\n"); - result = -1; - break; - } - - /* basic operations */ - if (test_ring_basic(r) < 0) { - LOG_ERR("ring basic enqueue/dequeu ops failed\n"); - result = -1; - } - - /* dump ring stats */ - odph_ring_list_dump(); - - break; - - case ODP_RING_TEST_STRESS: - test_ring_stress(parg->stress_type); - - /* dump ring stats */ - odph_ring_list_dump(); - break; - - default: - LOG_ERR("Invalid test case [%d]\n", parg->thrdarg.testcase); - result = -1; - break; - } - - LOG_DBG("result = %d\n", result); - if (result == 0) - printf("test_ring Result:pass\n"); - else - printf("test_ring Result:fail\n"); - - fflush(stdout); - - return parg; -} - - -int main(int argc __attribute__((__unused__)), - char *argv[] __attribute__((__unused__))) -{ - ring_arg_t rarg; - - if (odp_test_global_init() != 0) - return -1; - - odp_print_system_info(); - - odph_ring_tailq_init(); - - rarg.thrdarg.numthrds = odp_cpu_count(); - -#ifdef RING_TEST_BASIC - rarg.thrdarg.testcase = ODP_RING_TEST_BASIC; -#else - rarg.thrdarg.testcase = ODP_RING_TEST_STRESS; - rarg.stress_type = one_enq_one_deq; -/* rarg.stress_type = multi_enq_multi_deq;*/ - char ring_name[ODPH_RING_NAMESIZE]; - - printf("starting stess test type : %d..\n", rarg.stress_type); - /* create a ring */ - snprintf(ring_name, sizeof(ring_name), "test_ring_stress"); - - r_stress = odph_ring_create(ring_name, RING_SIZE, - 0 /* not used, alignement - taken care inside func : todo */); - if (r_stress == NULL) { - LOG_ERR("ring create failed\n"); - goto fail; - } - /* lookup ring from its name */ - if (odph_ring_lookup(ring_name) != r_stress) { - LOG_ERR("ring lookup failed\n"); - goto fail; - } -#endif - odp_test_thread_create(test_ring, (pthrd_arg *)&rarg); - -#ifndef RING_TEST_BASIC -fail: -#endif - - odp_test_thread_exit(&rarg.thrdarg); - - return 0; -} -
Remove ring and dead api-next code. In api-next pktio ipc patches moved ring code to linux-generic and updated that test case to the latest odp api. If we ipc pktio will be accepted to master than current api-next ring test will be used. Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> --- configure.ac | 1 - helper/Makefile.am | 2 - helper/include/odp/helper/ring.h | 577 ----------------------------------- helper/ring.c | 634 --------------------------------------- test/Makefile.am | 2 +- test/api_test/.gitignore | 2 - test/api_test/Makefile.am | 16 - test/api_test/odp_common.c | 91 ------ test/api_test/odp_common.h | 42 --- test/api_test/odp_ring_test.c | 470 ----------------------------- 10 files changed, 1 insertion(+), 1836 deletions(-) delete mode 100644 helper/include/odp/helper/ring.h delete mode 100644 helper/ring.c delete mode 100644 test/api_test/.gitignore delete mode 100644 test/api_test/Makefile.am delete mode 100644 test/api_test/odp_common.c delete mode 100644 test/api_test/odp_common.h delete mode 100644 test/api_test/odp_ring_test.c