From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 19121A2EDB for ; Tue, 1 Oct 2019 13:47:32 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 76F5D5681; Tue, 1 Oct 2019 13:47:31 +0200 (CEST) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id 0EDA823D for ; Tue, 1 Oct 2019 13:47:29 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Oct 2019 04:47:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,571,1559545200"; d="scan'208";a="181664773" Received: from irsmsx104.ger.corp.intel.com ([163.33.3.159]) by orsmga007.jf.intel.com with ESMTP; 01 Oct 2019 04:47:27 -0700 Received: from irsmsx105.ger.corp.intel.com ([169.254.7.164]) by IRSMSX104.ger.corp.intel.com ([169.254.5.103]) with mapi id 14.03.0439.000; Tue, 1 Oct 2019 12:47:26 +0100 From: "Ananyev, Konstantin" To: Honnappa Nagarahalli , "olivier.matz@6wind.com" , "Wang, Yipeng1" , "Gobriel, Sameh" , "Richardson, Bruce" , "De Lara Guarch, Pablo" CC: "dev@dpdk.org" , "dharmik.thakkar@arm.com" , "gavin.hu@arm.com" , "ruifeng.wang@arm.com" , "nd@arm.com" Thread-Topic: [dpdk-dev] [PATCH 2/5] lib/ring: add template to support different element sizes Thread-Index: AQHVXa90autmMQgO70SevYhypWJbKqdF3rfw Date: Tue, 1 Oct 2019 11:47:25 +0000 Message-ID: <2601191342CEEE43887BDE71AB977258019196E21E@irsmsx105.ger.corp.intel.com> References: <20190828144614.25284-1-honnappa.nagarahalli@arm.com> <20190828144614.25284-3-honnappa.nagarahalli@arm.com> In-Reply-To: <20190828144614.25284-3-honnappa.nagarahalli@arm.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiZWM5NDcyZjQtZWY5Yi00ZGY1LWE2MDEtYWJkNDlhOGUyNTNiIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiMUVSUThzNnB4YTlJZWwwMlkraE5qQVprRmRwZEJiQVhacEVXdkRPSnpvUXREK00yZDJiVE1oS3FEZVdkSHBJVSJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [163.33.239.180] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [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" >=20 >=20 > Add templates to support creating ring APIs with different > ring element sizes. >=20 > 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 >=20 > 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) :=3D rte_ring.c > # install includes > SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include :=3D 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 >=20 > 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 =3D 2 > sources =3D files('rte_ring.c') > headers =3D 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') >=20 > # rte_ring_create_elem and rte_ring_get_memsize_elem are experimental > allow_experimental_apis =3D true > diff --git a/lib/librte_ring/rte_ring_template.c b/lib/librte_ring/rte_ri= ng_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_ri= ng_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); Just an idea - probably same thing can be achieved in a different way. Instead of all these defines - replace ENQUEUE_PTRS/DEQUEUE_PTRS macros with static inline functions and then make all internal functions, i.e. __r= te_ring_do_dequeue() to accept enqueue/dequeue function pointer as a parameter. Then let say default rte_ring_mc_dequeue_bulk will do: rte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int *available) { return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED, __IS_MC, available, dequeue_ptr_default); } Then if someone will like to define ring functions forelt_size=3D=3DX, all = he would need to do: 1. define his own enqueue/dequeuer functions. 2. do something like: rte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int *available) { return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED, __IS_MC, available, dequeue_X); } Konstantin > + > +/** > + * @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 =3D __rte_ring_move_prod_head(r, is_sp, n, behavior, > + &prod_head, &prod_next, &free_entries); > + if (n =3D=3D 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 !=3D NULL) > + *free_space =3D 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 =3D __rte_ring_move_cons_head(r, (int)is_sc, n, behavior, > + &cons_head, &cons_next, &entries); > + if (n =3D=3D 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 !=3D NULL) > + *available =3D 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 t= he > + * 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_ */ > -- > 2.17.1