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 C65B9A0577; Tue, 14 Apr 2020 05:45:25 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 054671C05C; Tue, 14 Apr 2020 05:45:25 +0200 (CEST) Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60062.outbound.protection.outlook.com [40.107.6.62]) by dpdk.org (Postfix) with ESMTP id F15BD1C039 for ; Tue, 14 Apr 2020 05:45:23 +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=tK5dsnillMEWHVc0P+Z400VLhX4OFGmXlSRay80H0Sg=; b=0QRcItANZH0HyhElbPgBFBca6ZEGbkvXMzOnIcqlaN0YOvrG8WpNe+bCJsNPoTqA18OK1BuzKoTKX2s8unEYwmahtyqwUSHsPM9JTdvYlHxjp5srwtcHUyxKYMXosnI3odM/X7FM5CB6kgRspCXLNaGWEEQc5w1sEXELWMjFBuE= Received: from DB6PR0501CA0041.eurprd05.prod.outlook.com (2603:10a6:4:67::27) by DBBPR08MB4348.eurprd08.prod.outlook.com (2603:10a6:10:cc::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.26; Tue, 14 Apr 2020 03:45:22 +0000 Received: from DB5EUR03FT046.eop-EUR03.prod.protection.outlook.com (2603:10a6:4:67:cafe::a1) by DB6PR0501CA0041.outlook.office365.com (2603:10a6:4:67::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.17 via Frontend Transport; Tue, 14 Apr 2020 03:45:22 +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 DB5EUR03FT046.mail.protection.outlook.com (10.152.21.230) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.18 via Frontend Transport; Tue, 14 Apr 2020 03:45:22 +0000 Received: ("Tessian outbound af37c2b81632:v50"); Tue, 14 Apr 2020 03:45:22 +0000 X-CR-MTA-TID: 64aa7808 Received: from ce018ca2c0ab.2 by 64aa7808-outbound-1.mta.getcheckrecipient.com id ADD07542-28A6-4462-8C13-900BE281CEC3.1; Tue, 14 Apr 2020 03:45:17 +0000 Received: from EUR04-HE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id ce018ca2c0ab.2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Tue, 14 Apr 2020 03:45:17 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BYop0K4MDoN79I5DdaqE07iMGm2OQMV+UMaBNsJZIN9whbUBe+KmOo6rh/NWxLKUlsPw6OI6byqdr/lRRebjSz8QggXfyuT8xIsmQHKoWJmjflcKj9aByBAcFH6ZX3Ka/FSH5DHATjeEmGYkp1RARDalnCfp1rAsOqk3FOv+91OpvfnhupuLJDqR+gtwQB/VATqzEZf67ICNkLiMVPBw+42v6wZ4yYO245YHsD4avTS5GGSUp6+xm7Hmfo3lD4lGSsIZxRbcqOcK9fS82ILGH2JToS/I7Cz1B7gftAp/gusYTbEFluEKS1t6jXvJ+AFIBMuflb+EI4O9t24OERBq3A== 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=tK5dsnillMEWHVc0P+Z400VLhX4OFGmXlSRay80H0Sg=; b=keO6xxBVGEb1U4Q2RMAM2h0ODbpaFvnGGiW0GpGipzxBUcE22DARIHLOoB2q+6LmXaj1o/Wein/bLyDqcpHdEzqn6zYeRW2z73e2lPUjD7toszHzSM5UsE0z+Yz0Q5BNqQ+4F0sZ58XtrXRdE09x+nGCIWDyv3+aYggb/WNFtIgfWEUvH2qPb/r+s8EwN2kYT99D64X6SL1m2gnavNVWfoT2sRV+C23T6eBIIuRhN7Yx0DoEVQeTdqNfQ0gyvQzsOmmjuqL9a5Rn5PUS+SEVcitxXIh/tDZv40gcXA3xVm0zH/FddBdGPJnWO/uFdudMRdbB6WFfBSERN1nBnjCD/Q== 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=tK5dsnillMEWHVc0P+Z400VLhX4OFGmXlSRay80H0Sg=; b=0QRcItANZH0HyhElbPgBFBca6ZEGbkvXMzOnIcqlaN0YOvrG8WpNe+bCJsNPoTqA18OK1BuzKoTKX2s8unEYwmahtyqwUSHsPM9JTdvYlHxjp5srwtcHUyxKYMXosnI3odM/X7FM5CB6kgRspCXLNaGWEEQc5w1sEXELWMjFBuE= Received: from DBBPR08MB4646.eurprd08.prod.outlook.com (2603:10a6:10:f5::16) by DBBPR08MB4677.eurprd08.prod.outlook.com (2603:10a6:10:f1::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.24; Tue, 14 Apr 2020 03:45:14 +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.2900.028; Tue, 14 Apr 2020 03:45:14 +0000 From: Honnappa Nagarahalli To: Konstantin Ananyev , "dev@dpdk.org" CC: "david.marchand@redhat.com" , "jielong.zjl@antfin.com" , nd , Honnappa Nagarahalli , nd Thread-Topic: [PATCH v3 7/9] ring: introduce peek style API Thread-Index: AQHWCd9cfoGjgBmDwE6GtYzbMvcpp6h3xDiA Date: Tue, 14 Apr 2020 03:45:14 +0000 Message-ID: References: <20200402220959.29885-1-konstantin.ananyev@intel.com> <20200403174235.23308-1-konstantin.ananyev@intel.com> <20200403174235.23308-8-konstantin.ananyev@intel.com> In-Reply-To: <20200403174235.23308-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: 74a42b23-7d50-4c74-9409-c3e72a39b322.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: 36e0f147-545c-42d9-1720-08d7e02642b2 x-ms-traffictypediagnostic: DBBPR08MB4677:|DBBPR08MB4677:|DBBPR08MB4348: x-ms-exchange-transport-forked: True X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true nodisclaimer: true x-ms-oob-tlc-oobclassifiers: OLM:9508;OLM:9508; x-forefront-prvs: 0373D94D15 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)(396003)(39860400002)(376002)(346002)(366004)(55016002)(26005)(8676002)(2906002)(33656002)(9686003)(81156014)(8936002)(4326008)(76116006)(110136005)(316002)(54906003)(66946007)(66446008)(64756008)(66476007)(6506007)(478600001)(186003)(71200400001)(7696005)(30864003)(66556008)(86362001)(5660300002)(52536014); 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: Zk8liykgatn9Xm9nvcIa0z/ZPouBPalSOMSCH88/BOuXnPmWrqRxpElWYRou25XGR77gv7GygBLJrF9gcHxDy/FLmrbOwrAaJKOWKcVGNcikqVcmYO6ZmwE3rJMYkJdFo+xuhQHNiIlCXI4BoPtvUQsWXJXyV97/sxgKt1u0aGon2HkdYzS9JMy6cy5Ea0u4i6qIYC17asT7hu9MLKPkWghgnKv9ASWDSnX0L4LCS1Tijsa9jcCtQANA7ehJAEDWtRzqI5I23QxWqt+hbprxnEpMrYZFHoFq0LgDQSWoA26l2yIn02FVh8YpVyeIxV5DRHTE2iUNOCCy2Z2ULM9D+V6TAiGzwWRqUakPPUUsSPms/Vj2QKyjQeKFg65FkR05XtW26cI2ZRqGl0NM5dRrqELHadL//iook4EjY6QVPC3sFRwcstlaftwGQ6uoejdC x-ms-exchange-antispam-messagedata: 0Cgpr1Lr8eZXjtmxVBQ07EMLlcs8+p5sY4BJNts77Y6EgwO/1KW/7JmfOu7gybeOgKfwlKBHicUjQYPhyJcxY6HfU9N1jF4OtEpmNGoukriC0v0W0xTwvqqxUU619DEdoIhySQit4ibWidA5llIc7g== Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBBPR08MB4677 Original-Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Honnappa.Nagarahalli@arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: DB5EUR03FT046.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)(396003)(136003)(39860400002)(376002)(346002)(46966005)(316002)(70206006)(30864003)(9686003)(55016002)(336012)(70586007)(5660300002)(81166007)(86362001)(356005)(47076004)(8936002)(33656002)(81156014)(26826003)(186003)(2906002)(4326008)(52536014)(54906003)(6506007)(8676002)(82740400003)(7696005)(26005)(110136005)(478600001); DIR:OUT; SFP:1101; X-MS-Office365-Filtering-Correlation-Id-Prvs: c9baa1a1-f6a0-4f23-86a2-08d7e0263dc1 X-Forefront-PRVS: 0373D94D15 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: TIceXtd9MKhJt4+ZkfQOFfeA2S5PjzMqGMBi85bt4M6SK6yQvc5d1SZQu4WV/jIcDQHdeMvxD4fbIZzAQ/QU7lQStI5yp+qGaTv6lkKuewTsdUFKvO2t9Z3kRa9rDdzKlbdRyoZ+gLPopSUm4f4hfjaYstyMV36L1VR2gfbNjdX/QLgLVnDNam85YVqnNXkUPwm531sJdyXtlhldm6yKGnuQk8Kr1iES87uD2RglLkUpS/dI4OhB89tbJBcE2Um9drw7vWFPVl4Hd+qOWRTilKByQGKGMdF0hyUjcbJzdvE5BIl4SqYiq0ELvkSSRorJy5xInpshVhgCybXxAdCbIoMOVk7Ztjm9UHI7FZBEKL53gcDfe5SnAtmsr3qOXMqfX1WXUPgHXll4Aw5C8gWswHxHysHCzEO9okPbdqUGFabxNMJMg5ZYDa1UG7nQuPKENc4P9IeRo5xVBCzm+0w0P2q1drDjsuqVfyNduVEq4dF8NbbY9m1YX5EZvKZQvqR+V5lvnv4unB8GATgJrUmGMQ== X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Apr 2020 03:45:22.8481 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 36e0f147-545c-42d9-1720-08d7e02642b2 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: DBBPR08MB4348 Subject: Re: [dpdk-dev] [PATCH v3 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" >=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 > --- > 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_hts_generic.h | 47 ++- > lib/librte_ring/rte_ring_peek.h | 379 +++++++++++++++++++++++++ > 7 files changed, 519 insertions(+), 5 deletions(-) create mode 100644 > lib/librte_ring/rte_ring_peek.h >=20 > diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile index > 6fe500f0d..5f8662737 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_hts.h \ > rte_ring_hts_elem.h \ > rte_ring_hts_generic.h \ > + rte_ring_peek.h \ > rte_ring_rts.h \ > rte_ring_rts_elem.h \ > rte_ring_rts_generic.h > diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build in= dex > 8e86e037a..f5f84dc6e 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_hts.h', > 'rte_ring_hts_elem.h', > 'rte_ring_hts_generic.h', > + 'rte_ring_peek.h', > 'rte_ring_rts.h', > 'rte_ring_rts_elem.h', > 'rte_ring_rts_generic.h') > 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. Do we need this check? This could be a data path function, we could documen= t a warning and leave it to the users to provide the correct value. > + * 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 010a564c1..5bf7c1c1b 100644 > --- a/lib/librte_ring/rte_ring_elem.h > +++ b/lib/librte_ring/rte_ring_elem.h > @@ -1083,6 +1083,10 @@ rte_ring_dequeue_burst_elem(struct rte_ring *r, > void *obj_table, > return 0; > } >=20 > +#ifdef ALLOW_EXPERIMENTAL_API > +#include > +#endif > + > #ifdef __cplusplus > } > #endif > 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 > @@ -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_hts_generic.h > b/lib/librte_ring/rte_ring_hts_generic.h > index da08f1d94..8e699c006 100644 > --- a/lib/librte_ring/rte_ring_hts_generic.h > +++ b/lib/librte_ring/rte_ring_hts_generic.h > @@ -18,9 +18,38 @@ > * For more information please refer to . > */ >=20 > +/** > + * @internal get current tail value. > + * 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_hts_get_tail(struct rte_ring_hts_headtail *ht, uint32_t *tail= , > + uint32_t num) > +{ > + uint32_t n; > + union rte_ring_ht_pos p; > + > + p.raw =3D rte_atomic64_read((rte_atomic64_t *)(uintptr_t)&ht- > >ht.raw); > + n =3D p.pos.head - p.pos.tail; > + > + RTE_ASSERT(n >=3D num); > + num =3D (n >=3D num) ? num : 0; > + > + *tail =3D p.pos.tail; > + return num; > +} > + > +/** > + * @internal set new values for head and tail as one atomic 64 bit opera= tion. > + * Should be used only in conjunction with __rte_ring_hts_get_tail. > + */ > static __rte_always_inline void > -__rte_ring_hts_update_tail(struct rte_ring_hts_headtail *ht, uint32_t nu= m, > - uint32_t enqueue) > +__rte_ring_hts_set_head_tail(struct rte_ring_hts_headtail *ht, uint32_t = tail, > + uint32_t num, uint32_t enqueue) > { > union rte_ring_ht_pos p; >=20 > @@ -29,14 +58,22 @@ __rte_ring_hts_update_tail(struct > rte_ring_hts_headtail *ht, uint32_t num, > else > rte_smp_rmb(); >=20 > - p.raw =3D rte_atomic64_read((rte_atomic64_t *)(uintptr_t)&ht- > >ht.raw); > - > - p.pos.head =3D p.pos.tail + num; > + p.pos.head =3D tail + num; > p.pos.tail =3D p.pos.head; >=20 > rte_atomic64_set((rte_atomic64_t *)(uintptr_t)&ht->ht.raw, p.raw); } >=20 > +static __rte_always_inline void > +__rte_ring_hts_update_tail(struct rte_ring_hts_headtail *ht, uint32_t nu= m, > + uint32_t enqueue) > +{ > + uint32_t tail; > + > + num =3D __rte_ring_hts_get_tail(ht, &tail, num); > + __rte_ring_hts_set_head_tail(ht, tail, num, enqueue); } > + > /** > * @internal waits till tail will become equal to head. > * Means no writer/reader is active for that ring. > 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..baefd2f7b > --- /dev/null > +++ b/lib/librte_ring/rte_ring_peek.h > @@ -0,0 +1,379 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * > + * Copyright (c) 2010-2017 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 AP ^^^ 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_hts_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_hts_dequeue_finish(ring, 0); > + * else > + * //decided to remove it from the ring. > + * rte_ring_hts_dequeue_finish(ring, n); > + * } > + * Note that between _start_ and _finish_ the ring is sort of locked - = ^^^^^^^^^^^^^^^^^^^^ - 'locked' can mean different to different peop= le, may be remove this, the next sentence anyway has the description > + * none other thread can proceed with enqueue(/dequeue) operation till ^^^^ no > + * _finish_ will complete. ^^^^^^^^^^^ completes > + */ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > + > +/** > + * 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) If one wants to use _elem_ APIs for ring peek, a combination of legacy API = (format) and a _elem_ API is required. For ex: rte_ring_enqueue_bulk_start rte_ring_enqueue_elem_finish I understand why you have done this. I think this is getting somewhat too i= nconsistent. > +{ > + return __rte_ring_do_enqueue_start(r, n, RTE_RING_QUEUE_FIXED, > + free_space); > +} > + > + > +/** > + * 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 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 > + * 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) { Should this in a separate file? (similar to rte_ring.h and rte_ring_elem.h) > + 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 void * pointers (objects) that will be fill= ed. Minor, update this to indicate generic objects. Can be copied from rte_ring= _elem.h. > + * @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); } > + > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* _RTE_RING_PEEK_H_ */ > -- > 2.17.1