From patchwork Wed Aug 28 14:46:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Honnappa Nagarahalli X-Patchwork-Id: 172393 Delivered-To: patch@linaro.org Received: by 2002:ac9:5c4b:0:0:0:0:0 with SMTP id r11csp1016251ocp; Wed, 28 Aug 2019 07:46:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqwwLP38yrf5dUIDw0KAzBy3bVQjtRtpF1pqOCAATFDsQGu7NHhg+ldqVm03MPjcRjZ0mJPf X-Received: by 2002:a17:906:185b:: with SMTP id w27mr3507020eje.203.1567003607044; Wed, 28 Aug 2019 07:46:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1567003607; cv=none; d=google.com; s=arc-20160816; b=hswNxYhrmb2SWoPoWyFqLq9cNHnna7OzI0GMLCe/KPnChDWpWAhJz1KPnmO7yDJe0/ XpUS7RR3D0rv1Wk58ER6PfVy/T+wp6hzym1D0gH6uVMkvitABikLgTavta+BNQc48my2 of+U3hVJY/U5aOBX7p4Lm3L+mh7rlQx5uj+WCjjkap0ATdrH9P1n+P46lqFiZwzX27nS qhyoBaFkbP8H7c1COlyRbONmr1Rh3X251ptI8LLD21YKwDdtxAFiRAzLTjQ6zYCJyPzm iIyK1bowI744HZN2IuTmFaXY6lv9HxWg9Ppay45CY0wo/QUUs1ZksvNimXB8FZ5xHCGB rs2A== 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=YE0xLBhdUSbcqZSeWiTBt6N3FhWOYjuxFo9GA5h5eFs=; b=bIJKgwRpRBFf3a43oujZsZizSMDCpVX3oFzTCXdzcpt+ut6caZPGL+7wfF6yxwby8Z R7tJM9wuWVOHgOULfF+hC61X/rZKtIwBxDeNGXh5vOP6tWgZh67zZjAf+OAiDYqqmq6t qBKUHWzSiuE4P5BTz2lzLtdIXrDyiNmW4EKf0oDKGjo9FkxMdYTBt4WFoSYWE8eeQ2PH Y1IAR1jZuZUH3qK7TL5N85b65fexCuUlO1fXwKmFFd7dNxO9XzSlrBrS8UEU0QMTwvY/ dDMI2GXqIMkHkGBahMbsuwZNt3HWQH4KrmZnvlU0Hv8n6DBzHkF8XH2FNlQ1LbpVo/JA Vtzw== 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 s47si1424941edb.351.2019.08.28.07.46.46; Wed, 28 Aug 2019 07:46:47 -0700 (PDT) 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 E35551BF36; Wed, 28 Aug 2019 16:46:39 +0200 (CEST) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by dpdk.org (Postfix) with ESMTP id 2D65A2952 for ; Wed, 28 Aug 2019 16:46:37 +0200 (CEST) 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 AD85D360; Wed, 28 Aug 2019 07:46:36 -0700 (PDT) Received: from qc2400f-1.austin.arm.com (qc2400f-1.austin.arm.com [10.118.12.34]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 967A23F246; Wed, 28 Aug 2019 07:46:36 -0700 (PDT) From: Honnappa Nagarahalli To: olivier.matz@6wind.com, yipeng1.wang@intel.com, sameh.gobriel@intel.com, bruce.richardson@intel.com, pablo.de.lara.guarch@intel.com, honnappa.nagarahalli@arm.com Cc: dev@dpdk.org, dharmik.thakkar@arm.com, gavin.hu@arm.com, ruifeng.wang@arm.com, nd@arm.com Date: Wed, 28 Aug 2019 09:46:11 -0500 Message-Id: <20190828144614.25284-3-honnappa.nagarahalli@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190828144614.25284-1-honnappa.nagarahalli@arm.com> References: <20190828144614.25284-1-honnappa.nagarahalli@arm.com> Subject: [dpdk-dev] [PATCH 2/5] lib/ring: add template to support different element sizes 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 templates to support creating ring APIs with different ring element sizes. Signed-off-by: Honnappa Nagarahalli Reviewed-by: Dharmik Thakkar Reviewed-by: Gavin Hu Reviewed-by: Ruifeng Wang --- lib/librte_ring/Makefile | 4 +- lib/librte_ring/meson.build | 4 +- lib/librte_ring/rte_ring_template.c | 46 ++++ lib/librte_ring/rte_ring_template.h | 330 ++++++++++++++++++++++++++++ 4 files changed, 382 insertions(+), 2 deletions(-) create mode 100644 lib/librte_ring/rte_ring_template.c create mode 100644 lib/librte_ring/rte_ring_template.h -- 2.17.1 diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile index 4c8410229..818898110 100644 --- a/lib/librte_ring/Makefile +++ b/lib/librte_ring/Makefile @@ -19,6 +19,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_RING) := rte_ring.c # install includes SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \ rte_ring_generic.h \ - rte_ring_c11_mem.h + rte_ring_c11_mem.h \ + rte_ring_template.h \ + rte_ring_template.c include $(RTE_SDK)/mk/rte.lib.mk diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build index 74219840a..e4e208a7c 100644 --- a/lib/librte_ring/meson.build +++ b/lib/librte_ring/meson.build @@ -5,7 +5,9 @@ version = 2 sources = files('rte_ring.c') headers = files('rte_ring.h', 'rte_ring_c11_mem.h', - 'rte_ring_generic.h') + 'rte_ring_generic.h', + 'rte_ring_template.h', + 'rte_ring_template.c') # rte_ring_create_elem and rte_ring_get_memsize_elem are experimental allow_experimental_apis = true diff --git a/lib/librte_ring/rte_ring_template.c b/lib/librte_ring/rte_ring_template.c new file mode 100644 index 000000000..1ca593f95 --- /dev/null +++ b/lib/librte_ring/rte_ring_template.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2019 Arm Limited + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rte_ring.h" + +/* return the size of memory occupied by a ring */ +ssize_t +__RTE_RING_CONCAT(rte_ring_get_memsize)(unsigned count) +{ + return rte_ring_get_memsize_elem(count, RTE_RING_TMPLT_ELEM_SIZE); +} + +/* create the ring */ +struct rte_ring * +__RTE_RING_CONCAT(rte_ring_create)(const char *name, unsigned count, + int socket_id, unsigned flags) +{ + return rte_ring_create_elem(name, count, RTE_RING_TMPLT_ELEM_SIZE, + socket_id, flags); +} diff --git a/lib/librte_ring/rte_ring_template.h b/lib/librte_ring/rte_ring_template.h new file mode 100644 index 000000000..b9b14dfbb --- /dev/null +++ b/lib/librte_ring/rte_ring_template.h @@ -0,0 +1,330 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2019 Arm Limited + */ + +#ifndef _RTE_RING_TEMPLATE_H_ +#define _RTE_RING_TEMPLATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Ring API suffix name - used to append to API names */ +#ifndef RTE_RING_TMPLT_API_SUFFIX +#error RTE_RING_TMPLT_API_SUFFIX not defined +#endif + +/* Ring's element size in bits, should be a power of 2 */ +#ifndef RTE_RING_TMPLT_ELEM_SIZE +#error RTE_RING_TMPLT_ELEM_SIZE not defined +#endif + +/* Type of ring elements */ +#ifndef RTE_RING_TMPLT_ELEM_TYPE +#error RTE_RING_TMPLT_ELEM_TYPE not defined +#endif + +#define _rte_fuse(a, b) a##_##b +#define __rte_fuse(a, b) _rte_fuse(a, b) +#define __RTE_RING_CONCAT(a) __rte_fuse(a, RTE_RING_TMPLT_API_SUFFIX) + +/* Calculate the memory size needed for a ring */ +RTE_RING_TMPLT_EXPERIMENTAL +ssize_t __RTE_RING_CONCAT(rte_ring_get_memsize)(unsigned count); + +/* Create a new ring named *name* in memory. */ +RTE_RING_TMPLT_EXPERIMENTAL +struct rte_ring * +__RTE_RING_CONCAT(rte_ring_create)(const char *name, unsigned count, + int socket_id, unsigned flags); + +/** + * @internal Enqueue several objects on the ring + */ +static __rte_always_inline unsigned int +__RTE_RING_CONCAT(__rte_ring_do_enqueue)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE const *obj_table, unsigned int n, + enum rte_ring_queue_behavior behavior, unsigned int is_sp, + unsigned int *free_space) +{ + uint32_t prod_head, prod_next; + uint32_t free_entries; + + n = __rte_ring_move_prod_head(r, is_sp, n, behavior, + &prod_head, &prod_next, &free_entries); + if (n == 0) + goto end; + + ENQUEUE_PTRS(r, &r[1], prod_head, obj_table, n, + RTE_RING_TMPLT_ELEM_TYPE); + + update_tail(&r->prod, prod_head, prod_next, is_sp, 1); +end: + if (free_space != NULL) + *free_space = free_entries - n; + return n; +} + +/** + * @internal Dequeue several objects from the ring + */ +static __rte_always_inline unsigned int +__RTE_RING_CONCAT(__rte_ring_do_dequeue)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, unsigned int n, + enum rte_ring_queue_behavior behavior, unsigned int is_sc, + unsigned int *available) +{ + uint32_t cons_head, cons_next; + uint32_t entries; + + n = __rte_ring_move_cons_head(r, (int)is_sc, n, behavior, + &cons_head, &cons_next, &entries); + if (n == 0) + goto end; + + DEQUEUE_PTRS(r, &r[1], cons_head, obj_table, n, + RTE_RING_TMPLT_ELEM_TYPE); + + update_tail(&r->cons, cons_head, cons_next, is_sc, 0); + +end: + if (available != NULL) + *available = entries - n; + return n; +} + + +/** + * Enqueue several objects on the ring (multi-producers safe). + */ +static __rte_always_inline unsigned int +__RTE_RING_CONCAT(rte_ring_mp_enqueue_bulk)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE const *obj_table, unsigned int n, + unsigned int *free_space) +{ + return __RTE_RING_CONCAT(__rte_ring_do_enqueue)(r, obj_table, n, + RTE_RING_QUEUE_FIXED, __IS_MP, free_space); +} + +/** + * Enqueue several objects on a ring (NOT multi-producers safe). + */ +static __rte_always_inline unsigned int +__RTE_RING_CONCAT(rte_ring_sp_enqueue_bulk)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE const *obj_table, unsigned int n, + unsigned int *free_space) +{ + return __RTE_RING_CONCAT(__rte_ring_do_enqueue)(r, obj_table, n, + RTE_RING_QUEUE_FIXED, __IS_SP, free_space); +} + +/** + * Enqueue several objects on a ring. + */ +static __rte_always_inline unsigned int +__RTE_RING_CONCAT(rte_ring_enqueue_bulk)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE const *obj_table, unsigned int n, + unsigned int *free_space) +{ + return __RTE_RING_CONCAT(__rte_ring_do_enqueue)(r, obj_table, n, + RTE_RING_QUEUE_FIXED, r->prod.single, free_space); +} + +/** + * Enqueue one object on a ring (multi-producers safe). + */ +static __rte_always_inline int +__RTE_RING_CONCAT(rte_ring_mp_enqueue)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE obj) +{ + return __RTE_RING_CONCAT(rte_ring_mp_enqueue_bulk)(r, &obj, 1, NULL) ? + 0 : -ENOBUFS; +} + +/** + * Enqueue one object on a ring (NOT multi-producers safe). + */ +static __rte_always_inline int +__RTE_RING_CONCAT(rte_ring_sp_enqueue)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE obj) +{ + return __RTE_RING_CONCAT(rte_ring_sp_enqueue_bulk)(r, &obj, 1, NULL) ? + 0 : -ENOBUFS; +} + +/** + * Enqueue one object on a ring. + */ +static __rte_always_inline int +__RTE_RING_CONCAT(rte_ring_enqueue)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj) +{ + return __RTE_RING_CONCAT(rte_ring_enqueue_bulk)(r, obj, 1, NULL) ? + 0 : -ENOBUFS; +} + +/** + * Dequeue several objects from a ring (multi-consumers safe). + */ +static __rte_always_inline unsigned int +__RTE_RING_CONCAT(rte_ring_mc_dequeue_bulk)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, unsigned int n, + unsigned int *available) +{ + return __RTE_RING_CONCAT(__rte_ring_do_dequeue)(r, obj_table, n, + RTE_RING_QUEUE_FIXED, __IS_MC, available); +} + +/** + * Dequeue several objects from a ring (NOT multi-consumers safe). + */ +static __rte_always_inline unsigned int +__RTE_RING_CONCAT(rte_ring_sc_dequeue_bulk)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, unsigned int n, + unsigned int *available) +{ + return __RTE_RING_CONCAT(__rte_ring_do_dequeue)(r, obj_table, n, + RTE_RING_QUEUE_FIXED, __IS_SC, available); +} + +/** + * Dequeue several objects from a ring. + */ +static __rte_always_inline unsigned int +__RTE_RING_CONCAT(rte_ring_dequeue_bulk)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, unsigned int n, + unsigned int *available) +{ + return __RTE_RING_CONCAT(__rte_ring_do_dequeue)(r, obj_table, n, + RTE_RING_QUEUE_FIXED, r->cons.single, available); +} + +/** + * Dequeue one object from a ring (multi-consumers safe). + */ +static __rte_always_inline int +__RTE_RING_CONCAT(rte_ring_mc_dequeue)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_p) +{ + return __RTE_RING_CONCAT(rte_ring_mc_dequeue_bulk)(r, obj_p, 1, NULL) ? + 0 : -ENOENT; +} + +/** + * Dequeue one object from a ring (NOT multi-consumers safe). + */ +static __rte_always_inline int +__RTE_RING_CONCAT(rte_ring_sc_dequeue)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_p) +{ + return __RTE_RING_CONCAT(rte_ring_sc_dequeue_bulk)(r, obj_p, 1, NULL) ? + 0 : -ENOENT; +} + +/** + * Dequeue one object from a ring. + */ +static __rte_always_inline int +__RTE_RING_CONCAT(rte_ring_dequeue)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_p) +{ + return __RTE_RING_CONCAT(rte_ring_dequeue_bulk)(r, obj_p, 1, NULL) ? + 0 : -ENOENT; +} + +/** + * Enqueue several objects on the ring (multi-producers safe). + */ +static __rte_always_inline unsigned +__RTE_RING_CONCAT(rte_ring_mp_enqueue_burst)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, + unsigned int n, unsigned int *free_space) +{ + return __RTE_RING_CONCAT(__rte_ring_do_enqueue)(r, obj_table, n, + RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space); +} + +/** + * Enqueue several objects on a ring (NOT multi-producers safe). + */ +static __rte_always_inline unsigned +__RTE_RING_CONCAT(rte_ring_sp_enqueue_burst)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, + unsigned int n, unsigned int *free_space) +{ + return __RTE_RING_CONCAT(__rte_ring_do_enqueue)(r, obj_table, n, + RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space); +} + +/** + * Enqueue several objects on a ring. + */ +static __rte_always_inline unsigned +__RTE_RING_CONCAT(rte_ring_enqueue_burst)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, unsigned int n, + unsigned int *free_space) +{ + return __RTE_RING_CONCAT(__rte_ring_do_enqueue)(r, obj_table, n, + RTE_RING_QUEUE_VARIABLE, r->prod.single, free_space); +} + +/** + * 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 + */ +static __rte_always_inline unsigned +__RTE_RING_CONCAT(rte_ring_mc_dequeue_burst)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, unsigned int n, + unsigned int *available) +{ + return __RTE_RING_CONCAT(__rte_ring_do_dequeue)(r, obj_table, n, + RTE_RING_QUEUE_VARIABLE, __IS_MC, available); +} + +/** + * 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 + */ +static __rte_always_inline unsigned +__RTE_RING_CONCAT(rte_ring_sc_dequeue_burst)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, unsigned int n, + unsigned int *available) +{ + return __RTE_RING_CONCAT(__rte_ring_do_dequeue)(r, obj_table, n, + RTE_RING_QUEUE_VARIABLE, __IS_SC, available); +} + +/** + * Dequeue multiple objects from a ring up to a maximum number. + */ +static __rte_always_inline unsigned +__RTE_RING_CONCAT(rte_ring_dequeue_burst)(struct rte_ring *r, + RTE_RING_TMPLT_ELEM_TYPE *obj_table, unsigned int n, + unsigned int *available) +{ + return __RTE_RING_CONCAT(__rte_ring_do_dequeue)(r, obj_table, n, + RTE_RING_QUEUE_VARIABLE, + r->cons.single, available); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_RING_TEMPLATE_H_ */