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 5F34AA0561; Sun, 19 Apr 2020 04:32:37 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3E6D81D53B; Sun, 19 Apr 2020 04:32:07 +0200 (CEST) Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-eopbgr140083.outbound.protection.outlook.com [40.107.14.83]) by dpdk.org (Postfix) with ESMTP id C959B1D536 for ; Sun, 19 Apr 2020 04:32:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5rQ71nr9yhlTOY0HhMTZA9CPLM57YTHFsIatVLQTKzc=; b=7oTGH4/GTAQ16E9Nu2x6h/4ysr4ODOBA9FmojLf0k1Ohi02hGyp98vC7pK3rJ/ljkZ+evaoaLjoha+vMsBVKQ+7R3bntndKNcdStcRsldGNUr8kcQ2LVUXHj1Nh9RnfDAxAGOL4Zn72jPQvBO9so4XPjIOVJ24Kl6nsesPQ+ASE= Received: from AM6P195CA0045.EURP195.PROD.OUTLOOK.COM (2603:10a6:209:87::22) by AM5PR0801MB1779.eurprd08.prod.outlook.com (2603:10a6:203:2f::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2921.29; Sun, 19 Apr 2020 02:32:04 +0000 Received: from VE1EUR03FT057.eop-EUR03.prod.protection.outlook.com (2603:10a6:209:87:cafe::4d) by AM6P195CA0045.outlook.office365.com (2603:10a6:209:87::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2921.25 via Frontend Transport; Sun, 19 Apr 2020 02:32:04 +0000 Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dpdk.org; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dpdk.org; dmarc=bestguesspass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by VE1EUR03FT057.mail.protection.outlook.com (10.152.19.123) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.18 via Frontend Transport; Sun, 19 Apr 2020 02:32:03 +0000 Received: ("Tessian outbound cbb03e3a1db0:v53"); Sun, 19 Apr 2020 02:32:03 +0000 X-CR-MTA-TID: 64aa7808 Received: from db483c6bb6a6.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id CF5A9066-A863-41F8-AA88-BDFECCF5F253.1; Sun, 19 Apr 2020 02:31:58 +0000 Received: from EUR02-AM5-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id db483c6bb6a6.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Sun, 19 Apr 2020 02:31:58 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BYUKt/EVZzU6BiPA21kAF+dbOPU+1a/wsSHQKzrmpLWmmOGM8JPOTJ29Y+FXEJqQUdCpy3ISDhh3ssU0ohcUveFa+UIsP+RuBaLVsd3TBrF96FZKlKKhIjojDBS9MnFjmgV3kKNq4AYZ7AVCC6Y7ZY2qakLnARwA/UJuBt4JWkwV5wRskr3/ap1Iwdb3UzBGsS4gIA7w8Li6dyaY0YFtye3wW6TuwR3sol743CTv3HwwxcJUhLL55yncP/FmGbt4KjOZfFvMP+kWl3shbYwjU8D+3CNCGCnzaWrsP5DwUz8avYr754A79bJnZsF7Gkq1HPegugEkfVmegBDEBzUEMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5rQ71nr9yhlTOY0HhMTZA9CPLM57YTHFsIatVLQTKzc=; b=dCRf6egFI0aFi48soIkMZOW88l1pxL0r/tlhHNAGDMgl4Xmo3IsU1cJ9oW1MHMQivlLOyLofHsRy+RE9cNAm9p7GZ06v/WYakvscaT9YrK0iCZIqdGvhA2EfelDITRLdEkx6+oX475BlvZ1YgVPOrx6HOydbkVPVyZpjdaBqNlhrgLrZVNYdHvJN6RVB5L9r/5RSnY1Kg5nab4MqMJYckOVAd/pldjUscTxxW+e8qzEaztQYsN73tvjztxnp88H4p3ObRKIZQebp1q8UxrWTgH2ubD1iIPCzg07dpoYhdxUTmuBHS2/ULBsWl/I1R3bf4coFzmZ2+F9hDgJCejKx2g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5rQ71nr9yhlTOY0HhMTZA9CPLM57YTHFsIatVLQTKzc=; b=7oTGH4/GTAQ16E9Nu2x6h/4ysr4ODOBA9FmojLf0k1Ohi02hGyp98vC7pK3rJ/ljkZ+evaoaLjoha+vMsBVKQ+7R3bntndKNcdStcRsldGNUr8kcQ2LVUXHj1Nh9RnfDAxAGOL4Zn72jPQvBO9so4XPjIOVJ24Kl6nsesPQ+ASE= Received: from DBBPR08MB4646.eurprd08.prod.outlook.com (2603:10a6:10:f5::16) by DBBPR08MB4297.eurprd08.prod.outlook.com (2603:10a6:10:c3::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2921.29; Sun, 19 Apr 2020 02:31:55 +0000 Received: from DBBPR08MB4646.eurprd08.prod.outlook.com ([fe80::1870:afc4:b90f:609d]) by DBBPR08MB4646.eurprd08.prod.outlook.com ([fe80::1870:afc4:b90f:609d%5]) with mapi id 15.20.2921.027; Sun, 19 Apr 2020 02:31:55 +0000 From: Honnappa Nagarahalli To: Konstantin Ananyev , "dev@dpdk.org" CC: "david.marchand@redhat.com" , "jielong.zjl@antfin.com" , nd Thread-Topic: [PATCH v5 7/9] ring: introduce peek style API Thread-Index: AQHWFZ8HmxXr54d4HEOmuyexwRZkVqh/jNQA Date: Sun, 19 Apr 2020 02:31:55 +0000 Message-ID: References: <20200417133639.14019-1-konstantin.ananyev@intel.com> <20200418163225.17635-1-konstantin.ananyev@intel.com> <20200418163225.17635-8-konstantin.ananyev@intel.com> In-Reply-To: <20200418163225.17635-8-konstantin.ananyev@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ts-tracking-id: 989c24d2-c802-4462-b67b-71ae53d23511.0 x-checkrecipientchecked: true Authentication-Results-Original: spf=none (sender IP is ) smtp.mailfrom=Honnappa.Nagarahalli@arm.com; x-originating-ip: [70.113.25.165] x-ms-publictraffictype: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 3a4558a3-fc1b-464f-8644-08d7e409d8cb x-ms-traffictypediagnostic: DBBPR08MB4297:|AM5PR0801MB1779: X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true nodisclaimer: true x-ms-oob-tlc-oobclassifiers: OLM:8273;OLM:8273; x-forefront-prvs: 0378F1E47A X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DBBPR08MB4646.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(10009020)(4636009)(136003)(39850400004)(376002)(396003)(366004)(346002)(478600001)(52536014)(54906003)(110136005)(33656002)(71200400001)(7696005)(2906002)(6506007)(4326008)(5660300002)(8936002)(316002)(76116006)(66946007)(8676002)(66446008)(64756008)(66556008)(66476007)(81156014)(30864003)(9686003)(186003)(55016002)(86362001)(26005)(579004); DIR:OUT; SFP:1101; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: mjLXSwjhYqxuZ1tVzWdc34OXKzwzYLTce1YdcUMl/V0KPPh+b2JL+1jJEHtUmqQQYK98pPICbOIaPHd/BFrA9n2/XUT79UkbqfRO2KGo9scVsId2RcTyrxOeVHEerDw7YwbbH46CquSKcdugsxtN7NK68uVmTDjuoyVGIVdSiMaw5NJtKvBdvWdf+KPE4KkNs6eiey8xOh7AjHEZODvxtDdqRrLPEdyNr01xx6JkamynwwRQEhOWktU9b/s5cYROkTsu9N/XuIBRw3Fg4P4bMNVj2QnqehE/Rroj8jWaqGv1LHQ4mCA9blHWLqIm3786rdJV4l7YgkIMJDGTFpKKpQKJsYCCQ9HwsrWvsoA66x+aOavRHDDdcP+x6C4F8QWXT2BoZlDj8NSarnMzESpDn7SVbJztGJ63RYaidr7XFaEqUCg0eqawKp5ajR8EGLIz x-ms-exchange-antispam-messagedata: h/Aw5+mtoPgGdVCT+RI9IC3EnDY35QNMwKNq0RtslHOwwCcYwQzP58AbXbVXIuuDeBUmoIrJUtq9b24jp9s+W9U7w04ARK2sYtGGhoVDAHOzvN+l9DO+vugZqmViTH/75i5NckOezwrFCNpwnhP8pQ== x-ms-exchange-transport-forked: True Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBBPR08MB4297 Original-Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Honnappa.Nagarahalli@arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: VE1EUR03FT057.eop-EUR03.prod.protection.outlook.com X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFTY:; SFS:(10009020)(4636009)(376002)(346002)(396003)(136003)(39850400004)(46966005)(55016002)(4326008)(9686003)(86362001)(2906002)(8936002)(33656002)(8676002)(81156014)(54906003)(7696005)(110136005)(36906005)(316002)(70206006)(6506007)(81166007)(5660300002)(26005)(186003)(30864003)(336012)(47076004)(356005)(478600001)(70586007)(82740400003)(52536014); DIR:OUT; SFP:1101; X-MS-Office365-Filtering-Correlation-Id-Prvs: 71e99f3c-f4e4-493e-2f00-08d7e409d406 X-Forefront-PRVS: 0378F1E47A X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: D7Y8nOqC9NCf/khl8amBC0yVWudwn6NgXWRUtjpeNwonX+RiHXy0t2s5C8E4LChdRRORKrry20JshXQVqSNmDa9wnq4QXK7sRNfIrC2mzQ11kCwzipSXTZGOWJwslxjfLhGSO8GCaBmp6lf78di6qicbGBeTVPWqrZ8L52niLDI8ICwZ3Go5k4/PZ9oT0g2Y61+dptnSB72j1z2vw8KXAgrZTPsq0yTu7AC2ubHMxLddGfwchlbzTKEUj3QXKcNtcCGmgz4maJi1MX58gC+eypBB2vvoBWtSVt1downGiuIElNSwkhHZQFFOg05PpdwXFal/I/RYu/Qw43evyfxERalenLULq4PAQdG9krHsSnbazKFMR785Zc1fHqpxZ0Cd180EbnP9Gai0C/SJNcWkJnsZjC8+E0UyHH0mlCuJrm/9R3J5AcxmwrRXE0k/6m1oho+gLglVXg3DCL8YNGKoD7uS9bLaBSmwW4Fcqv52NOc8jJtUtW1dZ6TttWiNDH1ICwJhkbxCeFrXuZC5Iw/6Sg== X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Apr 2020 02:32:03.7948 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3a4558a3-fc1b-464f-8644-08d7e409d8cb X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1779 Subject: Re: [dpdk-dev] [PATCH v5 7/9] ring: introduce peek style API 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" > Subject: [PATCH v5 7/9] ring: introduce peek style API >=20 > For rings with producer/consumer in RTE_RING_SYNC_ST, > RTE_RING_SYNC_MT_HTS mode, provide an ability to split enqueue/dequeue > operation into two phases: > - enqueue/dequeue start > - enqueue/dequeue finish > That allows user to inspect objects in the ring without removing them fro= m it > (aka MT safe peek). >=20 > Signed-off-by: Konstantin Ananyev One nit inline, otherwise, Acked-by: Honnappa Nagarahalli > --- > lib/librte_ring/Makefile | 1 + > lib/librte_ring/meson.build | 1 + > lib/librte_ring/rte_ring_c11_mem.h | 44 +++ > lib/librte_ring/rte_ring_elem.h | 4 + > lib/librte_ring/rte_ring_generic.h | 48 ++++ > lib/librte_ring/rte_ring_peek.h | 442 +++++++++++++++++++++++++++++ > 6 files changed, 540 insertions(+) > create mode 100644 lib/librte_ring/rte_ring_peek.h >=20 > diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile index > f75d8e530..52bb2a42d 100644 > --- a/lib/librte_ring/Makefile > +++ b/lib/librte_ring/Makefile > @@ -22,6 +22,7 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include :=3D > rte_ring.h \ > rte_ring_c11_mem.h \ > rte_ring_hts.h \ > rte_ring_hts_c11_mem.h \ > + rte_ring_peek.h \ > rte_ring_rts.h \ > rte_ring_rts_c11_mem.h >=20 > diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build in= dex > ca37cb8cc..0c1f2d996 100644 > --- a/lib/librte_ring/meson.build > +++ b/lib/librte_ring/meson.build > @@ -9,6 +9,7 @@ headers =3D files('rte_ring.h', > 'rte_ring_generic.h', > 'rte_ring_hts.h', > 'rte_ring_hts_c11_mem.h', > + 'rte_ring_peek.h', > 'rte_ring_rts.h', > 'rte_ring_rts_c11_mem.h') >=20 > diff --git a/lib/librte_ring/rte_ring_c11_mem.h > b/lib/librte_ring/rte_ring_c11_mem.h > index 0fb73a337..bb3096721 100644 > --- a/lib/librte_ring/rte_ring_c11_mem.h > +++ b/lib/librte_ring/rte_ring_c11_mem.h > @@ -10,6 +10,50 @@ > #ifndef _RTE_RING_C11_MEM_H_ > #define _RTE_RING_C11_MEM_H_ >=20 > +/** > + * @internal get current tail value. > + * This function should be used only for single thread producer/consumer= . > + * Check that user didn't request to move tail above the head. > + * In that situation: > + * - return zero, that will cause abort any pending changes and > + * return head to its previous position. > + * - throw an assert in debug mode. > + */ > +static __rte_always_inline uint32_t > +__rte_ring_st_get_tail(struct rte_ring_headtail *ht, uint32_t *tail, > + uint32_t num) > +{ > + uint32_t h, n, t; > + > + h =3D ht->head; > + t =3D ht->tail; > + n =3D h - t; > + > + RTE_ASSERT(n >=3D num); > + num =3D (n >=3D num) ? num : 0; > + > + *tail =3D h; > + return num; > +} > + > +/** > + * @internal set new values for head and tail. > + * This function should be used only for single thread producer/consumer= . > + * Should be used only in conjunction with __rte_ring_st_get_tail. > + */ > +static __rte_always_inline void > +__rte_ring_st_set_head_tail(struct rte_ring_headtail *ht, uint32_t tail, > + uint32_t num, uint32_t enqueue) > +{ > + uint32_t pos; > + > + RTE_SET_USED(enqueue); > + > + pos =3D tail + num; > + ht->head =3D pos; > + __atomic_store_n(&ht->tail, pos, __ATOMIC_RELEASE); } > + > static __rte_always_inline void > update_tail(struct rte_ring_headtail *ht, uint32_t old_val, uint32_t new= _val, > uint32_t single, uint32_t enqueue) > diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_e= lem.h > index df485fc6b..eeb850ab5 100644 > --- a/lib/librte_ring/rte_ring_elem.h > +++ b/lib/librte_ring/rte_ring_elem.h > @@ -1071,6 +1071,10 @@ rte_ring_dequeue_burst_elem(struct rte_ring *r, > void *obj_table, > return 0; > } >=20 > +#ifdef ALLOW_EXPERIMENTAL_API > +#include > +#endif > + > #include >=20 > #ifdef __cplusplus > diff --git a/lib/librte_ring/rte_ring_generic.h > b/lib/librte_ring/rte_ring_generic.h > index 953cdbbd5..9f5fdf13b 100644 > --- a/lib/librte_ring/rte_ring_generic.h > +++ b/lib/librte_ring/rte_ring_generic.h Changes in this file are not required as we agreed to implement only C11 fo= r new features. > @@ -10,6 +10,54 @@ > #ifndef _RTE_RING_GENERIC_H_ > #define _RTE_RING_GENERIC_H_ >=20 > +/** > + * @internal get current tail value. > + * This function should be used only for single thread producer/consumer= . > + * Check that user didn't request to move tail above the head. > + * In that situation: > + * - return zero, that will cause abort any pending changes and > + * return head to its previous position. > + * - throw an assert in debug mode. > + */ > +static __rte_always_inline uint32_t > +__rte_ring_st_get_tail(struct rte_ring_headtail *ht, uint32_t *tail, > + uint32_t num) > +{ > + uint32_t h, n, t; > + > + h =3D ht->head; > + t =3D ht->tail; > + n =3D h - t; > + > + RTE_ASSERT(n >=3D num); > + num =3D (n >=3D num) ? num : 0; > + > + *tail =3D h; > + return num; > +} > + > +/** > + * @internal set new values for head and tail. > + * This function should be used only for single thread producer/consumer= . > + * Should be used only in conjunction with __rte_ring_st_get_tail. > + */ > +static __rte_always_inline void > +__rte_ring_st_set_head_tail(struct rte_ring_headtail *ht, uint32_t tail, > + uint32_t num, uint32_t enqueue) > +{ > + uint32_t pos; > + > + pos =3D tail + num; > + > + if (enqueue) > + rte_smp_wmb(); > + else > + rte_smp_rmb(); > + > + ht->head =3D pos; > + ht->tail =3D pos; > +} > + > static __rte_always_inline void > update_tail(struct rte_ring_headtail *ht, uint32_t old_val, uint32_t new= _val, > uint32_t single, uint32_t enqueue) > diff --git a/lib/librte_ring/rte_ring_peek.h b/lib/librte_ring/rte_ring_p= eek.h > new file mode 100644 index 000000000..2d06888b6 > --- /dev/null > +++ b/lib/librte_ring/rte_ring_peek.h > @@ -0,0 +1,442 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * > + * Copyright (c) 2010-2020 Intel Corporation > + * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org > + * All rights reserved. > + * Derived from FreeBSD's bufring.h > + * Used as BSD-3 Licensed with permission from Kip Macy. > + */ > + > +#ifndef _RTE_RING_PEEK_H_ > +#define _RTE_RING_PEEK_H_ > + > +/** > + * @file > + * @b EXPERIMENTAL: this API may change without prior notice > + * It is not recommended to include this file directly. > + * Please include instead. > + * > + * Ring Peek API > + * Introduction of rte_ring with serialized producer/consumer (HTS sync > +mode) > + * makes possible to split public enqueue/dequeue API into two phases: > + * - enqueue/dequeue start > + * - enqueue/dequeue finish > + * That allows user to inspect objects in the ring without removing > +them > + * from it (aka MT safe peek). > + * Note that right now this new API is avaialble only for two sync modes= : > + * 1) Single Producer/Single Consumer (RTE_RING_SYNC_ST) > + * 2) Serialized Producer/Serialized Consumer (RTE_RING_SYNC_MT_HTS). > + * It is a user responsibility to create/init ring with appropriate > +sync > + * modes selected. > + * As an example: > + * // read 1 elem from the ring: > + * n =3D rte_ring_dequeue_bulk_start(ring, &obj, 1, NULL); > + * if (n !=3D 0) { > + * //examine object > + * if (object_examine(obj) =3D=3D KEEP) > + * //decided to keep it in the ring. > + * rte_ring_dequeue_finish(ring, 0); > + * else > + * //decided to remove it from the ring. > + * rte_ring_dequeue_finish(ring, n); > + * } > + * Note that between _start_ and _finish_ none other thread can proceed > + * with enqueue(/dequeue) operation till _finish_ completes. > + */ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** > + * @internal This function moves prod head value. > + */ > +static __rte_always_inline unsigned int > +__rte_ring_do_enqueue_start(struct rte_ring *r, uint32_t n, > + enum rte_ring_queue_behavior behavior, uint32_t > *free_space) { > + uint32_t free, head, next; > + > + switch (r->prod.sync_type) { > + case RTE_RING_SYNC_ST: > + n =3D __rte_ring_move_prod_head(r, RTE_RING_SYNC_ST, n, > + behavior, &head, &next, &free); > + break; > + case RTE_RING_SYNC_MT_HTS: > + n =3D __rte_ring_hts_move_prod_head(r, n, behavior, > + &head, &free); > + break; > + default: > + /* unsupported mode, shouldn't be here */ > + RTE_ASSERT(0); > + n =3D 0; > + } > + > + if (free_space !=3D NULL) > + *free_space =3D free - n; > + return n; > +} > + > +/** > + * Start to enqueue several objects on the ring. > + * Note that no actual objects are put in the queue by this function, > + * it just reserves for user such ability. > + * User has to call appropriate enqueue_elem_finish() to copy objects > +into the > + * queue and complete given enqueue operation. > + * > + * @param r > + * A pointer to the ring structure. > + * @param n > + * The number of objects to add in the ring from the obj_table. > + * @param free_space > + * if non-NULL, returns the amount of space in the ring after the > + * enqueue operation has finished. > + * @return > + * The number of objects that can be enqueued, either 0 or n > + */ > +__rte_experimental > +static __rte_always_inline unsigned int > +rte_ring_enqueue_bulk_elem_start(struct rte_ring *r, unsigned int n, > + unsigned int *free_space) > +{ > + return __rte_ring_do_enqueue_start(r, n, RTE_RING_QUEUE_FIXED, > + free_space); > +} > + > +/** > + * Start to enqueue several objects on the ring. > + * Note that no actual objects are put in the queue by this function, > + * it just reserves for user such ability. > + * User has to call appropriate enqueue_finish() to copy objects into > +the > + * queue and complete given enqueue operation. > + * > + * @param r > + * A pointer to the ring structure. > + * @param n > + * The number of objects to add in the ring from the obj_table. > + * @param free_space > + * if non-NULL, returns the amount of space in the ring after the > + * enqueue operation has finished. > + * @return > + * The number of objects that can be enqueued, either 0 or n > + */ > +__rte_experimental > +static __rte_always_inline unsigned int > +rte_ring_enqueue_bulk_start(struct rte_ring *r, unsigned int n, > + unsigned int *free_space) > +{ > + return rte_ring_enqueue_bulk_elem_start(r, n, free_space); } > + > +/** > + * Start to enqueue several objects on the ring. > + * Note that no actual objects are put in the queue by this function, > + * it just reserves for user such ability. > + * User has to call appropriate enqueue_elem_finish() to copy objects > +into the > + * queue and complete given enqueue operation. > + * > + * @param r > + * A pointer to the ring structure. > + * @param n > + * The number of objects to add in the ring from the obj_table. > + * @param free_space > + * if non-NULL, returns the amount of space in the ring after the > + * enqueue operation has finished. > + * @return > + * Actual number of objects that can be enqueued. > + */ > +__rte_experimental > +static __rte_always_inline unsigned int > +rte_ring_enqueue_burst_elem_start(struct rte_ring *r, unsigned int n, > + unsigned int *free_space) > +{ > + return __rte_ring_do_enqueue_start(r, n, > RTE_RING_QUEUE_VARIABLE, > + free_space); > +} > + > +/** > + * Start to enqueue several objects on the ring. > + * Note that no actual objects are put in the queue by this function, > + * it just reserves for user such ability. > + * User has to call appropriate enqueue_finish() to copy objects into > +the > + * queue and complete given enqueue operation. > + * > + * @param r > + * A pointer to the ring structure. > + * @param n > + * The number of objects to add in the ring from the obj_table. > + * @param free_space > + * if non-NULL, returns the amount of space in the ring after the > + * enqueue operation has finished. > + * @return > + * Actual number of objects that can be enqueued. > + */ > +__rte_experimental > +static __rte_always_inline unsigned int > +rte_ring_enqueue_burst_start(struct rte_ring *r, unsigned int n, > + unsigned int *free_space) > +{ > + return rte_ring_enqueue_burst_elem_start(r, n, free_space); } > + > +/** > + * Complete to enqueue several objects on the ring. > + * Note that number of objects to enqueue should not exceed previous > + * enqueue_start return value. > + * > + * @param r > + * A pointer to the ring structure. > + * @param obj_table > + * A pointer to a table of objects. > + * @param esize > + * The size of ring element, in bytes. It must be a multiple of 4. > + * This must be the same value used while creating the ring. Otherwise > + * the results are undefined. > + * @param n > + * The number of objects to add to the ring from the obj_table. > + */ > +__rte_experimental > +static __rte_always_inline void > +rte_ring_enqueue_elem_finish(struct rte_ring *r, const void *obj_table, > + unsigned int esize, unsigned int n) > +{ > + uint32_t tail; > + > + switch (r->prod.sync_type) { > + case RTE_RING_SYNC_ST: > + n =3D __rte_ring_st_get_tail(&r->prod, &tail, n); > + if (n !=3D 0) > + __rte_ring_enqueue_elems(r, tail, obj_table, esize, n); > + __rte_ring_st_set_head_tail(&r->prod, tail, n, 1); > + break; > + case RTE_RING_SYNC_MT_HTS: > + n =3D __rte_ring_hts_get_tail(&r->hts_prod, &tail, n); > + if (n !=3D 0) > + __rte_ring_enqueue_elems(r, tail, obj_table, esize, n); > + __rte_ring_hts_set_head_tail(&r->hts_prod, tail, n, 1); > + break; > + default: > + /* unsupported mode, shouldn't be here */ > + RTE_ASSERT(0); > + } > +} > + > +/** > + * Complete to enqueue several objects on the ring. > + * Note that number of objects to enqueue should not exceed previous > + * enqueue_start return value. > + * > + * @param r > + * A pointer to the ring structure. > + * @param obj_table > + * A pointer to a table of objects. > + * @param n > + * The number of objects to add to the ring from the obj_table. > + */ > +__rte_experimental > +static __rte_always_inline void > +rte_ring_enqueue_finish(struct rte_ring *r, void * const *obj_table, > + unsigned int n) > +{ > + rte_ring_enqueue_elem_finish(r, obj_table, sizeof(uintptr_t), n); } > + > +/** > + * @internal This function moves cons head value and copies up to *n* > + * objects from the ring to the user provided obj_table. > + */ > +static __rte_always_inline unsigned int > +__rte_ring_do_dequeue_start(struct rte_ring *r, void *obj_table, > + uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior, > + uint32_t *available) > +{ > + uint32_t avail, head, next; > + > + switch (r->cons.sync_type) { > + case RTE_RING_SYNC_ST: > + n =3D __rte_ring_move_cons_head(r, RTE_RING_SYNC_ST, n, > + behavior, &head, &next, &avail); > + break; > + case RTE_RING_SYNC_MT_HTS: > + n =3D __rte_ring_hts_move_cons_head(r, n, behavior, > + &head, &avail); > + break; > + default: > + /* unsupported mode, shouldn't be here */ > + RTE_ASSERT(0); > + n =3D 0; > + } > + > + if (n !=3D 0) > + __rte_ring_dequeue_elems(r, head, obj_table, esize, n); > + > + if (available !=3D NULL) > + *available =3D avail - n; > + return n; > +} > + > +/** > + * Start to dequeue several objects from the ring. > + * Note that user has to call appropriate dequeue_finish() > + * to complete given dequeue operation and actually remove objects the r= ing. > + * > + * @param r > + * A pointer to the ring structure. > + * @param obj_table > + * A pointer to a table of objects that will be filled. > + * @param esize > + * The size of ring element, in bytes. It must be a multiple of 4. > + * This must be the same value used while creating the ring. Otherwise > + * the results are undefined. > + * @param n > + * The number of objects to dequeue from the ring to the obj_table. > + * @param available > + * If non-NULL, returns the number of remaining ring entries after the > + * dequeue has finished. > + * @return > + * The number of objects dequeued, either 0 or n. > + */ > +__rte_experimental > +static __rte_always_inline unsigned int > +rte_ring_dequeue_bulk_elem_start(struct rte_ring *r, void *obj_table, > + unsigned int esize, unsigned int n, unsigned int *available) { > + return __rte_ring_do_dequeue_start(r, obj_table, esize, n, > + RTE_RING_QUEUE_FIXED, available); > +} > + > +/** > + * Start to dequeue several objects from the ring. > + * Note that user has to call appropriate dequeue_finish() > + * to complete given dequeue operation and actually remove objects the r= ing. > + * > + * @param r > + * A pointer to the ring structure. > + * @param obj_table > + * A pointer to a table of void * pointers (objects) that will be fill= ed. > + * @param n > + * The number of objects to dequeue from the ring to the obj_table. > + * @param available > + * If non-NULL, returns the number of remaining ring entries after the > + * dequeue has finished. > + * @return > + * Actual number of objects dequeued. > + */ > +__rte_experimental > +static __rte_always_inline unsigned int > +rte_ring_dequeue_bulk_start(struct rte_ring *r, void **obj_table, > + unsigned int n, unsigned int *available) { > + return rte_ring_dequeue_bulk_elem_start(r, obj_table, > sizeof(uintptr_t), > + n, available); > +} > + > +/** > + * Start to dequeue several objects from the ring. > + * Note that user has to call appropriate dequeue_finish() > + * to complete given dequeue operation and actually remove objects the r= ing. > + * > + * @param r > + * A pointer to the ring structure. > + * @param obj_table > + * A pointer to a table of objects that will be filled. > + * @param esize > + * The size of ring element, in bytes. It must be a multiple of 4. > + * This must be the same value used while creating the ring. Otherwise > + * the results are undefined. > + * @param n > + * The number of objects to dequeue from the ring to the obj_table. > + * @param available > + * If non-NULL, returns the number of remaining ring entries after the > + * dequeue has finished. > + * @return > + * The actual number of objects dequeued. > + */ > +__rte_experimental > +static __rte_always_inline unsigned int > +rte_ring_dequeue_burst_elem_start(struct rte_ring *r, void *obj_table, > + unsigned int esize, unsigned int n, unsigned int *available) { > + return __rte_ring_do_dequeue_start(r, obj_table, esize, n, > + RTE_RING_QUEUE_VARIABLE, available); } > + > +/** > + * Start to dequeue several objects from the ring. > + * Note that user has to call appropriate dequeue_finish() > + * to complete given dequeue operation and actually remove objects the r= ing. > + * > + * @param r > + * A pointer to the ring structure. > + * @param obj_table > + * A pointer to a table of void * pointers (objects) that will be fill= ed. > + * @param n > + * The number of objects to dequeue from the ring to the obj_table. > + * @param available > + * If non-NULL, returns the number of remaining ring entries after the > + * dequeue has finished. > + * @return > + * The actual number of objects dequeued. > + */ > +__rte_experimental > +static __rte_always_inline unsigned int > +rte_ring_dequeue_burst_start(struct rte_ring *r, void **obj_table, > + unsigned int n, unsigned int *available) { > + return rte_ring_dequeue_burst_elem_start(r, obj_table, > + sizeof(uintptr_t), n, available); > +} > + > +/** > + * Complete to dequeue several objects from the ring. > + * Note that number of objects to dequeue should not exceed previous > + * dequeue_start return value. > + * > + * @param r > + * A pointer to the ring structure. > + * @param n > + * The number of objects to remove from the ring. > + */ > +__rte_experimental > +static __rte_always_inline void > +rte_ring_dequeue_elem_finish(struct rte_ring *r, unsigned int n) { > + uint32_t tail; > + > + switch (r->cons.sync_type) { > + case RTE_RING_SYNC_ST: > + n =3D __rte_ring_st_get_tail(&r->cons, &tail, n); > + __rte_ring_st_set_head_tail(&r->cons, tail, n, 0); > + break; > + case RTE_RING_SYNC_MT_HTS: > + n =3D __rte_ring_hts_get_tail(&r->hts_cons, &tail, n); > + __rte_ring_hts_set_head_tail(&r->hts_cons, tail, n, 0); > + break; > + default: > + /* unsupported mode, shouldn't be here */ > + RTE_ASSERT(0); > + } > +} > + > +/** > + * Complete to dequeue several objects from the ring. > + * Note that number of objects to dequeue should not exceed previous > + * dequeue_start return value. > + * > + * @param r > + * A pointer to the ring structure. > + * @param n > + * The number of objects to remove from the ring. > + */ > +__rte_experimental > +static __rte_always_inline void > +rte_ring_dequeue_finish(struct rte_ring *r, unsigned int n) { > + rte_ring_dequeue_elem_finish(r, n); > +} > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* _RTE_RING_PEEK_H_ */ > -- > 2.17.1