From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by dpdk.space (Postfix) with ESMTP id CB86CA0096 for ; Fri, 15 Mar 2019 13:56:05 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0B35B2C28; Fri, 15 Mar 2019 13:56:05 +0100 (CET) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 032B92C24 for ; Fri, 15 Mar 2019 13:56:03 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Mar 2019 05:56:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,482,1544515200"; d="scan'208";a="152630632" Received: from irsmsx154.ger.corp.intel.com ([163.33.192.96]) by fmsmga004.fm.intel.com with ESMTP; 15 Mar 2019 05:56:01 -0700 Received: from irsmsx156.ger.corp.intel.com (10.108.20.68) by IRSMSX154.ger.corp.intel.com (163.33.192.96) with Microsoft SMTP Server (TLS) id 14.3.408.0; Fri, 15 Mar 2019 12:56:00 +0000 Received: from irsmsx105.ger.corp.intel.com ([169.254.7.210]) by IRSMSX156.ger.corp.intel.com ([169.254.3.101]) with mapi id 14.03.0415.000; Fri, 15 Mar 2019 12:56:00 +0000 From: "Ananyev, Konstantin" To: Joyce Kong , "dev@dpdk.org" CC: "nd@arm.com" , "stephen@networkplumber.org" , "jerin.jacob@caviumnetworks.com" , "thomas@monjalon.net" , "honnappa.nagarahalli@arm.com" , "gavin.hu@arm.com" Thread-Topic: [dpdk-dev] [PATCH v6 1/2] eal/ticketlock: ticket based to improve fairness Thread-Index: AQHU2vxlKpABH57hOkqA57tQE05+36YMpFOA Date: Fri, 15 Mar 2019 12:55:59 +0000 Message-ID: <2601191342CEEE43887BDE71AB977258013655BF89@irsmsx105.ger.corp.intel.com> References: <1547802943-18711-1-git-send-email-joyce.kong@arm.com> <1552632988-80787-2-git-send-email-joyce.kong@arm.com> In-Reply-To: <1552632988-80787-2-git-send-email-joyce.kong@arm.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiZjU4YjM5MDktMDVjYy00YjZiLTgwYzUtZGFkYmQwODdhMGNjIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiVXN1OThQQUNSbjV0RXRYR1lqUXdMM2h5QnpFd3gyRThSeVBlUDVRaG51OENKRUVXeWlnV1llblwvTTlXbVhIcU0ifQ== x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.400.15 dlp-reaction: no-action x-originating-ip: [163.33.239.182] Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v6 1/2] eal/ticketlock: ticket based to improve fairness 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" Message-ID: <20190315125559.f6WzrZMXM_lCmcrYHRscstVXKNNNqZUx0py7rbzBQF8@z> Hi, > diff --git a/lib/librte_eal/common/include/generic/rte_ticketlock.h b/lib= /librte_eal/common/include/generic/rte_ticketlock.h > new file mode 100644 > index 0000000..d63aaaa > --- /dev/null > +++ b/lib/librte_eal/common/include/generic/rte_ticketlock.h > @@ -0,0 +1,308 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2019 Arm Limited > + */ > + > +#ifndef _RTE_TICKETLOCK_H_ > +#define _RTE_TICKETLOCK_H_ > + > +/** > + * @file > + * > + * RTE ticket locks > + * > + * This file defines an API for ticket locks, which give each waiting > + * thread a ticket and take the lock one by one, first come, first > + * serviced. > + * > + * All locks must be initialised before use, and only initialised once. > + * > + */ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include > +#include > +#include > + > +/** > + * The rte_ticketlock_t type. > + */ > +typedef struct { > + uint16_t current; > + uint16_t next; > +} rte_ticketlock_t; > + > +/** > + * A static ticketlock initializer. > + */ > +#define RTE_TICKETLOCK_INITIALIZER { 0 } > + > +/** > + * Initialize the ticketlock to an unlocked state. > + * > + * @param tl > + * A pointer to the ticketlock. > + */ > +static inline __rte_experimental void > +rte_ticketlock_init(rte_ticketlock_t *tl) > +{ > + __atomic_store_n(&tl->current, 0, __ATOMIC_RELAXED); > + __atomic_store_n(&tl->next, 0, __ATOMIC_RELAXED); > +} > + > +/** > + * Take the ticketlock. > + * > + * @param tl > + * A pointer to the ticketlock. > + */ > +static inline __rte_experimental void > +rte_ticketlock_lock(rte_ticketlock_t *tl) > +{ > + uint16_t me =3D __atomic_fetch_add(&tl->next, 1, __ATOMIC_RELAXED); > + while (__atomic_load_n(&tl->current, __ATOMIC_ACQUIRE) !=3D me) > + rte_pause(); > +} > + > +/** > + * Release the ticketlock. > + * > + * @param tl > + * A pointer to the ticketlock. > + */ > +static inline __rte_experimental void > +rte_ticketlock_unlock(rte_ticketlock_t *tl) > +{ > + uint16_t i =3D __atomic_load_n(&tl->current, __ATOMIC_RELAXED); > + __atomic_store_n(&tl->current, i+1, __ATOMIC_RELEASE); > +} > + > +/** > + * Try to take the lock. > + * > + * @param tl > + * A pointer to the ticketlock. > + * @return > + * 1 if the lock is successfully taken; 0 otherwise. > + */ > +static inline __rte_experimental int > +rte_ticketlock_trylock(rte_ticketlock_t *tl) > +{ > + uint16_t next =3D __atomic_load_n(&tl->next, __ATOMIC_RELAXED); > + uint16_t cur =3D __atomic_load_n(&tl->current, __ATOMIC_RELAXED); > + if (next =3D=3D cur) { Probably a na=EFve one: Suppose next=3D=3Dcur=3D=3D1 here, then this thread will experience really = long context switch, so next time it continues its execution tl->next value will wrap-up and wil= l be 1 again, and tl->current=3D=3D0 (lock held). I suppose this function will set tl->next=3D2 and will return a success? Wouldn't be better here and in _is_locked_ to do load/store for next/curren= t values in one go (using 32bit op)?=20 Konstantin > + if (__atomic_compare_exchange_n(&tl->next, &next, next+1, > + 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) > + return 1; > + } > + > + return 0; > +} > + > +/** > + * Test if the lock is taken. > + * > + * @param tl > + * A pointer to the ticketlock. > + * @return > + * 1 if the lock icurrently taken; 0 otherwise. > + */ > +static inline __rte_experimental int > +rte_ticketlock_is_locked(rte_ticketlock_t *tl) > +{ > + return (__atomic_load_n(&tl->current, __ATOMIC_ACQUIRE) !=3D > + __atomic_load_n(&tl->next, __ATOMIC_ACQUIRE)); > +} > +