From patchwork Sat Jan 18 19:32:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Honnappa Nagarahalli X-Patchwork-Id: 182887 Delivered-To: patch@linaro.org Received: by 2002:a92:1f12:0:0:0:0:0 with SMTP id i18csp797403ile; Sat, 18 Jan 2020 11:33:27 -0800 (PST) X-Google-Smtp-Source: APXvYqzevbHx8VQgVuqDK/2h+IGlui0mvzw81shs+rWwZNJCFqcFMwHK8TWb5YZbBCgpxu1/yNaf X-Received: by 2002:aa7:c6c5:: with SMTP id b5mr10252872eds.281.1579376007310; Sat, 18 Jan 2020 11:33:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579376007; cv=none; d=google.com; s=arc-20160816; b=FncUwbZF+GBNQ7OkGRhTmiqt5XaNTZQRODGshuLso1FAEUd5FPU4AQjSOb4xgkO0RN 1D2sGa+R1CxZAKwZHi9toP1fGqKaZjrM611DtmWhbYuUpDgxfistFsv6+VUKBx+liCGt 9Sdv94hltS9SqQTu4XvBCikEfW4GyrKu/YMo70QxmEnKAOPA7ajBIoHHiQ5+zP/rLs38 3JNCJ6IrcTLGpTV/tmJGjq6Uw9IE0X9ymZYFjuBD6fAqxhPY70oTJsxlXuoIbWRzZBs7 9T0rHAtdnf3iNYg6TzcUxuM96wPaLyyl2YfWMyFtYX80F2bELrlt2sESDLryXQGWsZYB K8xw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:cc:to:from; bh=KENw2xtpJ0GypQtldiFBebXY2yjlBQOTHPCiFO2YwW4=; b=Kr8522whi86jJKbuoFaL4YCBrIZg+NKR/LvVzqPQgZSerYIyaa+fzJPXFZYnPF4lzy me50Z7xV7CzTxsTXq0AlibdUruQ++DCM5Ds4GOuWti0LXRInCrkach+Ba8WAUWm/nHCw 8K5lJpkCoNFscjLmagV0T+Uqa98XZrl7b1TxTl1PhoAymybVlp1fTNcSZFYJaVMUXPbr QcSYfHenn/U/2d62cecRrzqxWjfFq78yI8ZK4BTrRSAX0BtdLLaKEpPKCWaExFz0B/eF ipwlNnz8l9Ujkydxi22PA12+vC0+dE/p1gpql7JhFIGp/m8ss4Smm+Z9j3D3P2gwz/3T c06w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of dev-bounces@dpdk.org designates 92.243.14.124 as permitted sender) smtp.mailfrom=dev-bounces@dpdk.org Return-Path: Received: from dpdk.org (dpdk.org. [92.243.14.124]) by mx.google.com with ESMTP id gv22si18306709ejb.99.2020.01.18.11.33.26; Sat, 18 Jan 2020 11:33:27 -0800 (PST) Received-SPF: pass (google.com: domain of dev-bounces@dpdk.org designates 92.243.14.124 as permitted sender) client-ip=92.243.14.124; Authentication-Results: mx.google.com; spf=pass (google.com: domain of dev-bounces@dpdk.org designates 92.243.14.124 as permitted sender) smtp.mailfrom=dev-bounces@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3EF1F1BF6F; Sat, 18 Jan 2020 20:33:14 +0100 (CET) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by dpdk.org (Postfix) with ESMTP id 76F441BECF for ; Sat, 18 Jan 2020 20:33:10 +0100 (CET) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EE9E511D4; Sat, 18 Jan 2020 11:33:09 -0800 (PST) Received: from qc2400f-1.austin.arm.com (qc2400f-1.austin.arm.com [10.118.14.48]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D0FC33F6C4; Sat, 18 Jan 2020 11:33:09 -0800 (PST) From: Honnappa Nagarahalli To: olivier.matz@6wind.com, sthemmin@microsoft.com, jerinj@marvell.com, bruce.richardson@intel.com, david.marchand@redhat.com, pbhagavatula@marvell.com, konstantin.ananyev@intel.com, yipeng1.wang@intel.com, drc@linux.vnet.ibm.com, honnappa.nagarahalli@arm.com Cc: dev@dpdk.org, dharmik.thakkar@arm.com, ruifeng.wang@arm.com, gavin.hu@arm.com, nd@arm.com Date: Sat, 18 Jan 2020 13:32:44 -0600 Message-Id: <20200118193247.43831-4-honnappa.nagarahalli@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200118193247.43831-1-honnappa.nagarahalli@arm.com> References: <20190906190510.11146-1-honnappa.nagarahalli@arm.com> <20200118193247.43831-1-honnappa.nagarahalli@arm.com> Subject: [dpdk-dev] [PATCH v10 3/6] test/ring: add functional tests for rte_ring_xxx_elem APIs X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add basic infrastructure to test rte_ring_xxx_elem APIs. Adjust the existing test cases to test for various ring element sizes. Signed-off-by: Honnappa Nagarahalli Reviewed-by: Gavin Hu --- app/test/test_ring.c | 1383 +++++++++++++++++++++--------------------- app/test/test_ring.h | 187 ++++++ 2 files changed, 875 insertions(+), 695 deletions(-) create mode 100644 app/test/test_ring.h -- 2.17.1 diff --git a/app/test/test_ring.c b/app/test/test_ring.c index aaf1e70ad..fbcd109b1 100644 --- a/app/test/test_ring.c +++ b/app/test/test_ring.c @@ -23,40 +23,29 @@ #include #include #include +#include #include #include #include #include "test.h" +#include "test_ring.h" /* * Ring * ==== * - * #. Basic tests: done on one core: + * #. Functional tests. Tests single/bulk/burst, default/SPSC/MPMC, + * legacy/custom element size (4B, 8B, 16B, 20B) APIs. + * Some tests incorporate unaligned addresses for objects. + * The enqueued/dequeued data is validated for correctness. * - * - Using single producer/single consumer functions: - * - * - Enqueue one object, two objects, MAX_BULK objects - * - Dequeue one object, two objects, MAX_BULK objects - * - Check that dequeued pointers are correct - * - * - Using multi producers/multi consumers functions: - * - * - Enqueue one object, two objects, MAX_BULK objects - * - Dequeue one object, two objects, MAX_BULK objects - * - Check that dequeued pointers are correct - * - * #. Performance tests. - * - * Tests done in test_ring_perf.c + * #. Performance tests are in test_ring_perf.c */ #define RING_SIZE 4096 #define MAX_BULK 32 -static rte_atomic32_t synchro; - #define TEST_RING_VERIFY(exp) \ if (!(exp)) { \ printf("error at %s:%d\tcondition " #exp " failed\n", \ @@ -67,808 +56,812 @@ static rte_atomic32_t synchro; #define TEST_RING_FULL_EMTPY_ITER 8 -/* - * helper routine for test_ring_basic - */ -static int -test_ring_basic_full_empty(struct rte_ring *r, void * const src[], void *dst[]) +static const int esize[] = {-1, 4, 8, 16, 20}; + +static void** +test_ring_inc_ptr(void **obj, int esize, unsigned int n) { - unsigned i, rand; - const unsigned rsz = RING_SIZE - 1; - - printf("Basic full/empty test\n"); - - for (i = 0; TEST_RING_FULL_EMTPY_ITER != i; i++) { - - /* random shift in the ring */ - rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL); - printf("%s: iteration %u, random shift: %u;\n", - __func__, i, rand); - TEST_RING_VERIFY(rte_ring_enqueue_bulk(r, src, rand, - NULL) != 0); - TEST_RING_VERIFY(rte_ring_dequeue_bulk(r, dst, rand, - NULL) == rand); - - /* fill the ring */ - TEST_RING_VERIFY(rte_ring_enqueue_bulk(r, src, rsz, NULL) != 0); - TEST_RING_VERIFY(0 == rte_ring_free_count(r)); - TEST_RING_VERIFY(rsz == rte_ring_count(r)); - TEST_RING_VERIFY(rte_ring_full(r)); - TEST_RING_VERIFY(0 == rte_ring_empty(r)); - - /* empty the ring */ - TEST_RING_VERIFY(rte_ring_dequeue_bulk(r, dst, rsz, - NULL) == rsz); - TEST_RING_VERIFY(rsz == rte_ring_free_count(r)); - TEST_RING_VERIFY(0 == rte_ring_count(r)); - TEST_RING_VERIFY(0 == rte_ring_full(r)); - TEST_RING_VERIFY(rte_ring_empty(r)); + /* Legacy queue APIs? */ + if ((esize) == -1) + return ((void **)obj) + n; + else + return (void **)(((uint32_t *)obj) + + (n * esize / sizeof(uint32_t))); +} - /* check data */ - TEST_RING_VERIFY(0 == memcmp(src, dst, rsz)); - rte_ring_dump(stdout, r); - } - return 0; +static void +test_ring_mem_init(void *obj, unsigned int count, int esize) +{ + unsigned int i; + + /* Legacy queue APIs? */ + if (esize == -1) + for (i = 0; i < count; i++) + ((void **)obj)[i] = (void *)(unsigned long)i; + else + for (i = 0; i < (count * esize / sizeof(uint32_t)); i++) + ((uint32_t *)obj)[i] = i; } -static int -test_ring_basic(struct rte_ring *r) +static void +test_ring_print_test_string(const char *istr, unsigned int api_type, int esize) { - void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL; - int ret; - unsigned i, num_elems; + printf("\n%s: ", istr); + + if (esize == -1) + printf("legacy APIs: "); + else + printf("elem APIs: element size %dB ", esize); + + if (api_type == TEST_RING_IGNORE_API_TYPE) + return; + + if (api_type & TEST_RING_THREAD_DEF) + printf(": default enqueue/dequeue: "); + else if (api_type & TEST_RING_THREAD_SPSC) + printf(": SP/SC: "); + else if (api_type & TEST_RING_THREAD_MPMC) + printf(": MP/MC: "); + + if (api_type & TEST_RING_ELEM_SINGLE) + printf("single\n"); + else if (api_type & TEST_RING_ELEM_BULK) + printf("bulk\n"); + else if (api_type & TEST_RING_ELEM_BURST) + printf("burst\n"); +} - /* alloc dummy object pointers */ - src = malloc(RING_SIZE*2*sizeof(void *)); - if (src == NULL) - goto fail; +/* + * Various negative test cases. + */ +static int +test_ring_negative_tests(void) +{ + struct rte_ring *rp = NULL; + struct rte_ring *rt = NULL; + unsigned int i; - 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) - goto fail; - - memset(dst, 0, RING_SIZE*2*sizeof(void *)); - cur_dst = dst; - - printf("enqueue 1 obj\n"); - ret = rte_ring_sp_enqueue_bulk(r, cur_src, 1, NULL); - cur_src += 1; - if (ret == 0) - goto fail; - - printf("enqueue 2 objs\n"); - ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2, NULL); - cur_src += 2; - if (ret == 0) - goto fail; - - printf("enqueue MAX_BULK objs\n"); - ret = rte_ring_sp_enqueue_bulk(r, cur_src, MAX_BULK, NULL); - cur_src += MAX_BULK; - if (ret == 0) - goto fail; - - printf("dequeue 1 obj\n"); - ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1, NULL); - cur_dst += 1; - if (ret == 0) - goto fail; - - printf("dequeue 2 objs\n"); - ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2, NULL); - cur_dst += 2; - if (ret == 0) - goto fail; - - printf("dequeue MAX_BULK objs\n"); - ret = rte_ring_sc_dequeue_bulk(r, cur_dst, MAX_BULK, NULL); - cur_dst += MAX_BULK; - if (ret == 0) - goto fail; - - /* check data */ - if (memcmp(src, dst, cur_dst - dst)) { - rte_hexdump(stdout, "src", src, cur_src - src); - rte_hexdump(stdout, "dst", dst, cur_dst - dst); - printf("data after dequeue is not the same\n"); - goto fail; - } - cur_src = src; - cur_dst = dst; - - printf("enqueue 1 obj\n"); - ret = rte_ring_mp_enqueue_bulk(r, cur_src, 1, NULL); - cur_src += 1; - if (ret == 0) - goto fail; - - printf("enqueue 2 objs\n"); - ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2, NULL); - cur_src += 2; - if (ret == 0) - goto fail; - - printf("enqueue MAX_BULK objs\n"); - ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK, NULL); - cur_src += MAX_BULK; - if (ret == 0) - goto fail; - - printf("dequeue 1 obj\n"); - ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1, NULL); - cur_dst += 1; - if (ret == 0) - goto fail; - - printf("dequeue 2 objs\n"); - ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2, NULL); - cur_dst += 2; - if (ret == 0) - goto fail; - - printf("dequeue MAX_BULK objs\n"); - ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK, NULL); - cur_dst += MAX_BULK; - if (ret == 0) - goto fail; - - /* check data */ - if (memcmp(src, dst, cur_dst - dst)) { - rte_hexdump(stdout, "src", src, cur_src - src); - rte_hexdump(stdout, "dst", dst, cur_dst - dst); - printf("data after dequeue is not the same\n"); - goto fail; - } - cur_src = src; - cur_dst = dst; - - printf("fill and empty the ring\n"); - for (i = 0; i= rte_ring_get_size(exact_sz_r)) { + printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n", + __func__, + rte_ring_get_size(std_r), + rte_ring_get_size(exact_sz_r)); + goto test_fail; + } + /* + * check that the exact_sz_ring can hold one more element + * than the standard ring. (16 vs 15 elements) + */ + for (j = 0; j < ring_sz - 1; j++) { + test_ring_enqueue(std_r, obj, esize[i], 1, + TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); + test_ring_enqueue(exact_sz_r, obj, esize[i], 1, + TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); + } + ret = test_ring_enqueue(std_r, obj, esize[i], 1, + TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); + if (ret != -ENOBUFS) { + printf("%s: error, unexpected successful enqueue\n", + __func__); + goto test_fail; + } + ret = test_ring_enqueue(exact_sz_r, obj, esize[i], 1, + TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE); + if (ret == -ENOBUFS) { + printf("%s: error, enqueue failed\n", __func__); + goto test_fail; + } + + /* check that dequeue returns the expected number of elements */ + ret = test_ring_dequeue(exact_sz_r, obj, esize[i], ring_sz, + TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST); + if (ret != (int)ring_sz) { + printf("%s: error, failed to dequeue expected nb of elements\n", + __func__); + goto test_fail; + } - /* - * Check that the exact size ring is bigger than the standard ring - */ - if (rte_ring_get_size(std_ring) >= rte_ring_get_size(exact_sz_ring)) { - printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n", - __func__, - rte_ring_get_size(std_ring), - rte_ring_get_size(exact_sz_ring)); - goto end; - } - /* - * check that the exact_sz_ring can hold one more element than the - * standard ring. (16 vs 15 elements) - */ - for (i = 0; i < ring_sz - 1; i++) { - rte_ring_enqueue(std_ring, NULL); - rte_ring_enqueue(exact_sz_ring, NULL); - } - if (rte_ring_enqueue(std_ring, NULL) != -ENOBUFS) { - printf("%s: error, unexpected successful enqueue\n", __func__); - goto end; - } - if (rte_ring_enqueue(exact_sz_ring, NULL) == -ENOBUFS) { - printf("%s: error, enqueue failed\n", __func__); - goto end; - } + /* check that the capacity function returns expected value */ + if (rte_ring_get_capacity(exact_sz_r) != ring_sz) { + printf("%s: error, incorrect ring capacity reported\n", + __func__); + goto test_fail; + } - /* check that dequeue returns the expected number of elements */ - if (rte_ring_dequeue_burst(exact_sz_ring, ptr_array, - RTE_DIM(ptr_array), NULL) != ring_sz) { - printf("%s: error, failed to dequeue expected nb of elements\n", - __func__); - goto end; + rte_free(obj_orig); + rte_ring_free(std_r); + rte_ring_free(exact_sz_r); + obj_orig = NULL; + std_r = NULL; + exact_sz_r = NULL; } - /* check that the capacity function returns expected value */ - if (rte_ring_get_capacity(exact_sz_ring) != ring_sz) { - printf("%s: error, incorrect ring capacity reported\n", - __func__); - goto end; - } + return 0; - ret = 0; /* all ok if we get here */ -end: - rte_ring_free(std_ring); - rte_ring_free(exact_sz_ring); - return ret; +test_fail: + rte_free(obj_orig); + rte_ring_free(std_r); + rte_ring_free(exact_sz_r); + return -1; } static int test_ring(void) { - struct rte_ring *r = NULL; - - /* some more basic operations */ - if (test_ring_basic_ex() < 0) - goto test_fail; - - rte_atomic32_init(&synchro); - - r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0); - if (r == NULL) - goto test_fail; - - /* retrieve the ring from its name */ - if (rte_ring_lookup("test") != r) { - printf("Cannot lookup ring from its name\n"); - goto test_fail; - } - - /* burst operations */ - if (test_ring_burst_basic(r) < 0) - goto test_fail; + unsigned int i, j; - /* basic operations */ - if (test_ring_basic(r) < 0) + /* Negative test cases */ + if (test_ring_negative_tests() < 0) goto test_fail; - /* basic operations */ - if ( test_create_count_odd() < 0){ - printf("Test failed to detect odd count\n"); - goto test_fail; - } else - printf("Test detected odd count\n"); - - if ( test_lookup_null() < 0){ - printf("Test failed to detect NULL ring lookup\n"); - goto test_fail; - } else - printf("Test detected NULL ring lookup\n"); - - /* test of creating ring with wrong size */ - if (test_ring_creation_with_wrong_size() < 0) - goto test_fail; - - /* test of creation ring with an used name */ - if (test_ring_creation_with_an_used_name() < 0) + /* Some basic operations */ + if (test_ring_basic_ex() < 0) goto test_fail; if (test_ring_with_exact_size() < 0) goto test_fail; + /* Burst and bulk operations with sp/sc, mp/mc and default. + * The test cases are split into smaller test cases to + * help clang compile faster. + */ + for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1) + for (i = TEST_RING_THREAD_DEF; + i <= TEST_RING_THREAD_MPMC; i <<= 1) + if (test_ring_burst_bulk_tests1(i | j) < 0) + goto test_fail; + + for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1) + for (i = TEST_RING_THREAD_DEF; + i <= TEST_RING_THREAD_MPMC; i <<= 1) + if (test_ring_burst_bulk_tests2(i | j) < 0) + goto test_fail; + + for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1) + for (i = TEST_RING_THREAD_DEF; + i <= TEST_RING_THREAD_MPMC; i <<= 1) + if (test_ring_burst_bulk_tests3(i | j) < 0) + goto test_fail; + + for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1) + for (i = TEST_RING_THREAD_DEF; + i <= TEST_RING_THREAD_MPMC; i <<= 1) + if (test_ring_burst_bulk_tests4(i | j) < 0) + goto test_fail; + /* dump the ring status */ rte_ring_list_dump(stdout); - rte_ring_free(r); - return 0; test_fail: - rte_ring_free(r); return -1; } diff --git a/app/test/test_ring.h b/app/test/test_ring.h new file mode 100644 index 000000000..aa6ae67ca --- /dev/null +++ b/app/test/test_ring.h @@ -0,0 +1,187 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Arm Limited + */ + +#include +#include +#include + +/* API type to call + * rte_ring__enqueue_ + * TEST_RING_THREAD_DEF - Uses configured SPSC/MPMC calls + * TEST_RING_THREAD_SPSC - Calls SP or SC API + * TEST_RING_THREAD_MPMC - Calls MP or MC API + */ +#define TEST_RING_THREAD_DEF 1 +#define TEST_RING_THREAD_SPSC 2 +#define TEST_RING_THREAD_MPMC 4 + +/* API type to call + * TEST_RING_ELEM_SINGLE - Calls single element APIs + * TEST_RING_ELEM_BULK - Calls bulk APIs + * TEST_RING_ELEM_BURST - Calls burst APIs + */ +#define TEST_RING_ELEM_SINGLE 8 +#define TEST_RING_ELEM_BULK 16 +#define TEST_RING_ELEM_BURST 32 + +#define TEST_RING_IGNORE_API_TYPE ~0U + +/* This function is placed here as it is required for both + * performance and functional tests. + */ +static inline struct rte_ring* +test_ring_create(const char *name, int esize, unsigned int count, + int socket_id, unsigned int flags) +{ + /* Legacy queue APIs? */ + if ((esize) == -1) + return rte_ring_create((name), (count), (socket_id), (flags)); + else + return rte_ring_create_elem((name), (esize), (count), + (socket_id), (flags)); +} + +static __rte_always_inline unsigned int +test_ring_enqueue(struct rte_ring *r, void **obj, int esize, unsigned int n, + unsigned int api_type) +{ + /* Legacy queue APIs? */ + if ((esize) == -1) + switch (api_type) { + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE): + return rte_ring_enqueue(r, obj); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE): + return rte_ring_sp_enqueue(r, obj); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE): + return rte_ring_mp_enqueue(r, obj); + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK): + return rte_ring_enqueue_bulk(r, obj, n, NULL); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK): + return rte_ring_sp_enqueue_bulk(r, obj, n, NULL); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK): + return rte_ring_mp_enqueue_bulk(r, obj, n, NULL); + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST): + return rte_ring_enqueue_burst(r, obj, n, NULL); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST): + return rte_ring_sp_enqueue_burst(r, obj, n, NULL); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST): + return rte_ring_mp_enqueue_burst(r, obj, n, NULL); + default: + printf("Invalid API type\n"); + return 0; + } + else + switch (api_type) { + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE): + return rte_ring_enqueue_elem(r, obj, esize); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE): + return rte_ring_sp_enqueue_elem(r, obj, esize); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE): + return rte_ring_mp_enqueue_elem(r, obj, esize); + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK): + return rte_ring_enqueue_bulk_elem(r, obj, esize, n, + NULL); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK): + return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, n, + NULL); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK): + return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, n, + NULL); + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST): + return rte_ring_enqueue_burst_elem(r, obj, esize, n, + NULL); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST): + return rte_ring_sp_enqueue_burst_elem(r, obj, esize, n, + NULL); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST): + return rte_ring_mp_enqueue_burst_elem(r, obj, esize, n, + NULL); + default: + printf("Invalid API type\n"); + return 0; + } +} + +static __rte_always_inline unsigned int +test_ring_dequeue(struct rte_ring *r, void **obj, int esize, unsigned int n, + unsigned int api_type) +{ + /* Legacy queue APIs? */ + if ((esize) == -1) + switch (api_type) { + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE): + return rte_ring_dequeue(r, obj); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE): + return rte_ring_sc_dequeue(r, obj); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE): + return rte_ring_mc_dequeue(r, obj); + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK): + return rte_ring_dequeue_bulk(r, obj, n, NULL); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK): + return rte_ring_sc_dequeue_bulk(r, obj, n, NULL); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK): + return rte_ring_mc_dequeue_bulk(r, obj, n, NULL); + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST): + return rte_ring_dequeue_burst(r, obj, n, NULL); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST): + return rte_ring_sc_dequeue_burst(r, obj, n, NULL); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST): + return rte_ring_mc_dequeue_burst(r, obj, n, NULL); + default: + printf("Invalid API type\n"); + return 0; + } + else + switch (api_type) { + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE): + return rte_ring_dequeue_elem(r, obj, esize); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE): + return rte_ring_sc_dequeue_elem(r, obj, esize); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE): + return rte_ring_mc_dequeue_elem(r, obj, esize); + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK): + return rte_ring_dequeue_bulk_elem(r, obj, esize, + n, NULL); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK): + return rte_ring_sc_dequeue_bulk_elem(r, obj, esize, + n, NULL); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK): + return rte_ring_mc_dequeue_bulk_elem(r, obj, esize, + n, NULL); + case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST): + return rte_ring_dequeue_burst_elem(r, obj, esize, + n, NULL); + case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST): + return rte_ring_sc_dequeue_burst_elem(r, obj, esize, + n, NULL); + case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST): + return rte_ring_mc_dequeue_burst_elem(r, obj, esize, + n, NULL); + default: + printf("Invalid API type\n"); + return 0; + } +} + +/* This function is placed here as it is required for both + * performance and functional tests. + */ +static __rte_always_inline void * +test_ring_calloc(unsigned int rsize, int esize) +{ + unsigned int sz; + void *p; + + /* Legacy queue APIs? */ + if (esize == -1) + sz = sizeof(void *); + else + sz = esize; + + p = rte_zmalloc(NULL, rsize * sz, RTE_CACHE_LINE_SIZE); + if (p == NULL) + printf("Failed to allocate memory\n"); + + return p; +}