On 17 February 2016 at 05:16, Maxim Uvarov <maxim.uva...@linaro.org
<mailto:maxim.uva...@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.uva...@linaro.org
<mailto:maxim.uva...@linaro.org>>
Reviewed-by Mike Holmes <mike.hol...@linaro.org
<mailto:mike.hol...@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 km...@freebsd.org
<mailto:km...@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 km...@freebsd.org
<mailto:km...@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"