From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4A1C144099; Wed, 22 May 2024 18:14:44 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6B3F94064A; Wed, 22 May 2024 18:14:41 +0200 (CEST) Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) by mails.dpdk.org (Postfix) with ESMTP id 26D3E402EF for ; Wed, 22 May 2024 18:14:39 +0200 (CEST) Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-1f335e8d493so1354395ad.1 for ; Wed, 22 May 2024 09:14:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1716394478; x=1716999278; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hVCKCmUDHLN6MQuTC3Jka0cV7oRhFSKBefcQ7wfVJqM=; b=xYcpDqINMAy2dReXbD5DGcMiE8D2qN1zc/m7QQbij7hj6OlXh1Vl84cMct1msmlLKg PsQR1EKqxNuCXkmPwM+FlIUkhYgy5UGQ3Wb/ZzNbBo/Fe6XjXxPoMYKbS0jTqFDogH9G lW71uC8WGx6Qw4gTYC2u13xMiwUb1epfVayK50GXhGPJFHn9/o/hX3Ep5+S046F8NZXv AZa9OCaCOg+Uooa4OtmBWgKKwhEt3zjtSVg0nMUkPMGRI2Nb4izCPR1Wkxk1EqdVZ23D 54HYaXggHnvYwFMPKW08x4lwj+sf6FOmvgD2TakcDfJT1gfkrpW4eSO7LFPgMoxMd45g EHug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716394478; x=1716999278; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hVCKCmUDHLN6MQuTC3Jka0cV7oRhFSKBefcQ7wfVJqM=; b=mzNAB946LvlTSte+1W1iJ7AHZHbdGELa9wpUW+w3pxV6dTeRxnhyVMyBD255qi6bog AvCf/RV7B7K/J+Qc8Jpm+E0PZ25ZQZ7ETQMzgWkNm5eHDpQCm5Uk4ELS2aPYJ62RR2kf O6iCGOZaIPabRTYojX2CHFxj9AERl3q8AlEgwsvlGeGFwLxhEfZu2tDa3f94/mH8kqbt df+RPpndJMrhbclZQJAH4Sp3Y7AahQAnsWxT/weP0aDcLy8kCuEicpSuwgt4EE/fN6lD M4DwmzjO0ScpUAmwHAI1ZDILARqCV+f3ZpDgtBoDdfNTI2lhmc+Clk8WkpY+o1TemYxE 7Txw== X-Gm-Message-State: AOJu0YyQYiZOLpsoOkgeKWgpWSSrq8Dl2S52bMLHjWxXgnEzFm+T9mvJ C2nsty7tUbnyffyVAdGCtrVRTkwsdloqX+FBCHE8M8DYmo4T3uva3VodG2a1dekIPiKVz+G3IZw 71eg= X-Google-Smtp-Source: AGHT+IGYamnBLHfIWD8Xr0Q0rlYAxyCPlTDvfjXWuqUOssdlZCSE/VqU7Mayj9Ll9NaKnJDfUsTqEA== X-Received: by 2002:a17:902:f712:b0:1f3:360f:8947 with SMTP id d9443c01a7336-1f3360f89c0mr3379745ad.68.1716394478141; Wed, 22 May 2024 09:14:38 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f327ae4647sm13684175ad.224.2024.05.22.09.14.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 May 2024 09:14:37 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger , =?UTF-8?q?Morten=20Br=C3=B8rup?= , Tyler Retzlaff Subject: [PATCH v10 1/8] eal: generic 64 bit counter Date: Wed, 22 May 2024 09:12:25 -0700 Message-ID: <20240522161427.64568-2-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240522161427.64568-1-stephen@networkplumber.org> References: <20240510050507.14381-1-stephen@networkplumber.org> <20240522161427.64568-1-stephen@networkplumber.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This header implements 64 bit counters that can be reset. The counter increment in the fast path requires no locked operations. Reading and resetting the counter is handled by keeping track of a zero offset. Signed-off-by: Stephen Hemminger Acked-by: Morten Brørup --- lib/eal/include/meson.build | 1 + lib/eal/include/rte_counter.h | 141 ++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 lib/eal/include/rte_counter.h diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build index e94b056d46..c070dd0079 100644 --- a/lib/eal/include/meson.build +++ b/lib/eal/include/meson.build @@ -12,6 +12,7 @@ headers += files( 'rte_class.h', 'rte_common.h', 'rte_compat.h', + 'rte_counter.h', 'rte_debug.h', 'rte_dev.h', 'rte_devargs.h', diff --git a/lib/eal/include/rte_counter.h b/lib/eal/include/rte_counter.h new file mode 100644 index 0000000000..7a90a328fd --- /dev/null +++ b/lib/eal/include/rte_counter.h @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) Stephen Hemminger + */ + +#ifndef _RTE_COUNTER_H_ +#define _RTE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/** + * @file + * RTE Counter + * + * A counter is 64 bit value that is safe from split read/write. + * It assumes that only one CPU at a time will update the counter, + * and another CPU may want to read it. + * + * This is a weaker subset of full atomic variables. + * + * The counters are subject to the restrictions of atomic variables + * in packed structures or unaligned. + */ + +#ifndef RTE_ARCH_I686 + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * On platforms where 64 bit values are not split by compiler, the counter + * is implemented as basic 64 bit unsigned integer that only increases. + * The counter is reset by changing zero offset. + */ +typedef struct { + uint64_t current; /**< Monotonically increasing value. */ + uint64_t offset; /**< Offset of zero value. */ +} rte_counter64_t; + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Add value to counter. + * Assumes this operation is only done by one thread on the object. + * + * @param counter + * A pointer to the counter. + * @param val + * The value to add to the counter. + */ +static inline void +rte_counter64_add(rte_counter64_t *counter, uint32_t val) +{ + counter->current += val; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Reads the value of the current which is current value adjusted by the zero offset. + * This operation can be done by any thread. + * + * @param counter + * A pointer to the counter. + * @return + * The value of the counter. + */ +__rte_experimental +static inline uint64_t +rte_counter64_read(const rte_counter64_t *counter) +{ + uint64_t cur, offs; + + cur = rte_atomic_load_explicit(&counter->current, rte_memory_order_consume); + offs = rte_atomic_load_explicit(&counter->offset, rte_memory_order_relaxed); + + return cur - offs; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Reset a counter to zero by recording current value and making it the new zero offset. + * This operation can be done by any thread. + * + * @param counter + * A pointer to the counter. + */ +__rte_experimental +static inline void +rte_counter64_reset(rte_counter64_t *counter) +{ + uint64_t cur; + + cur = rte_atomic_load_explicit(&counter->current, rte_memory_order_consume); + rte_atomic_store_explicit(&counter->offset, cur, rte_memory_order_relaxed); +} + +#else + +/* On x86 32 bit need to use atomic to avoid load/store tearing */ +typedef RTE_ATOMIC(uint64_t) rte_counter64_t; + +__rte_experimental +static inline void +rte_counter64_add(rte_counter64_t *counter, uint32_t val) +{ + rte_atomic_fetch_add_explicit(counter, val, rte_memory_order_relaxed); +} + +__rte_experimental +static inline uint64_t +rte_counter64_read(const rte_counter64_t *counter) +{ + return rte_atomic_load_explicit(counter, rte_memory_order_relaxed); +} + +__rte_experimental +static inline void +rte_counter64_reset(rte_counter64_t *counter) +{ + rte_atomic_store_explicit(counter, 0, rte_memory_order_relaxed); +} + +#endif /* RTE_ARCH_64 */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_COUNTER_H_ */ -- 2.43.0