From patchwork Tue Apr 30 09:55:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Mattias_R=C3=B6nnblom?= X-Patchwork-Id: 139727 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id A4D4543F3A; Tue, 30 Apr 2024 12:06:02 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 23BCB402C0; Tue, 30 Apr 2024 12:05:57 +0200 (CEST) Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2045.outbound.protection.outlook.com [40.107.20.45]) by mails.dpdk.org (Postfix) with ESMTP id 92F6240262 for ; Tue, 30 Apr 2024 12:05:54 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PqgEB8LjW0yxSLfGbEUdvVk5O+X47PWk3ia88gBav+Wn4NG8eW7XdB8y4jeLZpMhDrpXQ4A9TRblCtfJ2Q7zX3o/aNtwc6KrhADqPaiXlsoBWb7xnxv/uEPk6TrPqZnKjc5RR1wGHWl7SZ+p3tyN1jq2e50/xljAUCt/507yB/npKugbg4cXennUtrat+78y3LkdE55Yjbpk7fCij4UbWNhPmf0oSxRt97UVjYRM146cipTb7KRPCQnpsefTwbrhDsz+dUcHowHKOs6bgFBuGb3HeziYxunOlEK4vGJZQ5mly90pN1I4I/qOg1xWDjm6Ww5lJWl+zqob8FXWi2xcJw== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=f5HAbuFsAhlunqLGlzVjT0YEbYgMjTahD6lsx+VsdgU=; b=GIJpdElGdN6ic7nPIJ7qbtQM8TBPu/kjCGzWihVv/MApKRCp1Ialq2khvRZq4LAxnoSLZYncygEmONg1fouB2r/PZEOyxAlAGaH7SJG7KSdogKCvGs8jJtsPSy7N/5h0CArRPUFwrmgMEP34IRu/PucP01dMr3g0JVlakizyf+PSeVKwWZwWrR/NiBxPXP/fgVVna+YJuekjCmtxpEcwNzbZgtDdRLDx9lAwxGyaV70jfBXaC6bzJ9yuBVR1icO5gSoIAGy40cLFC3PU2o5epjCjZXnpYRMKWtpoo6SnXQH8ZSyG6Q43ryKnPpdp2A9lksFXSOo9DCcGzExW63XVFw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 192.176.1.74) smtp.rcpttodomain=dpdk.org smtp.mailfrom=ericsson.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=ericsson.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ericsson.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=f5HAbuFsAhlunqLGlzVjT0YEbYgMjTahD6lsx+VsdgU=; b=d5FOXNE4wAPEwC5Bk4nnyNcOnu7X0oD6Vi5E/lNdd1XfqZAt9Q60Cr4ZWOIiFcbByUw/ocDz8rmpgBkEtJ9x36Qc97O07+xZ1SKa5Umkc1NaXnIHcOwkCWDj6Xxq9j5+rLHOENLr0difdibG2Vab7NU4rcVs4Nn8fdHw8Qe5ews5HxrUiIHDXcvJFz8GnsA3LLfGRr/hT6KTR/5SrUH4Z+c+l+rIwzTJA6d9Iz7YetR5wbLbBniMjJ7IFN7hnP76MD+k6xLzzEh3aESQ0XIWxqvOoRJGDsSvRGaitGsLh/xwNr8i7FlIW/OCIGM8y4JG0lYYekJBsYzySuKiWmpvBg== Received: from DUZPR01CA0073.eurprd01.prod.exchangelabs.com (2603:10a6:10:3c2::11) by DBAPR07MB6981.eurprd07.prod.outlook.com (2603:10a6:10:17e::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.36; Tue, 30 Apr 2024 10:05:53 +0000 Received: from DB1PEPF000509F8.eurprd02.prod.outlook.com (2603:10a6:10:3c2:cafe::1e) by DUZPR01CA0073.outlook.office365.com (2603:10a6:10:3c2::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.31 via Frontend Transport; Tue, 30 Apr 2024 10:05:53 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 192.176.1.74) smtp.mailfrom=ericsson.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=ericsson.com; Received-SPF: Pass (protection.outlook.com: domain of ericsson.com designates 192.176.1.74 as permitted sender) receiver=protection.outlook.com; client-ip=192.176.1.74; helo=oa.msg.ericsson.com; pr=C Received: from oa.msg.ericsson.com (192.176.1.74) by DB1PEPF000509F8.mail.protection.outlook.com (10.167.242.154) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7544.18 via Frontend Transport; Tue, 30 Apr 2024 10:05:52 +0000 Received: from seliicinfr00050.seli.gic.ericsson.se (153.88.142.248) by smtp-central.internal.ericsson.com (100.87.178.63) with Microsoft SMTP Server id 15.2.1544.9; Tue, 30 Apr 2024 12:05:52 +0200 Received: from breslau.. (seliicwb00002.seli.gic.ericsson.se [10.156.25.100]) by seliicinfr00050.seli.gic.ericsson.se (Postfix) with ESMTP id 06B1A1C006A; Tue, 30 Apr 2024 12:05:52 +0200 (CEST) From: =?utf-8?q?Mattias_R=C3=B6nnblom?= To: CC: , Heng Wang , "Stephen Hemminger" , Tyler Retzlaff , =?utf-8?q?Morten_Br=C3=B8rup?= , =?utf-8?q?Mattia?= =?utf-8?q?s_R=C3=B6nnblom?= Subject: [RFC v4 1/6] eal: extend bit manipulation functionality Date: Tue, 30 Apr 2024 11:55:18 +0200 Message-ID: <20240430095523.108688-2-mattias.ronnblom@ericsson.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240430095523.108688-1-mattias.ronnblom@ericsson.com> References: <20240429095138.106849-2-mattias.ronnblom@ericsson.com> <20240430095523.108688-1-mattias.ronnblom@ericsson.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DB1PEPF000509F8:EE_|DBAPR07MB6981:EE_ X-MS-Office365-Filtering-Correlation-Id: 6e435264-047e-47d7-54b2-08dc68fd1e99 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230031|1800799015|376005|82310400014|36860700004; X-Microsoft-Antispam-Message-Info: =?utf-8?q?kG7i8YvTrdBVI0iP3iStRuTUyPlQIBD?= =?utf-8?q?/QZsd3DsZD0VHC1UQeYgAQU/yUUrIo39QmLGgyachfPNgyh624MceKG5SOOmYADmo?= =?utf-8?q?VMkBkfBbGyx5lYrViLDiCRCKY+IkaLl2je/FyV2q2wG4Xlgn9183Wv0BnpXI1vV3g?= =?utf-8?q?zSgOrv6nKX/SFNeNh0Ce6iUOgbWBqecMXDGFjH4RfnOJC0XXM58WecpCk80i2yTHS?= =?utf-8?q?Mq4pwOvRHx8QuRpuDdpTQQpAwUg8/hDe2KT8BVo/W5hc9j/3WVdtqv43hNIH/BDzM?= =?utf-8?q?hb4LbOPtjed1m/A/yUROS537bOEhN/SOdEvxbQf4KbVuKfrxv1PKB4NkzZy4oPS5l?= =?utf-8?q?gCWqaPPogolxIViqwWzpD/uzBZIy5KhPQmnO15ory0tE3pX2Wq8tCh2ACv904hgj0?= =?utf-8?q?kH5x6dDWy6mBtq+uYZZUPN9I1ZRM2SOXcgUAjO9Urtl4OCufEy2yi3VUIwkedyJaU?= =?utf-8?q?iY7XCz8Z9NQzKx9dC+iRVRJonokFmvCQVJke+78oy2w0ZrxwNTHooMSUBW0OtdP/i?= =?utf-8?q?k17llb3OV68peEBifi+p1w+guQ4UZXkPE5KT2MJKooC7s5ZMPKSJvz/0961U0x9gi?= =?utf-8?q?l5qWtVWuuDxbtaK78r1UwW4VASZIdC5E/KOEaLfbLBuKpIe9dTtDfDbwf+8O2av/n?= =?utf-8?q?Nwxs5y361jUgiuhEkciDgN7ppmZmhe9NIvqnPW16v6sVU6CN8g+jqnd0Gm33H78Vc?= =?utf-8?q?KZumwc4MYaE2LTNlz8W9L/chC7trX8NR4HOQgGPnfBPJACCy9J9ZAt5vtGwGu1ZBN?= =?utf-8?q?lkg7ya17vP0JNgkdOlCFlLB6fGxliKCa7wfNUgdb9vGZ/7AKrQl9Xgz/qu7CCB/sS?= =?utf-8?q?F4fD2k19B18+VSXcioV76x60mIKhED52T+2Yz9MeDW8yi/ksI7Gg927PfbTu8DpgQ?= =?utf-8?q?FKVtCeimZYMG38Kys+dvRVX2i2MKVn/+0wFrvbcXCQhoTfoF9KFA9880w9Y3xGy1z?= =?utf-8?q?Dt9gC6fG8rWvRzUqaRbDno24hp0kU9oexl/DZkKhUdev4NZKC7t7tt//LWwKEHCsY?= =?utf-8?q?2Zb668SCTqNg5RRTokwjBk7mrJcV4qH5ONeJwjbMjIiPOas1PQXeDctzsHWbVg4ts?= =?utf-8?q?u7sZuM7YfYRm3dkcqcF86/R0pKPOnT30xBstDGnaDcTviW/zikjxsqwK2kCDBvnUt?= =?utf-8?q?CQUvA66Lrg2SoUeSNTB2DlHUHENGtbo6WpbwYVQ2AHfYuwg/0qdBjpg82psYBAkkY?= =?utf-8?q?MUnOeqIrX+Q4Jp2Ei69VBrptLIiDnI68gejw+NR/c0z/yqQVENd787ummUN/xi+j+?= =?utf-8?q?YDEptPqe29fH2v0Opg6jL7ibT3BmZ4oYv+W95WMaHwexBA5q7W/D6QQ7rVCffqdlE?= =?utf-8?q?nU9XV6cg+EjS?= X-Forefront-Antispam-Report: CIP:192.176.1.74; CTRY:SE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:oa.msg.ericsson.com; PTR:office365.se.ericsson.net; CAT:NONE; SFS:(13230031)(1800799015)(376005)(82310400014)(36860700004); DIR:OUT; SFP:1101; X-OriginatorOrg: ericsson.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Apr 2024 10:05:52.8366 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6e435264-047e-47d7-54b2-08dc68fd1e99 X-MS-Exchange-CrossTenant-Id: 92e84ceb-fbfd-47ab-be52-080c6b87953f X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=92e84ceb-fbfd-47ab-be52-080c6b87953f; Ip=[192.176.1.74]; Helo=[oa.msg.ericsson.com] X-MS-Exchange-CrossTenant-AuthSource: DB1PEPF000509F8.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAPR07MB6981 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 Add functionality to test, set, clear, and assign the value to individual bits in 32-bit or 64-bit words. These functions have no implications on memory ordering, atomicity and does not use volatile and thus does not prevent any compiler optimizations. RFC v4: * Add rte_bit_flip() which, believe it or not, flips the value of a bit. * Mark macro-generated private functions as experimental. * Use macros to generate *assign*() functions. RFC v3: * Work around lack of C++ support for _Generic (Tyler Retzlaff). * Fix ','-related checkpatch warnings. Signed-off-by: Mattias Rönnblom Acked-by: Morten Brørup Acked-by: Tyler Retzlaff --- lib/eal/include/rte_bitops.h | 257 ++++++++++++++++++++++++++++++++++- 1 file changed, 255 insertions(+), 2 deletions(-) diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index 449565eeae..9d426f1602 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -2,6 +2,7 @@ * Copyright(c) 2020 Arm Limited * Copyright(c) 2010-2019 Intel Corporation * Copyright(c) 2023 Microsoft Corporation + * Copyright(c) 2024 Ericsson AB */ #ifndef _RTE_BITOPS_H_ @@ -11,12 +12,14 @@ * @file * Bit Operations * - * This file defines a family of APIs for bit operations - * without enforcing memory ordering. + * This file provides functionality for low-level, single-word + * arithmetic and bit-level operations, such as counting or + * setting individual bits. */ #include +#include #include #ifdef __cplusplus @@ -105,6 +108,194 @@ extern "C" { #define RTE_FIELD_GET64(mask, reg) \ ((typeof(mask))(((reg) & (mask)) >> rte_ctz64(mask))) +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Test bit in word. + * + * Generic selection macro to test the value of a bit in a 32-bit or + * 64-bit word. The type of operation depends on the type of the @c + * addr parameter. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ +#define rte_bit_test(addr, nr) \ + _Generic((addr), \ + uint32_t *: __rte_bit_test32, \ + uint64_t *: __rte_bit_test64)(addr, nr) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Set bit in word. + * + * Generic selection macro to set a bit in a 32-bit or 64-bit + * word. The type of operation depends on the type of the @c addr + * parameter. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ +#define rte_bit_set(addr, nr) \ + _Generic((addr), \ + uint32_t *: __rte_bit_set32, \ + uint64_t *: __rte_bit_set64)(addr, nr) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Clear bit in word. + * + * Generic selection macro to clear a bit in a 32-bit or 64-bit + * word. The type of operation depends on the type of the @c addr + * parameter. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ +#define rte_bit_clear(addr, nr) \ + _Generic((addr), \ + uint32_t *: __rte_bit_clear32, \ + uint64_t *: __rte_bit_clear64)(addr, nr) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Assign a value to a bit in word. + * + * Generic selection macro to assign a value to a bit in a 32-bit or 64-bit + * word. The type of operation depends on the type of the @c addr parameter. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param value + * The new value of the bit - true for '1', or false for '0'. + */ +#define rte_bit_assign(addr, nr, value) \ + _Generic((addr), \ + uint32_t *: __rte_bit_assign32, \ + uint64_t *: __rte_bit_assign64)(addr, nr, value) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Flip a bit in word. + * + * Generic selection macro to change the value of a bit to '0' if '1' + * or '1' if '0' in a 32-bit or 64-bit word. The type of operation + * depends on the type of the @c addr parameter. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ +#define rte_bit_flip(addr, nr) \ + _Generic((addr), \ + uint32_t *: __rte_bit_flip32, \ + uint64_t *: __rte_bit_flip64)(addr, nr) + +#define __RTE_GEN_BIT_TEST(family, fun, qualifier, size) \ + __rte_experimental \ + static inline bool \ + __rte_bit_ ## family ## fun ## size(const qualifier uint ## size ## _t *addr, \ + unsigned int nr) \ + { \ + RTE_ASSERT(nr < size); \ + \ + uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \ + return *addr & mask; \ + } + +#define __RTE_GEN_BIT_SET(family, fun, qualifier, size) \ + __rte_experimental \ + static inline void \ + __rte_bit_ ## family ## fun ## size(qualifier uint ## size ## _t *addr, \ + unsigned int nr) \ + { \ + RTE_ASSERT(nr < size); \ + \ + uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \ + *addr |= mask; \ + } \ + +#define __RTE_GEN_BIT_CLEAR(family, fun, qualifier, size) \ + __rte_experimental \ + static inline void \ + __rte_bit_ ## family ## fun ## size(qualifier uint ## size ## _t *addr, \ + unsigned int nr) \ + { \ + RTE_ASSERT(nr < size); \ + \ + uint ## size ## _t mask = ~((uint ## size ## _t)1 << nr); \ + (*addr) &= mask; \ + } \ + +#define __RTE_GEN_BIT_ASSIGN(family, fun, qualifier, size) \ + __rte_experimental \ + static inline void \ + __rte_bit_ ## family ## fun ## size(qualifier uint ## size ## _t *addr, \ + unsigned int nr, bool value) \ + { \ + if (value) \ + __rte_bit_ ## family ## set ## size(addr, nr); \ + else \ + __rte_bit_ ## family ## clear ## size(addr, nr); \ + } + +#define __RTE_GEN_BIT_FLIP(family, fun, qualifier, size) \ + __rte_experimental \ + static inline void \ + __rte_bit_ ## family ## fun ## size(qualifier uint ## size ## _t *addr, \ + unsigned int nr) \ + { \ + bool value; \ + \ + value = __rte_bit_ ## family ## test ## size(addr, nr); \ + __rte_bit_ ## family ## assign ## size(addr, nr, !value); \ + } + +__RTE_GEN_BIT_TEST(, test,, 32) +__RTE_GEN_BIT_SET(, set,, 32) +__RTE_GEN_BIT_CLEAR(, clear,, 32) +__RTE_GEN_BIT_ASSIGN(, assign,, 32) +__RTE_GEN_BIT_FLIP(, flip,, 32) + +__RTE_GEN_BIT_TEST(, test,, 64) +__RTE_GEN_BIT_SET(, set,, 64) +__RTE_GEN_BIT_CLEAR(, clear,, 64) +__RTE_GEN_BIT_ASSIGN(, assign,, 64) +__RTE_GEN_BIT_FLIP(, flip,, 64) + /*------------------------ 32-bit relaxed operations ------------------------*/ /** @@ -787,6 +978,68 @@ rte_log2_u64(uint64_t v) #ifdef __cplusplus } + +/* + * Since C++ doesn't support generic selection (i.e., _Generic), + * function overloading is used instead. Such functions must be + * defined outside 'extern "C"' to be accepted by the compiler. + */ + +#undef rte_bit_test +#undef rte_bit_set +#undef rte_bit_clear +#undef rte_bit_assign +#undef rte_bit_flip + +#define __RTE_BIT_OVERLOAD_SZ_2(fun, qualifier, size, arg1_type, arg1_name) \ + static inline void \ + rte_bit_ ## fun(qualifier uint ## size ## _t *addr, \ + arg1_type arg1_name) \ + { \ + __rte_bit_ ## fun ## size(addr, arg1_name); \ + } + +#define __RTE_BIT_OVERLOAD_2(fun, qualifier, arg1_type, arg1_name) \ + __RTE_BIT_OVERLOAD_SZ_2(fun, qualifier, 32, arg1_type, arg1_name) \ + __RTE_BIT_OVERLOAD_SZ_2(fun, qualifier, 64, arg1_type, arg1_name) + +#define __RTE_BIT_OVERLOAD_SZ_2R(fun, qualifier, size, ret_type, arg1_type, \ + arg1_name) \ + static inline ret_type \ + rte_bit_ ## fun(qualifier uint ## size ## _t *addr, \ + arg1_type arg1_name) \ + { \ + return __rte_bit_ ## fun ## size(addr, arg1_name); \ + } + +#define __RTE_BIT_OVERLOAD_2R(fun, qualifier, ret_type, arg1_type, arg1_name) \ + __RTE_BIT_OVERLOAD_SZ_2R(fun, qualifier, 32, ret_type, arg1_type, \ + arg1_name) \ + __RTE_BIT_OVERLOAD_SZ_2R(fun, qualifier, 64, ret_type, arg1_type, \ + arg1_name) + +#define __RTE_BIT_OVERLOAD_SZ_3(fun, qualifier, size, arg1_type, arg1_name, \ + arg2_type, arg2_name) \ + static inline void \ + rte_bit_ ## fun(uint ## size ## _t *addr, arg1_type arg1_name, \ + arg2_type arg2_name) \ + { \ + __rte_bit_ ## fun ## size(addr, arg1_name, arg2_name); \ + } + +#define __RTE_BIT_OVERLOAD_3(fun, qualifier, arg1_type, arg1_name, arg2_type, \ + arg2_name) \ + __RTE_BIT_OVERLOAD_SZ_3(fun, qualifier, 32, arg1_type, arg1_name, \ + arg2_type, arg2_name) \ + __RTE_BIT_OVERLOAD_SZ_3(fun, qualifier, 64, arg1_type, arg1_name, \ + arg2_type, arg2_name) + +__RTE_BIT_OVERLOAD_2R(test, const, bool, unsigned int, nr) +__RTE_BIT_OVERLOAD_2(set,, unsigned int, nr) +__RTE_BIT_OVERLOAD_2(clear,, unsigned int, nr) +__RTE_BIT_OVERLOAD_3(assign,, unsigned int, nr, bool, value) +__RTE_BIT_OVERLOAD_2(flip,, unsigned int, nr) + #endif #endif /* _RTE_BITOPS_H_ */ From patchwork Tue Apr 30 09:55:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Mattias_R=C3=B6nnblom?= X-Patchwork-Id: 139728 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 69DE543F3A; Tue, 30 Apr 2024 12:06:11 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6FEDA402CF; Tue, 30 Apr 2024 12:05:58 +0200 (CEST) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on2084.outbound.protection.outlook.com [40.107.13.84]) by mails.dpdk.org (Postfix) with ESMTP id E02A040262 for ; Tue, 30 Apr 2024 12:05:54 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NefJeH5p2TSlpE35s2E/a/Awi/n1jes2aob99cUKn0k3Zf34o840tOPgpz2PX+Kn97hKypmjDt+neh3DAh1nD7K/Ywofu0MtRC24q0veRmVtxZsdnoBa+/0Ne20IDOdaEFOFWBskMFgzSAl37JcU+uTbSnWX/gDuUZSMyKDslvGthaOQX9O+TmsFDvTbe2gDV5kcfgMDbTUAP3K5GS1bGrigiD8ISaRkx89Kh6SohAIP56yWZolLNzw47DOtrrsF2KT0Xjs9HhfqFxd6sV60bJbBf+RLmE7HnHI+4S5NoujBTr2xMSL763xhKq3saK/dsdWasXOAOU6ZNItRTYLGpg== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=70JPJO0XF4kc1nFz9IBwmvdNoabAvqTSzlYxlf9/jws=; b=FCE1heg2vXZKTOt41f0DIbSO53pfSwNMlca85i8zMurcdymzg3aB/cznCQW2vfMjQNzfkm39+3Oc8QF44u1f1CrGEDhtgQLwkK47e73eBBTeOaIXiwzE3d6kiNayeL9NFssHJvEKNyUzfReUWWSQowC47DgDFLmHArpZqa4rVTAz+fCp5anW0XB918EiCj3nCqokCKKhTCS/LdOoOzf9bpijz9lHvpTYZ5kinW6hKvm3H1mVzssYyv6S6MNSsj+oHJFO8Eq2TOdbkAuxn7gyEx0dXowbu01/NXCeemInvqqI5WZbANpgLxE35MeD4hqCNuXGPas7Zsga7cdtCy9elA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 192.176.1.74) smtp.rcpttodomain=dpdk.org smtp.mailfrom=ericsson.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=ericsson.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ericsson.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=70JPJO0XF4kc1nFz9IBwmvdNoabAvqTSzlYxlf9/jws=; b=w1F8d4l0QFhhDncrm2KvWlBq07sRYjU1Bk1Kl9YelAsQwSWMhdBpNM7oyHN3Kk2/fIbUxT/JCVTsCK3CTvwE2f0+F54XQjhP8r8lm807HuXkiPQz+takgqLfZ6DlAdKJnM3AZ2IXbHkKcUncAZ15mC84LRGu9vbBzTUyNb1X+MnWMq92DfmDXVKgHERlB0OmtwYib2pl3gGPEg3nM3C2RtpDe4dNa8OSS0R8pRKAns5H4acHUCWSHyzIPtxtA65ygxYXQAn0L+W40onPtbBCQZmIZPI/g34FSvZoE53oPAPw5Ktgm5KQtMwGLfAG+DwzYonWVGZRi0esNKun1yomGg== Received: from DUZP191CA0043.EURP191.PROD.OUTLOOK.COM (2603:10a6:10:4f8::26) by DU2PR07MB8347.eurprd07.prod.outlook.com (2603:10a6:10:2e6::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.34; Tue, 30 Apr 2024 10:05:53 +0000 Received: from DB1PEPF000509F6.eurprd02.prod.outlook.com (2603:10a6:10:4f8:cafe::8) by DUZP191CA0043.outlook.office365.com (2603:10a6:10:4f8::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.36 via Frontend Transport; Tue, 30 Apr 2024 10:05:53 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 192.176.1.74) smtp.mailfrom=ericsson.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=ericsson.com; Received-SPF: Pass (protection.outlook.com: domain of ericsson.com designates 192.176.1.74 as permitted sender) receiver=protection.outlook.com; client-ip=192.176.1.74; helo=oa.msg.ericsson.com; pr=C Received: from oa.msg.ericsson.com (192.176.1.74) by DB1PEPF000509F6.mail.protection.outlook.com (10.167.242.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7544.18 via Frontend Transport; Tue, 30 Apr 2024 10:05:53 +0000 Received: from seliicinfr00050.seli.gic.ericsson.se (153.88.142.248) by smtp-central.internal.ericsson.com (100.87.178.66) with Microsoft SMTP Server id 15.2.1544.9; Tue, 30 Apr 2024 12:05:52 +0200 Received: from breslau.. (seliicwb00002.seli.gic.ericsson.se [10.156.25.100]) by seliicinfr00050.seli.gic.ericsson.se (Postfix) with ESMTP id 94E351C006A; Tue, 30 Apr 2024 12:05:52 +0200 (CEST) From: =?utf-8?q?Mattias_R=C3=B6nnblom?= To: CC: , Heng Wang , "Stephen Hemminger" , Tyler Retzlaff , =?utf-8?q?Morten_Br=C3=B8rup?= , =?utf-8?q?Mattia?= =?utf-8?q?s_R=C3=B6nnblom?= Subject: [RFC v4 2/6] eal: add unit tests for bit operations Date: Tue, 30 Apr 2024 11:55:19 +0200 Message-ID: <20240430095523.108688-3-mattias.ronnblom@ericsson.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240430095523.108688-1-mattias.ronnblom@ericsson.com> References: <20240429095138.106849-2-mattias.ronnblom@ericsson.com> <20240430095523.108688-1-mattias.ronnblom@ericsson.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DB1PEPF000509F6:EE_|DU2PR07MB8347:EE_ X-MS-Office365-Filtering-Correlation-Id: 2c23b9a0-0898-4c91-0f94-08dc68fd1ecd X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230031|376005|82310400014|1800799015|36860700004; X-Microsoft-Antispam-Message-Info: =?utf-8?q?jx/EN+Dm3gdzihUSxu9oeitkdY4xK9C?= =?utf-8?q?Rrymzp1O6b/DWo4XVAQ04sAkDfdcrbE9kfYKwp1jFK5P+Fq53gy1wth6gRFI8b5+6?= =?utf-8?q?CoJvlPG5AkBw1wgQvvkaZ2dHZszmV/myFdmmeLnUQ1J+LXstLKyxLdygcN0Pm96gn?= =?utf-8?q?BBwjxHyDNmOufShw0oSnCBBQKLXFYPmabG+GmFr1tibbN1oaCRcBoVYKDLzFrnk3B?= =?utf-8?q?vt40wfAJqbvXs7JVO7wBxhGk4sbRdEZ516xpuC4qhiENNwMIs7z0j3jmMGjv/oNfZ?= =?utf-8?q?H/vstN6jUBzyz4Oxlwqnn2iwB5usRf8+Kmtj8Kg7D8wAIXzMayd8KKQYJzK2OEUrO?= =?utf-8?q?m5VLnhNjFib2R7AbyvEC/G7RqvrR6uNDDLjvvrEOdRbesvJHhr7ueK9kRJ0yRbn1G?= =?utf-8?q?qqzzNff9rrEpU2w9ojdL7wEGPdN/jqg1dQkASrhPi+DUIZFCgBc4OLnkCBCZ+Uken?= =?utf-8?q?HuBMDvCEmFsu3vel+/CFRFk53yRLbIDRFFi4kWHDp3zzDRP3NZmBlJ7aU0VgXQdoy?= =?utf-8?q?LKLfNSs5R2pcf+S+Sb/FcPTvjApJZGhliTvTRmnzKeYkDOWyaP8SvhZqdnSOMbtf5?= =?utf-8?q?WWlKZrD7qwDAX03wqYwzFITtl0F9Qjh4zawkLw0N/ijnbNXK9pUuv+bbc65s2Pn4h?= =?utf-8?q?3N3/Gqx0Pump0+/OhjtB/sWt4SNHIaz5aZbqdVl14T3a59mYphK2Jnhnun/qsdI1U?= =?utf-8?q?Uclojx4/EOo1Xh+Ov1G359b5v7EvradSmIdR2rg0N+AwYO0bKonf1xOIUB3D2+thw?= =?utf-8?q?Eo/1dF+0rbU+O6tDNrO3JvRoOlImYhA1/qZkgOYxhzbMp+V7B54hWqSmuJZZ/8NNF?= =?utf-8?q?hCFYXJQw/8h5FMdGcPIJd6TLBMhZIV+m+qCKSeQi0mYDY8jHvrDw9mxwLOzBpwwtp?= =?utf-8?q?EoumBxmDIUBOClKdOVHEcIxlJ9NzcDgy0v1c1uxKNtsPr7BLGk+gSdSUhArQOPs5e?= =?utf-8?q?txB36iwQ6LyPxCaviMHdofrWhvdVrNyfgOqeVcuiaijciOq8S5FIyoge9addwMxh2?= =?utf-8?q?O/vbqoDVVwkadF24YMDinOSEDz2E1khlGuvyG+Na7duvRSp1BbRFKQvVLaeBd6qoo?= =?utf-8?q?kqiDQS8BRHmpFxlHwsmX4RZnaqjCcPBqfa0kAGT1+YBzyprn+sHQBkQADlQ6DP5VC?= =?utf-8?q?d6BK3IgTvlG2zzBss01WH2jSC/BWmp5aKB5cx2ZhlPUEKeXDaUCZ1IJVbOhM3NwqD?= =?utf-8?q?zkWPWbz9PiLNAxnunv+IVuDNjDbizWAmzR5f++wP8wb7WWlvxdeYeIgenU9sokO5c?= =?utf-8?q?0P0d6nBIvv1wS7/JLiMGggkiIPi7U48ByYg5O5O0gW4J5j4g7ZpyWHK6QEbp53Uw0?= =?utf-8?q?EW/zv7QcOFNf?= X-Forefront-Antispam-Report: CIP:192.176.1.74; CTRY:SE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:oa.msg.ericsson.com; PTR:office365.se.ericsson.net; CAT:NONE; SFS:(13230031)(376005)(82310400014)(1800799015)(36860700004); DIR:OUT; SFP:1101; X-OriginatorOrg: ericsson.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Apr 2024 10:05:53.1756 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2c23b9a0-0898-4c91-0f94-08dc68fd1ecd X-MS-Exchange-CrossTenant-Id: 92e84ceb-fbfd-47ab-be52-080c6b87953f X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=92e84ceb-fbfd-47ab-be52-080c6b87953f; Ip=[192.176.1.74]; Helo=[oa.msg.ericsson.com] X-MS-Exchange-CrossTenant-AuthSource: DB1PEPF000509F6.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU2PR07MB8347 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 Extend bitops tests to cover the rte_bit_[set|clear|assign|test]() family of functions. The tests are converted to use the test suite runner framework. RFC v4: * Remove redundant line continuations. Signed-off-by: Mattias Rönnblom Acked-by: Morten Brørup Acked-by: Tyler Retzlaff --- app/test/test_bitops.c | 80 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/app/test/test_bitops.c b/app/test/test_bitops.c index 0d4ccfb468..111f9b328e 100644 --- a/app/test/test_bitops.c +++ b/app/test/test_bitops.c @@ -1,13 +1,63 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2019 Arm Limited + * Copyright(c) 2024 Ericsson AB */ +#include + #include #include +#include #include "test.h" -uint32_t val32; -uint64_t val64; +#define GEN_TEST_BIT_ACCESS(test_name, set_fun, clear_fun, assign_fun, \ + flip_fun, test_fun, size) \ + static int \ + test_name(void) \ + { \ + uint ## size ## _t reference = (uint ## size ## _t)rte_rand(); \ + unsigned int bit_nr; \ + uint ## size ## _t word = (uint ## size ## _t)rte_rand(); \ + \ + for (bit_nr = 0; bit_nr < size; bit_nr++) { \ + bool reference_bit = (reference >> bit_nr) & 1; \ + bool assign = rte_rand() & 1; \ + if (assign) \ + assign_fun(&word, bit_nr, reference_bit); \ + else { \ + if (reference_bit) \ + set_fun(&word, bit_nr); \ + else \ + clear_fun(&word, bit_nr); \ + \ + } \ + TEST_ASSERT(test_fun(&word, bit_nr) == reference_bit, \ + "Bit %d had unexpected value", bit_nr); \ + flip_fun(&word, bit_nr); \ + TEST_ASSERT(test_fun(&word, bit_nr) != reference_bit, \ + "Bit %d had unflipped value", bit_nr); \ + flip_fun(&word, bit_nr); \ + } \ + \ + for (bit_nr = 0; bit_nr < size; bit_nr++) { \ + bool reference_bit = (reference >> bit_nr) & 1; \ + TEST_ASSERT(test_fun(&word, bit_nr) == reference_bit, \ + "Bit %d had unexpected value", bit_nr); \ + } \ + \ + TEST_ASSERT(reference == word, "Word had unexpected value"); \ + \ + return TEST_SUCCESS; \ + } + +GEN_TEST_BIT_ACCESS(test_bit_access32, rte_bit_set, rte_bit_clear, + rte_bit_assign, rte_bit_flip, rte_bit_test, 32) + +GEN_TEST_BIT_ACCESS(test_bit_access64, rte_bit_set, rte_bit_clear, + rte_bit_assign, rte_bit_flip, rte_bit_test, 64) + +static uint32_t val32; +static uint64_t val64; #define MAX_BITS_32 32 #define MAX_BITS_64 64 @@ -117,22 +167,22 @@ test_bit_relaxed_test_set_clear(void) return TEST_SUCCESS; } +static struct unit_test_suite test_suite = { + .suite_name = "Bitops test suite", + .unit_test_cases = { + TEST_CASE(test_bit_access32), + TEST_CASE(test_bit_access64), + TEST_CASE(test_bit_relaxed_set), + TEST_CASE(test_bit_relaxed_clear), + TEST_CASE(test_bit_relaxed_test_set_clear), + TEST_CASES_END() + } +}; + static int test_bitops(void) { - val32 = 0; - val64 = 0; - - if (test_bit_relaxed_set() < 0) - return TEST_FAILED; - - if (test_bit_relaxed_clear() < 0) - return TEST_FAILED; - - if (test_bit_relaxed_test_set_clear() < 0) - return TEST_FAILED; - - return TEST_SUCCESS; + return unit_test_suite_runner(&test_suite); } REGISTER_FAST_TEST(bitops_autotest, true, true, test_bitops); From patchwork Tue Apr 30 09:55:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Mattias_R=C3=B6nnblom?= X-Patchwork-Id: 139729 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E4B6043F3A; Tue, 30 Apr 2024 12:06:24 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2C09C402E3; Tue, 30 Apr 2024 12:06:00 +0200 (CEST) Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04on2055.outbound.protection.outlook.com [40.107.7.55]) by mails.dpdk.org (Postfix) with ESMTP id 23A0B402BA for ; Tue, 30 Apr 2024 12:05:56 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PnWGvgjBBxEA8m4509+IuQRhgmxrj1nwQBu8BLIva58nUDXWtydGUs1WM42Enkp51o53+fPB2gdAzDBZCEDyS44y0q/Eql8a4iypwc4WiY/Z8/Zz504ir7OOIeFwhEam286TbhquQGcsOqYq8GE6CGz0S1ODMVtMGWLnz5BppvzxR1MO+DBFStDU1rDhXPi4+i9S4RrtLcJoTr9PDYRPIPbm1yh7ZtFqV204wofNP+G29cPg5qUokX0G7kSCjXEi6FqmqEK3cMLLCEt4kt0TFuEoU93ac9RzgvO25d3s9WyvYlUZ3e4Mgzbdjj4tEfps5mZMbTzSoX0jjz5P+5CJpA== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=AvPWbCvgzyOJyxa/j0ge/ILRgogIdQ9NHvtGx46yEDw=; b=bDeekbL81v3429vh/TW04dH1WnXTv0nYP9xF2X5wQAjoLFClbnYj0NKNKAPk0ixhTUKLv9/aeeWjpq5bJSDdWUTUPUfQw6Phu0Yk3z1j6UKLjMdj8LbjfeQ6wojNgKRQxeoNwPnBWouEBt130trjHaTvbWydEojZaHSd9Zhcb6l8BzjXRI3Q12CwenPGxInxDQKpRyrzENiqKTLWQmtUQJQ8FZq+8VP7T9JrQ6Uhb5cbuZEQ0NuAfXITzixyDcoRPRQ5M8BNGt7SjjBDBoCxOxpfcYwW2oGUoeIxpKG7BQc7rNHmMdujZ79XhkNXzZXqZNjuJHl+h3kKmjHiyFUHtw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 192.176.1.74) smtp.rcpttodomain=dpdk.org smtp.mailfrom=ericsson.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=ericsson.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ericsson.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=AvPWbCvgzyOJyxa/j0ge/ILRgogIdQ9NHvtGx46yEDw=; b=prVgr1sN1v24nq7JnyQdWBYJvHnmIA8GMfk67wgXvQLXfBpU+zep9Lxh7f9U6ogo9AeJ+89asEu4SVhQDLHDHgpZ0A3mNbn1cAvaYirxr77JtI2+Y9UrbNqOGFY7CFGrOgGHNmoFN2i34fXZ2bG9dkIiOMMOhYJtYqLJiinu1r/RwEosifqXjlDlOuSX8Y0qDais7F4J/4soOSG64/SrqYKUr9hK92zzn6uxs/rRLPBdrTIPSvq/E4ITN58aiYCHBKU6ssTQFnWCchM6IBONkuXSoaxDpTIWSUPO1DXKyZf7VzgFCRIWxDi/dePRFpMAOj+v1AlE5IlrXee3aXDBBw== Received: from AM6P191CA0101.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::42) by AM9PR07MB7859.eurprd07.prod.outlook.com (2603:10a6:20b:302::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.36; Tue, 30 Apr 2024 10:05:54 +0000 Received: from AMS1EPF00000042.eurprd04.prod.outlook.com (2603:10a6:209:8a:cafe::3c) by AM6P191CA0101.outlook.office365.com (2603:10a6:209:8a::42) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.35 via Frontend Transport; Tue, 30 Apr 2024 10:05:54 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 192.176.1.74) smtp.mailfrom=ericsson.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=ericsson.com; Received-SPF: Pass (protection.outlook.com: domain of ericsson.com designates 192.176.1.74 as permitted sender) receiver=protection.outlook.com; client-ip=192.176.1.74; helo=oa.msg.ericsson.com; pr=C Received: from oa.msg.ericsson.com (192.176.1.74) by AMS1EPF00000042.mail.protection.outlook.com (10.167.16.39) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7544.18 via Frontend Transport; Tue, 30 Apr 2024 10:05:54 +0000 Received: from seliicinfr00050.seli.gic.ericsson.se (153.88.142.248) by smtp-central.internal.ericsson.com (100.87.178.62) with Microsoft SMTP Server id 15.2.1544.9; Tue, 30 Apr 2024 12:05:53 +0200 Received: from breslau.. (seliicwb00002.seli.gic.ericsson.se [10.156.25.100]) by seliicinfr00050.seli.gic.ericsson.se (Postfix) with ESMTP id 287821C006A; Tue, 30 Apr 2024 12:05:53 +0200 (CEST) From: =?utf-8?q?Mattias_R=C3=B6nnblom?= To: CC: , Heng Wang , "Stephen Hemminger" , Tyler Retzlaff , =?utf-8?q?Morten_Br=C3=B8rup?= , =?utf-8?q?Mattia?= =?utf-8?q?s_R=C3=B6nnblom?= Subject: [RFC v4 3/6] eal: add exactly-once bit access functions Date: Tue, 30 Apr 2024 11:55:20 +0200 Message-ID: <20240430095523.108688-4-mattias.ronnblom@ericsson.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240430095523.108688-1-mattias.ronnblom@ericsson.com> References: <20240429095138.106849-2-mattias.ronnblom@ericsson.com> <20240430095523.108688-1-mattias.ronnblom@ericsson.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AMS1EPF00000042:EE_|AM9PR07MB7859:EE_ X-MS-Office365-Filtering-Correlation-Id: 71bfe9dc-cc0a-41af-35e5-08dc68fd1fa0 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230031|82310400014|376005|36860700004|1800799015; X-Microsoft-Antispam-Message-Info: =?utf-8?q?BgncMgxjckh/SDtFnQSWoMkSMuMZl6u?= =?utf-8?q?ACZAgUx98eWz45bEykPHVNiBuKeDoM3+b78ZiBtqb5mRIqK7dKkXnYH/J+tlyQde4?= =?utf-8?q?teCoE7BzJG24NcKdkOziltLniTVecsVXnxgaDS5mFP8cJesop7wo1WChQshl3HBhT?= =?utf-8?q?NK4cnuLTInqXtAOrZfMYzFV0eKgomU5LhHbO0sz5xNpyssfP0Q7jPyjqHgiYJ5wEO?= =?utf-8?q?8t0+KLJFUxT7VNKrIN4upZXCJix3MtXrcYKgoTDfxWkRz7S5AQgP1IDEFYVqjFveL?= =?utf-8?q?Xc9P/crDqopNMHRQ07ptHTL3vtnKspdnjeYEN6gD4WEr3aicbUX5rYnxEG1TiUhgT?= =?utf-8?q?0tJrxQ3+Z2mNk1cAgbLMUG1Z3bg9I0YKNHCYXqAVIw7BySv5lpceCAdpPXRphfjjw?= =?utf-8?q?j1hKOm7FMXrk00S7qxm18kb4ky0hTFMEZlHouPzMJRY6ukAMzw5nUltp/b7WNFz2Y?= =?utf-8?q?pnph18YOlbxzF+D6tdvQOhorC6yOxSk7xDy8an/kfOPlrNDdvEyvFNZ3b4LmPI9ZT?= =?utf-8?q?od/wcpFM8XgT9psXD1Lua37QPRN0zP3dPOz1T0daDsQIlZKD0b51iDXl6jEObl2O6?= =?utf-8?q?o4cIwsBzGDDfSJlGwHIIc1mv7MSuP4LhoYsXpHdYF7++MirbSNjvaxsW8xhxsuoXY?= =?utf-8?q?zOfV0NHJ3FQPz6j7chq87lhTgLTxSZ4CYE5Z+WaFVNw++2s1TZg9uYKBYyB+UpM8m?= =?utf-8?q?zcwCTK+20b+GLTZmuVhGnkH9AP3pixNZUA+FIA7kGCMk3tr4Bexkav4E2n9lj/L2o?= =?utf-8?q?O2ytRurW0gRcySB60g9glQxQl2BU/sCdnxNpkeK78TK/EFHrKA+PZVKqokmdFG8zR?= =?utf-8?q?QDfYq6LOtxmNNo5TQ9dvkBW83Z94f0eV35T4O9RTvsw7vUF/hiiRRagMkL4PBp1XF?= =?utf-8?q?l01B65L1AddwF2ge2VT0v9GD9XdbECxZxwJABdIPGXnTkhDqsqIx8aH7lohprQmxp?= =?utf-8?q?eQzk8aJu1GwnsWjs6a4u7xbjJJVihoEHJ6e63ELMkRS5nvOpDwZXEwuKjJCIgUV/g?= =?utf-8?q?3Jr8ELU4nx2euuy6uK0pxR3sriJiFXR6ScoDF8r0N25WJglH1H8pLqTp8nmECNgpd?= =?utf-8?q?vJt33SuArdysodR5iuCOQki1hAZimSH5lw0T1ps1c1gsBMigqy/kcf1bV4Qr7mbbT?= =?utf-8?q?tVqmzJMsfwBJDmlgRY5Bjj4BzqNAqBH5+3Scen1nhlHU1YlyJhdwU/zGAmngXqT0t?= =?utf-8?q?qu8lI6MH6dRe2++6S0mvxjc7awEG/VlIhWl3dHDpQDCShvuUZ2UxC+ULbmktsDOzV?= =?utf-8?q?GNRbstIPaZ5+bKjJdYMF+UBM/0qX4zlibtwioJO7yQHa6ga1RJkKhZlxRXFuqZM/p?= =?utf-8?q?SI/dJtXsF0Ac?= X-Forefront-Antispam-Report: CIP:192.176.1.74; CTRY:SE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:oa.msg.ericsson.com; PTR:office365.se.ericsson.net; CAT:NONE; SFS:(13230031)(82310400014)(376005)(36860700004)(1800799015); DIR:OUT; SFP:1101; X-OriginatorOrg: ericsson.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Apr 2024 10:05:54.5906 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 71bfe9dc-cc0a-41af-35e5-08dc68fd1fa0 X-MS-Exchange-CrossTenant-Id: 92e84ceb-fbfd-47ab-be52-080c6b87953f X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=92e84ceb-fbfd-47ab-be52-080c6b87953f; Ip=[192.176.1.74]; Helo=[oa.msg.ericsson.com] X-MS-Exchange-CrossTenant-AuthSource: AMS1EPF00000042.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM9PR07MB7859 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 Add bit test/set/clear/assign functions which prevents certain compiler optimizations and guarantees that program-level memory loads and/or stores will actually occur. These functions are useful when interacting with memory-mapped hardware devices. The "once" family of functions does not promise atomicity and provides no memory ordering guarantees beyond the C11 relaxed memory model. RFC v3: * Work around lack of C++ support for _Generic (Tyler Retzlaff). Signed-off-by: Mattias Rönnblom Acked-by: Morten Brørup Acked-by: Tyler Retzlaff --- lib/eal/include/rte_bitops.h | 195 +++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index 9d426f1602..f77bd83e97 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -224,6 +224,177 @@ extern "C" { uint32_t *: __rte_bit_flip32, \ uint64_t *: __rte_bit_flip64)(addr, nr) +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Generic selection macro to test exactly once the value of a bit in + * a 32-bit or 64-bit word. The type of operation depends on the type + * of the @c addr parameter. + * + * This function is guaranteed to result in exactly one memory load + * (e.g., it may not be eliminate or merged by the compiler). + * + * \code{.c} + * rte_bit_once_set(addr, 17); + * if (rte_bit_once_test(addr, 17)) { + * ... + * } + * \endcode + * + * In the above example, rte_bit_once_set() may not be removed by + * the compiler, which would be allowed in case rte_bit_set() and + * rte_bit_test() was used. + * + * \code{.c} + * while (rte_bit_once_test(addr, 17); + * ; + * \endcode + * + * In case rte_bit_test(addr, 17) was used instead, the resulting + * object code could (and in many cases would be) replaced with + * the equivalent to + * \code{.c} + * if (rte_bit_test(addr, 17)) { + * for (;;) // spin forever + * ; + * } + * \endcode + * + * rte_bit_once_test() does not give any guarantees in regards to + * memory ordering or atomicity. + * + * The regular bit set operations (e.g., rte_bit_test()) should be + * preferred over the "once" family of operations (e.g., + * rte_bit_once_test()) if possible, since the latter may prevent + * optimizations crucial for run-time performance. + * + * @param addr + * A pointer to the word to query. + * @param nr + * The index of the bit. + * @return + * Returns true if the bit is set, and false otherwise. + */ + +#define rte_bit_once_test(addr, nr) \ + _Generic((addr), \ + uint32_t *: __rte_bit_once_test32, \ + uint64_t *: __rte_bit_once_test64)(addr, nr) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Set bit in word exactly once. + * + * Set bit specified by @c nr in the word pointed to by @c addr to '1' + * exactly once. + * + * This function is guaranteed to result in exactly one memory load + * and exactly one memory store, *or* an atomic bit set operation. + * + * See rte_bit_test_once32() for more information and uses cases for + * the "once" class of functions. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ + +#define rte_bit_once_set(addr, nr) \ + _Generic((addr), \ + uint32_t *: __rte_bit_once_set32, \ + uint64_t *: __rte_bit_once_set64)(addr, nr) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Clear bit in word exactly once. + * + * Set bit specified by @c nr in the word pointed to by @c addr to '0' + * exactly once. + * + * This function is guaranteed to result in exactly one memory load + * and exactly one memory store, *or* an atomic bit clear operation. + * + * See rte_bit_test_once32() for more information and uses cases for + * the "once" class of functions. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ +#define rte_bit_once_clear(addr, nr) \ + _Generic((addr), \ + uint32_t *: __rte_bit_once_clear32, \ + uint64_t *: __rte_bit_once_clear64)(addr, nr) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Assign a value to bit in a word exactly once. + * + * Set bit specified by @c nr in the word pointed to by @c addr to the + * value indicated by @c value exactly once. + * + * This function is guaranteed to result in exactly one memory load + * and exactly one memory store, *or* an atomic bit clear operation. + * + * This function does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param value + * The new value of the bit - true for '1', or false for '0'. + */ +#define rte_bit_once_assign(addr, nr, value) \ + _Generic((addr), \ + uint32_t *: __rte_bit_once_assign32, \ + uint64_t *: __rte_bit_once_assign64)(addr, nr, value) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Flip bit in word, reading and writing exactly once. + * + * Change the value of a bit to '0' if '1' or '1' if '0' in a 32-bit + * or 64-bit word. The type of operation depends on the type of the @c + * addr parameter. + * + * This function is guaranteed to result in exactly one memory load + * and exactly one memory store, *or* an atomic bit flip operation. + * + * See rte_bit_test_once32() for more information and uses cases for + * the "once" class of functions. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ +#define rte_bit_once_flip(addr, nr) \ + _Generic((addr), \ + uint32_t *: __rte_bit_once_flip32, \ + uint64_t *: __rte_bit_once_flip64)(addr, nr) + #define __RTE_GEN_BIT_TEST(family, fun, qualifier, size) \ __rte_experimental \ static inline bool \ @@ -296,6 +467,18 @@ __RTE_GEN_BIT_CLEAR(, clear,, 64) __RTE_GEN_BIT_ASSIGN(, assign,, 64) __RTE_GEN_BIT_FLIP(, flip,, 64) +__RTE_GEN_BIT_TEST(once_, test, volatile, 32) +__RTE_GEN_BIT_SET(once_, set, volatile, 32) +__RTE_GEN_BIT_CLEAR(once_, clear, volatile, 32) +__RTE_GEN_BIT_ASSIGN(once_, assign, volatile, 32) +__RTE_GEN_BIT_FLIP(once_, flip, volatile, 32) + +__RTE_GEN_BIT_TEST(once_, test, volatile, 64) +__RTE_GEN_BIT_SET(once_, set, volatile, 64) +__RTE_GEN_BIT_CLEAR(once_, clear, volatile, 64) +__RTE_GEN_BIT_ASSIGN(once_, assign, volatile, 64) +__RTE_GEN_BIT_FLIP(once_, flip, volatile, 64) + /*------------------------ 32-bit relaxed operations ------------------------*/ /** @@ -991,6 +1174,12 @@ rte_log2_u64(uint64_t v) #undef rte_bit_assign #undef rte_bit_flip +#undef rte_bit_once_test +#undef rte_bit_once_set +#undef rte_bit_once_clear +#undef rte_bit_once_assign +#undef rte_bit_once_flip + #define __RTE_BIT_OVERLOAD_SZ_2(fun, qualifier, size, arg1_type, arg1_name) \ static inline void \ rte_bit_ ## fun(qualifier uint ## size ## _t *addr, \ @@ -1040,6 +1229,12 @@ __RTE_BIT_OVERLOAD_2(clear,, unsigned int, nr) __RTE_BIT_OVERLOAD_3(assign,, unsigned int, nr, bool, value) __RTE_BIT_OVERLOAD_2(flip,, unsigned int, nr) +__RTE_BIT_OVERLOAD_2R(once_test, const volatile, bool, unsigned int, nr) +__RTE_BIT_OVERLOAD_2(once_set, volatile, unsigned int, nr) +__RTE_BIT_OVERLOAD_2(once_clear, volatile, unsigned int, nr) +__RTE_BIT_OVERLOAD_3(once_assign, volatile, unsigned int, nr, bool, value) +__RTE_BIT_OVERLOAD_2(once_flip, volatile, unsigned int, nr) + #endif #endif /* _RTE_BITOPS_H_ */ From patchwork Tue Apr 30 09:55:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Mattias_R=C3=B6nnblom?= X-Patchwork-Id: 139732 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C385F43F3A; Tue, 30 Apr 2024 12:06:54 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7A4FE4064A; Tue, 30 Apr 2024 12:06:04 +0200 (CEST) Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on2054.outbound.protection.outlook.com [40.107.14.54]) by mails.dpdk.org (Postfix) with ESMTP id DC08F402EB for ; Tue, 30 Apr 2024 12:06:01 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hk0Ba68VDp9Nl1c/a6aXVSwEAPOZpA//cnq618hrb0AAaAJOduFeverk3zlQWjCjmZUh42fsEB2pIQXHKmAVA+dYGWizidQhDbLxn1g10I2JJijMt3kzn55vrLQSp/RwWe9b4TNOlkQ7wNZSjmr3TEULjhNK/drkzXzaXAXs5UNXjP7eyZT+UK/3OSboR06hN4YEhrGrgZwDbLnv2OkNP3YUJbmG1Leiu0Yrc/e9+rqFBv2H/a0Ag1HL8lSlVgFehkLPmQ/fR8UoFNPjP8XhXc9K5pA2TvCYs0IPABmnk/87ZF7TlLtbUGdU5g3UQs3NXEhCQN0QkCikVVRWjZ2bzg== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=S7lEMJk/WgNgYNKA+tfHbv7buTOuFqDk0YnVV6mMMn0=; b=dUndGY+ifkidIeaXY9EKC5tS0fftIlNpNIxffZZ+250mWUDtJRF7Ao95hOJO+sD1yV2WmDS9gR1Zlo2nH/czk3XlO/KOi/nlIKrIc31i3vt++SDgGINtA2caXz6pscZZ8AHBt/0joIOG7RC4PetBBuCT67rzGxb3DAy4lmk7iy+8+dDx2JNTFiGBCOFRi2exukpyDO+AzYj7slo+utWkUQkiCAzRKahZYU7Tnqtn4WHjr0nHX+EWZ0XJn1ZOAZaBniNXhn2dMHhRnz1kttvBCPO23O5AxgWk7ftNXut4vZUNpbP4q3D+4siM8LJ9hpCneywJ/qpb4zGkmTu8qHyAjg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 192.176.1.74) smtp.rcpttodomain=dpdk.org smtp.mailfrom=ericsson.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=ericsson.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ericsson.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=S7lEMJk/WgNgYNKA+tfHbv7buTOuFqDk0YnVV6mMMn0=; b=Tn5YDEtrjJ25uALcSBR6r8R2BLTunG/6vHJ0MoV/okZbwmqNKwoJTo1cuA1wIqTxSORk0sOf7uSpsECyw8Cx3iKuXGbZplZuUYE2vUNKfrlJQVlkuPhh/7i2dnuet+LwlurWHdxLX/KEhwqI3tkItd542pqAYrNnNYjGgV+VmMC1bAzIxQUm/omnKQEc9sRdWwZsle5gYZYIRV6UUOqWz7TMSZ6bBKNqIxT/ADlm5c5QZ9mUkcwm/zhH2n4SI08MUeht5q1o/FVPU+CgiyuLjLbjFV9uJAv5joxwpENSTqxpDZl1eG5lqbBXQD9hEvLAKHE6aUooT3Iff7sdBhoTWg== Received: from DUZPR01CA0236.eurprd01.prod.exchangelabs.com (2603:10a6:10:4b5::15) by AS2PR07MB9328.eurprd07.prod.outlook.com (2603:10a6:20b:608::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.34; Tue, 30 Apr 2024 10:05:57 +0000 Received: from DB3PEPF0000885A.eurprd02.prod.outlook.com (2603:10a6:10:4b5:cafe::8f) by DUZPR01CA0236.outlook.office365.com (2603:10a6:10:4b5::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.34 via Frontend Transport; Tue, 30 Apr 2024 10:05:54 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 192.176.1.74) smtp.mailfrom=ericsson.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=ericsson.com; Received-SPF: Pass (protection.outlook.com: domain of ericsson.com designates 192.176.1.74 as permitted sender) receiver=protection.outlook.com; client-ip=192.176.1.74; helo=oa.msg.ericsson.com; pr=C Received: from oa.msg.ericsson.com (192.176.1.74) by DB3PEPF0000885A.mail.protection.outlook.com (10.167.242.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7544.18 via Frontend Transport; Tue, 30 Apr 2024 10:05:54 +0000 Received: from seliicinfr00050.seli.gic.ericsson.se (153.88.142.248) by smtp-central.internal.ericsson.com (100.87.178.69) with Microsoft SMTP Server id 15.2.1544.9; Tue, 30 Apr 2024 12:05:53 +0200 Received: from breslau.. (seliicwb00002.seli.gic.ericsson.se [10.156.25.100]) by seliicinfr00050.seli.gic.ericsson.se (Postfix) with ESMTP id B914B1C006A; Tue, 30 Apr 2024 12:05:53 +0200 (CEST) From: =?utf-8?q?Mattias_R=C3=B6nnblom?= To: CC: , Heng Wang , "Stephen Hemminger" , Tyler Retzlaff , =?utf-8?q?Morten_Br=C3=B8rup?= , =?utf-8?q?Mattia?= =?utf-8?q?s_R=C3=B6nnblom?= Subject: [RFC v4 4/6] eal: add unit tests for exactly-once bit access functions Date: Tue, 30 Apr 2024 11:55:21 +0200 Message-ID: <20240430095523.108688-5-mattias.ronnblom@ericsson.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240430095523.108688-1-mattias.ronnblom@ericsson.com> References: <20240429095138.106849-2-mattias.ronnblom@ericsson.com> <20240430095523.108688-1-mattias.ronnblom@ericsson.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DB3PEPF0000885A:EE_|AS2PR07MB9328:EE_ X-MS-Office365-Filtering-Correlation-Id: bf57ba10-05dc-4358-48ab-08dc68fd1f7d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230031|82310400014|376005|1800799015|36860700004; X-Microsoft-Antispam-Message-Info: =?utf-8?q?gWdEAwWmhcWRfaK43feQhpIgW2PZG7d?= =?utf-8?q?9IUdjf4fNYvaX/Op+1OnJqIjKbiRqFxigED6hzvwFXgZZxCgZZYubNyv0/Anozs2R?= =?utf-8?q?8CtNFAFbI3oLf5nqw2RNxjtMb0+rCNgrfN2CVWDJcgBkoOLs+02qx6l6LinD1ayBV?= =?utf-8?q?URa3eI8jtJELotuYa415xmlJ6bO/+uAK4EAVPDaw2odafNQcb2KBE23dBJCFqduEl?= =?utf-8?q?YP6JfHfP2fWhKUjXsT9X9EyA15MY2/SzaIerUjiT0XroVhjUhU+x3pXqq1ZDJobA8?= =?utf-8?q?M4MSSMOMLTTlYrqNj3IfvtsPBjKo9TS99lV83wUx3rYtjTFnpqwT29usE2nl2j5/M?= =?utf-8?q?PMgGepxA3XNittdebQsUUL4gEyS1RWPjQS8YhdtCuPCY18tPYmGH5HS8V39r3iF9d?= =?utf-8?q?k3aWzfyOppcVgb17RFMYa1Mve1VHUV6tIIj8HxEfXEAbflsONjiFsaxHSMNDJZ9ht?= =?utf-8?q?mogFqUy4zNemmLpx+Dj34CGL94/p6aPIqWQnG3vAwSCCcTyxg1YcOtOdhFbnjYfX2?= =?utf-8?q?WGEnK/wkcai2QsFQ6Iz0TkV+D8baSz4xBSpqs5YtUm/NpuBRt4XU6QvEDByvblRQw?= =?utf-8?q?/7WO0NIu3iYT1chxQIiuKjH/NA+45QEQJRQVBafs9iAFuGTNIWRVFHzq8REMS1zO5?= =?utf-8?q?MNg34VPq90TMVn2YcRa15NUcKsw1Yeh0wnvL+LWVhvoSfClBfHM5+S7vPmh6dNmCt?= =?utf-8?q?ST4hJtKxlxhHOSangE8sSxO5XfsGElYoxn9x0/7kuvYa5W5By3R9G0wV9c8deevvT?= =?utf-8?q?Es9mJoPzTUTQi/P9sOitdV/9UL6m5DGqm9wxP2wJ8txiIWWftSZyyWFWiQvZodaY5?= =?utf-8?q?rdWOqkDxFiLNB8BB5hCC3bRGGYQb2F/jL5zhMANB+/FW08KOIA2rAxMVh28qOsEnZ?= =?utf-8?q?gfyq+wXvewL6bNK1jpIQ9XasnFhLzQ7WDXqFp7+kv10EhUynmYIZuwdYxKzyTdHZo?= =?utf-8?q?XfXHkslYHeIMSUfsq5d5nLWF8JaOyuDHcBfBFjYewG+1tRTMQuo5CfRBcl3e8ADhY?= =?utf-8?q?qhtDYI2xFubG9EiFSv99SpF2Q4EPPgm5WDmCvpbNjYfi8LxTA2XgJ0XCMXhe/9bI/?= =?utf-8?q?+LpR86WK3tNY36tMsKOZVpTidMdV6QJ1fGCRyhHbI5n8TSVbqC8QuI57G+5ByMASy?= =?utf-8?q?g2LfvkPMVz+0fveD7jll8YbMY8IwSGeAa7TBOmHHMHGCdXwlOHYZske9i9E728Jlj?= =?utf-8?q?tbEv0K8i6mO9V/bzaU9bMyamAcCOePX1n/CrL1Cbb9WiPhuO2WGI+6xbG5XzzMeuL?= =?utf-8?q?MIf7WI7OHujXnIEtP9Vy13Pc2dbkFRlueTzgA32n36x7UK5nXR7i189upcLJBaE8Q?= =?utf-8?q?uV7gyACqrQ5t?= X-Forefront-Antispam-Report: CIP:192.176.1.74; CTRY:SE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:oa.msg.ericsson.com; PTR:office365.se.ericsson.net; CAT:NONE; SFS:(13230031)(82310400014)(376005)(1800799015)(36860700004); DIR:OUT; SFP:1101; X-OriginatorOrg: ericsson.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Apr 2024 10:05:54.3305 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: bf57ba10-05dc-4358-48ab-08dc68fd1f7d X-MS-Exchange-CrossTenant-Id: 92e84ceb-fbfd-47ab-be52-080c6b87953f X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=92e84ceb-fbfd-47ab-be52-080c6b87953f; Ip=[192.176.1.74]; Helo=[oa.msg.ericsson.com] X-MS-Exchange-CrossTenant-AuthSource: DB3PEPF0000885A.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS2PR07MB9328 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 Extend bitops tests to cover the rte_bit_once_[set|clear|assign|test]() family of functions. RFC v4: * Remove redundant continuations. Signed-off-by: Mattias Rönnblom Acked-by: Morten Brørup Acked-by: Tyler Retzlaff --- app/test/test_bitops.c | 10 + lib/eal/include/rte_bitops.h | 425 +++++++++++++++++++++++++++++++++++ 2 files changed, 435 insertions(+) diff --git a/app/test/test_bitops.c b/app/test/test_bitops.c index 111f9b328e..615ec6e563 100644 --- a/app/test/test_bitops.c +++ b/app/test/test_bitops.c @@ -56,6 +56,14 @@ GEN_TEST_BIT_ACCESS(test_bit_access32, rte_bit_set, rte_bit_clear, GEN_TEST_BIT_ACCESS(test_bit_access64, rte_bit_set, rte_bit_clear, rte_bit_assign, rte_bit_flip, rte_bit_test, 64) +GEN_TEST_BIT_ACCESS(test_bit_once_access32, rte_bit_once_set, + rte_bit_once_clear, rte_bit_once_assign, + rte_bit_once_flip, rte_bit_once_test, 32) + +GEN_TEST_BIT_ACCESS(test_bit_once_access64, rte_bit_once_set, + rte_bit_once_clear, rte_bit_once_assign, + rte_bit_once_flip, rte_bit_once_test, 64) + static uint32_t val32; static uint64_t val64; @@ -172,6 +180,8 @@ static struct unit_test_suite test_suite = { .unit_test_cases = { TEST_CASE(test_bit_access32), TEST_CASE(test_bit_access64), + TEST_CASE(test_bit_once_access32), + TEST_CASE(test_bit_once_access64), TEST_CASE(test_bit_relaxed_set), TEST_CASE(test_bit_relaxed_clear), TEST_CASE(test_bit_relaxed_test_set_clear), diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index f77bd83e97..abfe96d531 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -21,6 +21,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -395,6 +396,199 @@ extern "C" { uint32_t *: __rte_bit_once_flip32, \ uint64_t *: __rte_bit_once_flip64)(addr, nr) +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Test if a particular bit in a word is set with a particular memory + * order. + * + * Test a bit with the resulting memory load ordered as per the + * specified memory order. + * + * @param addr + * A pointer to the word to query. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + * @return + * Returns true if the bit is set, and false otherwise. + */ +#define rte_bit_atomic_test(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_test32, \ + uint64_t *: __rte_bit_atomic_test64)(addr, nr, memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically set bit in word. + * + * Atomically set bit specified by @c nr in the word pointed to by @c + * addr to '1', with the memory ordering as specified by @c + * memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + */ +#define rte_bit_atomic_set(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_set32, \ + uint64_t *: __rte_bit_atomic_set64)(addr, nr, memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically clear bit in word. + * + * Atomically set bit specified by @c nr in the word pointed to by @c + * addr to '0', with the memory ordering as specified by @c + * memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + */ +#define rte_bit_atomic_clear(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_clear32, \ + uint64_t *: __rte_bit_atomic_clear64)(addr, nr, memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically assign a value to bit in word. + * + * Atomically set bit specified by @c nr in the word pointed to by @c + * addr to the value indicated by @c value, with the memory ordering + * as specified with @c memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param value + * The new value of the bit - true for '1', or false for '0'. + * @param memory_order + * The memory order to use. See for details. + */ +#define rte_bit_atomic_assign(addr, nr, value, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_assign32, \ + uint64_t *: __rte_bit_atomic_assign64)(addr, nr, value, \ + memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically flip bit in word. + * + * Atomically negate the value of the bit specified by @c nr in the + * word pointed to by @c addr to the value indicated by @c value, with + * the memory ordering as specified with @c memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + */ +#define rte_bit_atomic_flip(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_flip32, \ + uint64_t *: __rte_bit_atomic_flip64)(addr, nr, memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically test and set a bit in word. + * + * Atomically test and set bit specified by @c nr in the word pointed + * to by @c addr to '1', with the memory ordering as specified with @c + * memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + * @return + * Returns true if the bit was set, and false otherwise. + */ +#define rte_bit_atomic_test_and_set(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_test_and_set32, \ + uint64_t *: __rte_bit_atomic_test_and_set64)(addr, nr, \ + memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically test and clear a bit in word. + * + * Atomically test and clear bit specified by @c nr in the word + * pointed to by @c addr to '0', with the memory ordering as specified + * with @c memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + * @return + * Returns true if the bit was set, and false otherwise. + */ +#define rte_bit_atomic_test_and_clear(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_test_and_clear32, \ + uint64_t *: __rte_bit_atomic_test_and_clear64)(addr, nr, \ + memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically test and assign a bit in word. + * + * Atomically test and assign bit specified by @c nr in the word + * pointed to by @c addr the value specified by @c value, with the + * memory ordering as specified with @c memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param value + * The new value of the bit - true for '1', or false for '0'. + * @param memory_order + * The memory order to use. See for details. + * @return + * Returns true if the bit was set, and false otherwise. + */ +#define rte_bit_atomic_test_and_assign(addr, nr, value, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_test_and_assign32, \ + uint64_t *: __rte_bit_atomic_test_and_assign64)(addr, nr, \ + value, \ + memory_order) + #define __RTE_GEN_BIT_TEST(family, fun, qualifier, size) \ __rte_experimental \ static inline bool \ @@ -479,6 +673,162 @@ __RTE_GEN_BIT_CLEAR(once_, clear, volatile, 64) __RTE_GEN_BIT_ASSIGN(once_, assign, volatile, 64) __RTE_GEN_BIT_FLIP(once_, flip, volatile, 64) +#define __RTE_GEN_BIT_ATOMIC_TEST(size) \ + __rte_experimental \ + static inline bool \ + __rte_bit_atomic_test ## size(const uint ## size ## _t *addr, \ + unsigned int nr, int memory_order) \ + { \ + RTE_ASSERT(nr < size); \ + \ + const RTE_ATOMIC(uint ## size ## _t) *a_addr = \ + (const RTE_ATOMIC(uint ## size ## _t) *)addr; \ + uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \ + return rte_atomic_load_explicit(a_addr, memory_order) & mask; \ + } + +#define __RTE_GEN_BIT_ATOMIC_SET(size) \ + __rte_experimental \ + static inline void \ + __rte_bit_atomic_set ## size(uint ## size ## _t *addr, \ + unsigned int nr, int memory_order) \ + { \ + RTE_ASSERT(nr < size); \ + \ + RTE_ATOMIC(uint ## size ## _t) *a_addr = \ + (RTE_ATOMIC(uint ## size ## _t) *)addr; \ + uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \ + rte_atomic_fetch_or_explicit(a_addr, mask, memory_order); \ + } + +#define __RTE_GEN_BIT_ATOMIC_CLEAR(size) \ + __rte_experimental \ + static inline void \ + __rte_bit_atomic_clear ## size(uint ## size ## _t *addr, \ + unsigned int nr, int memory_order) \ + { \ + RTE_ASSERT(nr < size); \ + \ + RTE_ATOMIC(uint ## size ## _t) *a_addr = \ + (RTE_ATOMIC(uint ## size ## _t) *)addr; \ + uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \ + rte_atomic_fetch_and_explicit(a_addr, ~mask, memory_order); \ + } + +#define __RTE_GEN_BIT_ATOMIC_ASSIGN(size) \ + __rte_experimental \ + static inline void \ + __rte_bit_atomic_assign ## size(uint ## size ## _t *addr, \ + unsigned int nr, bool value, \ + int memory_order) \ + { \ + if (value) \ + __rte_bit_atomic_set ## size(addr, nr, memory_order); \ + else \ + __rte_bit_atomic_clear ## size(addr, nr, \ + memory_order); \ + } + +#define __RTE_GEN_BIT_ATOMIC_TEST_AND_ASSIGN(size) \ + __rte_experimental \ + static inline bool \ + __rte_bit_atomic_test_and_assign ## size(uint ## size ## _t *addr, \ + unsigned int nr, \ + bool value, \ + int memory_order) \ + { \ + RTE_ASSERT(nr < size); \ + \ + RTE_ATOMIC(uint ## size ## _t) *a_addr = \ + (RTE_ATOMIC(uint ## size ## _t) *)addr; \ + uint ## size ## _t before; \ + uint ## size ## _t target; \ + \ + before = rte_atomic_load_explicit(a_addr, \ + rte_memory_order_relaxed); \ + \ + do { \ + target = before; \ + __rte_bit_assign ## size(&target, nr, value); \ + } while (!rte_atomic_compare_exchange_weak_explicit( \ + a_addr, &before, target, \ + rte_memory_order_relaxed, \ + memory_order)); \ + return __rte_bit_test ## size(&before, nr); \ + } + +#define __RTE_GEN_BIT_ATOMIC_FLIP(size) \ + __rte_experimental \ + static inline void \ + __rte_bit_atomic_flip ## size(uint ## size ## _t *addr, \ + unsigned int nr, int memory_order) \ + { \ + RTE_ASSERT(nr < size); \ + \ + RTE_ATOMIC(uint ## size ## _t) *a_addr = \ + (RTE_ATOMIC(uint ## size ## _t) *)addr; \ + uint ## size ## _t before; \ + uint ## size ## _t target; \ + \ + before = rte_atomic_load_explicit(a_addr, \ + rte_memory_order_relaxed); \ + \ + do { \ + target = before; \ + __rte_bit_flip ## size(&target, nr); \ + } while (!rte_atomic_compare_exchange_weak_explicit( \ + a_addr, &before, target, \ + rte_memory_order_relaxed, \ + memory_order)); \ + } + +#define __RTE_GEN_BIT_ATOMIC_OPS(size) \ + __RTE_GEN_BIT_ATOMIC_TEST(size) \ + __RTE_GEN_BIT_ATOMIC_SET(size) \ + __RTE_GEN_BIT_ATOMIC_CLEAR(size) \ + __RTE_GEN_BIT_ATOMIC_ASSIGN(size) \ + __RTE_GEN_BIT_ATOMIC_TEST_AND_ASSIGN(size) \ + __RTE_GEN_BIT_ATOMIC_FLIP(size) + +__RTE_GEN_BIT_ATOMIC_OPS(32) +__RTE_GEN_BIT_ATOMIC_OPS(64) + +__rte_experimental +static inline bool +__rte_bit_atomic_test_and_set32(uint32_t *addr, unsigned int nr, + int memory_order) +{ + return __rte_bit_atomic_test_and_assign32(addr, nr, true, + memory_order); +} + +__rte_experimental +static inline bool +__rte_bit_atomic_test_and_clear32(uint32_t *addr, unsigned int nr, + int memory_order) +{ + return __rte_bit_atomic_test_and_assign32(addr, nr, false, + memory_order); +} + +__rte_experimental +static inline bool +__rte_bit_atomic_test_and_set64(uint64_t *addr, unsigned int nr, + int memory_order) +{ + return __rte_bit_atomic_test_and_assign64(addr, nr, true, + memory_order); +} + +__rte_experimental +static inline bool +__rte_bit_atomic_test_and_clear64(uint64_t *addr, unsigned int nr, + int memory_order) +{ + return __rte_bit_atomic_test_and_assign64(addr, nr, false, + memory_order); +} + /*------------------------ 32-bit relaxed operations ------------------------*/ /** @@ -1180,6 +1530,14 @@ rte_log2_u64(uint64_t v) #undef rte_bit_once_assign #undef rte_bit_once_flip +#undef rte_bit_atomic_test +#undef rte_bit_atomic_set +#undef rte_bit_atomic_clear +#undef rte_bit_atomic_assign +#undef rte_bit_atomic_test_and_set +#undef rte_bit_atomic_test_and_clear +#undef rte_bit_atomic_test_and_assign + #define __RTE_BIT_OVERLOAD_SZ_2(fun, qualifier, size, arg1_type, arg1_name) \ static inline void \ rte_bit_ ## fun(qualifier uint ## size ## _t *addr, \ @@ -1223,6 +1581,59 @@ rte_log2_u64(uint64_t v) __RTE_BIT_OVERLOAD_SZ_3(fun, qualifier, 64, arg1_type, arg1_name, \ arg2_type, arg2_name) +#define __RTE_BIT_OVERLOAD_SZ_3R(fun, qualifier, size, ret_type, arg1_type, \ + arg1_name, arg2_type, arg2_name) \ + static inline ret_type \ + rte_bit_ ## fun(uint ## size ## _t *addr, arg1_type arg1_name, \ + arg2_type arg2_name) \ + { \ + return __rte_bit_ ## fun ## size(addr, arg1_name, arg2_name); \ + } + +#define __RTE_BIT_OVERLOAD_3R(fun, qualifier, ret_type, arg1_type, arg1_name, \ + arg2_type, arg2_name) \ + __RTE_BIT_OVERLOAD_SZ_3R(fun, qualifier, 32, ret_type, arg1_type, \ + arg1_name, arg2_type, arg2_name) \ + __RTE_BIT_OVERLOAD_SZ_3R(fun, qualifier, 64, ret_type, arg1_type, \ + arg1_name, arg2_type, arg2_name) + +#define __RTE_BIT_OVERLOAD_SZ_4(fun, qualifier, size, arg1_type, arg1_name, \ + arg2_type, arg2_name, arg3_type, arg3_name) \ + static inline void \ + rte_bit_ ## fun(uint ## size ## _t *addr, arg1_type arg1_name, \ + arg2_type arg2_name, arg3_type arg3_name) \ + { \ + __rte_bit_ ## fun ## size(addr, arg1_name, arg2_name, \ + arg3_name); \ + } + +#define __RTE_BIT_OVERLOAD_4(fun, qualifier, arg1_type, arg1_name, arg2_type, \ + arg2_name, arg3_type, arg3_name) \ + __RTE_BIT_OVERLOAD_SZ_4(fun, qualifier, 32, arg1_type, arg1_name, \ + arg2_type, arg2_name, arg3_type, arg3_name) \ + __RTE_BIT_OVERLOAD_SZ_4(fun, qualifier, 64, arg1_type, arg1_name, \ + arg2_type, arg2_name, arg3_type, arg3_name) + +#define __RTE_BIT_OVERLOAD_SZ_4R(fun, qualifier, size, ret_type, arg1_type, \ + arg1_name, arg2_type, arg2_name, arg3_type, \ + arg3_name) \ + static inline ret_type \ + rte_bit_ ## fun(uint ## size ## _t *addr, arg1_type arg1_name, \ + arg2_type arg2_name, arg3_type arg3_name) \ + { \ + return __rte_bit_ ## fun ## size(addr, arg1_name, arg2_name, \ + arg3_name); \ + } + +#define __RTE_BIT_OVERLOAD_4R(fun, qualifier, ret_type, arg1_type, arg1_name, \ + arg2_type, arg2_name, arg3_type, arg3_name) \ + __RTE_BIT_OVERLOAD_SZ_4R(fun, qualifier, 32, ret_type, arg1_type, \ + arg1_name, arg2_type, arg2_name, arg3_type, \ + arg3_name) \ + __RTE_BIT_OVERLOAD_SZ_4R(fun, qualifier, 64, ret_type, arg1_type, \ + arg1_name, arg2_type, arg2_name, arg3_type, \ + arg3_name) + __RTE_BIT_OVERLOAD_2R(test, const, bool, unsigned int, nr) __RTE_BIT_OVERLOAD_2(set,, unsigned int, nr) __RTE_BIT_OVERLOAD_2(clear,, unsigned int, nr) @@ -1235,6 +1646,20 @@ __RTE_BIT_OVERLOAD_2(once_clear, volatile, unsigned int, nr) __RTE_BIT_OVERLOAD_3(once_assign, volatile, unsigned int, nr, bool, value) __RTE_BIT_OVERLOAD_2(once_flip, volatile, unsigned int, nr) +__RTE_BIT_OVERLOAD_3R(atomic_test, const, bool, unsigned int, nr, + int, memory_order) +__RTE_BIT_OVERLOAD_3(atomic_set,, unsigned int, nr, int, memory_order) +__RTE_BIT_OVERLOAD_3(atomic_clear,, unsigned int, nr, int, memory_order) +__RTE_BIT_OVERLOAD_4(atomic_assign,, unsigned int, nr, bool, value, + int, memory_order) +__RTE_BIT_OVERLOAD_3(atomic_flip,, unsigned int, nr, int, memory_order) +__RTE_BIT_OVERLOAD_3R(atomic_test_and_set,, bool, unsigned int, nr, + int, memory_order) +__RTE_BIT_OVERLOAD_3R(atomic_test_and_clear,, bool, unsigned int, nr, + int, memory_order) +__RTE_BIT_OVERLOAD_4R(atomic_test_and_assign,, bool, unsigned int, nr, + bool, value, int, memory_order) + #endif #endif /* _RTE_BITOPS_H_ */ From patchwork Tue Apr 30 09:55:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Mattias_R=C3=B6nnblom?= X-Patchwork-Id: 139730 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 140CE43F3A; Tue, 30 Apr 2024 12:06:36 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 80E0A402E8; Tue, 30 Apr 2024 12:06:01 +0200 (CEST) Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2051.outbound.protection.outlook.com [40.107.21.51]) by mails.dpdk.org (Postfix) with ESMTP id 42601402C6 for ; Tue, 30 Apr 2024 12:05:57 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=W3zmAMy0t+jfWd/xSl0b9xEYKTZR27ZHQNw8YeHUyfIvATM/W2WNdWEIY0gqC2i7T2ph9zqb2mzEuAoRX7God4kNQeIrLoaUt34H0qWDo20yiCWBnPWTJ2obItbUjobJmGdPL3Np8wQ0XeAmcNtg4zy57HLV+OBDEPvig0urAzRq0jJQlHglDJXe/fW08MNSF+ipNybbqznFw/VTacQ0bN8jaTkaxaFbQ8cR02h/AXfnV1Y0nKK9rIfaoSgn76pAp7EQIOvvnJHcoddMWCfXhpVeLvPuIHGNJf/QaIOzyaMfWq2OpfsJcQwhMBx7z43ANI4IHMJ7sQ9NxQ5Kw3z5iQ== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Xbdd4PQDgBRni6OwWxtZoG89tGz9EEnJ4OO6YhM2tjU=; b=Zwb9/gFrnY+DuQDR5SNSKQ0VRJo0PIKUS9k8GUkXHe8mryu8b62zbIYJH3L5MQ+8W6fA7HcaWCPETixBAKrxJfwPFtju3qhCDFDcxN65VJseW5BZZvMicPlsjLwt/eEnxOycYGdHS6XO8wCk3dMV0X9vTIBnQ/CkMHdoDLYAdDxcKr6pWlYNsfYwbKAkhyh58UasVzjOnjkvXXPkwvow9Pm9/GbFNUM5+q3bnazhZX8uH2i2xdOhJMLSmYDovb2OIDTVRHo8vpQjeafQ8CtWx/hgrLKT1XF6vjEa9jb0HlPWTzEVkcIA/rM+ayG/cDi9ogYoj+4Tbb06bEjfCkPtBQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 192.176.1.74) smtp.rcpttodomain=dpdk.org smtp.mailfrom=ericsson.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=ericsson.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ericsson.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Xbdd4PQDgBRni6OwWxtZoG89tGz9EEnJ4OO6YhM2tjU=; b=l4j8K6jftGQDx4qaAwL3uqE00RmTQQcE6uOBGlqGgnJVVqPr8W3ez92f4FzqKDbsWrDLRjOC+pOUrLT1AZ73hlOqbFeXs+NN78GLaWJbB6velTvz9Ms0ho9bTA4k5ae4iyrnZ8ROglaD3PbB6cVNPKO3XDXa/hfcue7ur8YVEkv9ISJWXiQ8IS6M/TNTphQ+JKj5M51bbXa0mYcfS2h4yHZMlhfdJ8+l7ctZaRmjD7EfeHsabFMk/3YuLBY0tQvtDPCwydxgUs5CY1Os747dJQcAk/zbkBXcn5fxgxXxHwoAPNLizp7SkTOxoJGm6g379pqNyypW/tDuB7+i8e7Vpw== Received: from AM6P191CA0107.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::48) by DBAPR07MB6808.eurprd07.prod.outlook.com (2603:10a6:10:17f::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.36; Tue, 30 Apr 2024 10:05:55 +0000 Received: from AMS1EPF00000042.eurprd04.prod.outlook.com (2603:10a6:209:8a:cafe::74) by AM6P191CA0107.outlook.office365.com (2603:10a6:209:8a::48) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.36 via Frontend Transport; Tue, 30 Apr 2024 10:05:55 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 192.176.1.74) smtp.mailfrom=ericsson.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=ericsson.com; Received-SPF: Pass (protection.outlook.com: domain of ericsson.com designates 192.176.1.74 as permitted sender) receiver=protection.outlook.com; client-ip=192.176.1.74; helo=oa.msg.ericsson.com; pr=C Received: from oa.msg.ericsson.com (192.176.1.74) by AMS1EPF00000042.mail.protection.outlook.com (10.167.16.39) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7544.18 via Frontend Transport; Tue, 30 Apr 2024 10:05:55 +0000 Received: from seliicinfr00050.seli.gic.ericsson.se (153.88.142.248) by smtp-central.internal.ericsson.com (100.87.178.62) with Microsoft SMTP Server id 15.2.1544.9; Tue, 30 Apr 2024 12:05:54 +0200 Received: from breslau.. (seliicwb00002.seli.gic.ericsson.se [10.156.25.100]) by seliicinfr00050.seli.gic.ericsson.se (Postfix) with ESMTP id 5174D1C006A; Tue, 30 Apr 2024 12:05:54 +0200 (CEST) From: =?utf-8?q?Mattias_R=C3=B6nnblom?= To: CC: , Heng Wang , "Stephen Hemminger" , Tyler Retzlaff , =?utf-8?q?Morten_Br=C3=B8rup?= , =?utf-8?q?Mattia?= =?utf-8?q?s_R=C3=B6nnblom?= Subject: [RFC v4 5/6] eal: add atomic bit operations Date: Tue, 30 Apr 2024 11:55:22 +0200 Message-ID: <20240430095523.108688-6-mattias.ronnblom@ericsson.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240430095523.108688-1-mattias.ronnblom@ericsson.com> References: <20240429095138.106849-2-mattias.ronnblom@ericsson.com> <20240430095523.108688-1-mattias.ronnblom@ericsson.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AMS1EPF00000042:EE_|DBAPR07MB6808:EE_ X-MS-Office365-Filtering-Correlation-Id: 12c161ac-c0a4-4acc-9249-08dc68fd201e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230031|1800799015|82310400014|36860700004|376005; X-Microsoft-Antispam-Message-Info: =?utf-8?q?M9rij9+hnhnh1v1fRMiXY7vBIeiIZ3+?= =?utf-8?q?/Oer5XXdvSVFABH5Wf8xgEPwi8YGl1eOp5c86AECoPFg0CkSzX8qP6RoB9yuVHyos?= =?utf-8?q?WvJHauWTboGfvFa6VdGvc5sBPKdXbvOYDOZIzQ6Luezao/H610zHEqnFNjl3b5+4n?= =?utf-8?q?S9lfqabyi2w3W3E8ys2fSiV+iw1AFOs/PzsmCT78seR7eL4HUWkvVmAEkA76AIEKF?= =?utf-8?q?jDYRQ5M412ATpzAQ6Vlq6Zcg4+Dgxmh6OM5eL22FHDFwywBBf2Rab9ru70DiQVoMX?= =?utf-8?q?HM4xHRJmnsPOnx7aFXBaaDN1AY9nOpaXwqv6R/y5IfNYUp1sIstAhg8XEIVgFXt3o?= =?utf-8?q?gu7CZmD/iPn/e4KwsyvGaYenNBDBEjlTtDjCSxZzEHhkZ4/erVxkD8Ir+SwE4AL23?= =?utf-8?q?N7RK9JeM5UbXAQatj1ZoWg1yWVwbGjCoZBQlJdUBaEan1D5bSHao1z8tpfq8ONe7f?= =?utf-8?q?WMlZZkIuyJk3mGplpc13t1BQdYuymbzYJ4xU8CDigTXp9UyVGkW1OBNb5HDz1QXpk?= =?utf-8?q?j/YW9uhuG0jCzvIgmJnBW9dmsOMBSLbtOD6nRy9AHReOBCKsx6/Urx6R0CRVlov4T?= =?utf-8?q?dlOeTPqf5GPK2dbDBZc8fIiWkHMDBlhIzvzr127DT31oEmo2qHAZZWjJtQ8ToD/XS?= =?utf-8?q?/lrrF7FXRMyZn3bK0j7rGPNORfIOC7s5yydf5zlmqvB2SkG0BV4qu5cwVs1/9nbk8?= =?utf-8?q?orq+n9d+qNt5vtg06mV+incVll/KeOrvQsgVouDmhmEnxeg0T2dvsOKbLi7MTRjYn?= =?utf-8?q?XM7m6kEgXWtyXFUa3ghWdlglBGXuS/996tx7CApzCIDC8uGtlATZ6QrqMaR5AE2JL?= =?utf-8?q?GqIKTXgc+LY9AS0+LskV5HoTamaEDnpKgtDbq/omrDH35qnHKo5MsAvPgR5qGQrSm?= =?utf-8?q?VB33TaoIFS7krioRfiV/7o3isOaLZU2S1h3xZRcZvGQBFg8HlW7fR3l/UK8bJdE23?= =?utf-8?q?H/VP13SHm2H37GdUFll+erBrCvIWJm+ebf9OhE8IwDhju+da5aGb0VqiIo612L+7P?= =?utf-8?q?J1OJYQLv8msooImIH+ZVDaf6XmE5zT8gFY8HQCS76o/xlUw8ipjQlq40j2Y2i5lA1?= =?utf-8?q?IBdAsj0xgDL1e+KRcKEpoE68s7MZyN4/UpSrlSL0+I/3C1Wn+BgljgkcdZm3XEwAt?= =?utf-8?q?9jP6Rwi8F71epW3npd19PX2O0JEDkilSJ2wLDXhz02JWAJ9tynzNNz0XsYUZAwg9+?= =?utf-8?q?dfzi22bLYKVactehhfu4xxhbrJ3O8+A0mxi0v29nEc/JWr6BtYIL/inF7nob76Xq2?= =?utf-8?q?z7XqNaOMjwyEyL4k90xyOG2hQN60BMS4EKwfeEvkuQlpkKN6h9v1WCjEghom2+/YM?= =?utf-8?q?t/YNE6ukfbp4?= X-Forefront-Antispam-Report: CIP:192.176.1.74; CTRY:SE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:oa.msg.ericsson.com; PTR:office365.se.ericsson.net; CAT:NONE; SFS:(13230031)(1800799015)(82310400014)(36860700004)(376005); DIR:OUT; SFP:1101; X-OriginatorOrg: ericsson.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Apr 2024 10:05:55.4188 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 12c161ac-c0a4-4acc-9249-08dc68fd201e X-MS-Exchange-CrossTenant-Id: 92e84ceb-fbfd-47ab-be52-080c6b87953f X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=92e84ceb-fbfd-47ab-be52-080c6b87953f; Ip=[192.176.1.74]; Helo=[oa.msg.ericsson.com] X-MS-Exchange-CrossTenant-AuthSource: AMS1EPF00000042.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAPR07MB6808 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 Add atomic bit test/set/clear/assign and test-and-set/clear functions. All atomic bit functions allow (and indeed, require) the caller to specify a memory order. RFC v4: * Add atomic bit flip. * Mark macro-generated private functions experimental. RFC v3: * Work around lack of C++ support for _Generic (Tyler Retzlaff). RFC v2: o Add rte_bit_atomic_test_and_assign() (for consistency). o Fix bugs in rte_bit_atomic_test_and_[set|clear](). o Use to support MSVC. Signed-off-by: Mattias Rönnblom Acked-by: Morten Brørup Acked-by: Tyler Retzlaff --- lib/eal/include/rte_bitops.h | 194 +++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index abfe96d531..f014bd913e 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -589,6 +589,199 @@ extern "C" { value, \ memory_order) +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Test if a particular bit in a word is set with a particular memory + * order. + * + * Test a bit with the resulting memory load ordered as per the + * specified memory order. + * + * @param addr + * A pointer to the word to query. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + * @return + * Returns true if the bit is set, and false otherwise. + */ +#define rte_bit_atomic_test(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_test32, \ + uint64_t *: __rte_bit_atomic_test64)(addr, nr, memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically set bit in word. + * + * Atomically set bit specified by @c nr in the word pointed to by @c + * addr to '1', with the memory ordering as specified by @c + * memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + */ +#define rte_bit_atomic_set(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_set32, \ + uint64_t *: __rte_bit_atomic_set64)(addr, nr, memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically clear bit in word. + * + * Atomically set bit specified by @c nr in the word pointed to by @c + * addr to '0', with the memory ordering as specified by @c + * memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + */ +#define rte_bit_atomic_clear(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_clear32, \ + uint64_t *: __rte_bit_atomic_clear64)(addr, nr, memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically assign a value to bit in word. + * + * Atomically set bit specified by @c nr in the word pointed to by @c + * addr to the value indicated by @c value, with the memory ordering + * as specified with @c memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param value + * The new value of the bit - true for '1', or false for '0'. + * @param memory_order + * The memory order to use. See for details. + */ +#define rte_bit_atomic_assign(addr, nr, value, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_assign32, \ + uint64_t *: __rte_bit_atomic_assign64)(addr, nr, value, \ + memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically flip bit in word. + * + * Atomically negate the value of the bit specified by @c nr in the + * word pointed to by @c addr to the value indicated by @c value, with + * the memory ordering as specified with @c memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + */ +#define rte_bit_atomic_flip(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_flip32, \ + uint64_t *: __rte_bit_atomic_flip64)(addr, nr, memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically test and set a bit in word. + * + * Atomically test and set bit specified by @c nr in the word pointed + * to by @c addr to '1', with the memory ordering as specified with @c + * memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + * @return + * Returns true if the bit was set, and false otherwise. + */ +#define rte_bit_atomic_test_and_set(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_test_and_set32, \ + uint64_t *: __rte_bit_atomic_test_and_set64)(addr, nr, \ + memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically test and clear a bit in word. + * + * Atomically test and clear bit specified by @c nr in the word + * pointed to by @c addr to '0', with the memory ordering as specified + * with @c memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param memory_order + * The memory order to use. See for details. + * @return + * Returns true if the bit was set, and false otherwise. + */ +#define rte_bit_atomic_test_and_clear(addr, nr, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_test_and_clear32, \ + uint64_t *: __rte_bit_atomic_test_and_clear64)(addr, nr, \ + memory_order) + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically test and assign a bit in word. + * + * Atomically test and assign bit specified by @c nr in the word + * pointed to by @c addr the value specified by @c value, with the + * memory ordering as specified with @c memory_order. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param value + * The new value of the bit - true for '1', or false for '0'. + * @param memory_order + * The memory order to use. See for details. + * @return + * Returns true if the bit was set, and false otherwise. + */ +#define rte_bit_atomic_test_and_assign(addr, nr, value, memory_order) \ + _Generic((addr), \ + uint32_t *: __rte_bit_atomic_test_and_assign32, \ + uint64_t *: __rte_bit_atomic_test_and_assign64)(addr, nr, \ + value, \ + memory_order) + #define __RTE_GEN_BIT_TEST(family, fun, qualifier, size) \ __rte_experimental \ static inline bool \ @@ -1534,6 +1727,7 @@ rte_log2_u64(uint64_t v) #undef rte_bit_atomic_set #undef rte_bit_atomic_clear #undef rte_bit_atomic_assign +#undef rte_bit_atomic_flip #undef rte_bit_atomic_test_and_set #undef rte_bit_atomic_test_and_clear #undef rte_bit_atomic_test_and_assign From patchwork Tue Apr 30 09:55:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Mattias_R=C3=B6nnblom?= X-Patchwork-Id: 139731 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0340B43F3A; Tue, 30 Apr 2024 12:06:44 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A1D01402F0; Tue, 30 Apr 2024 12:06:02 +0200 (CEST) Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2061.outbound.protection.outlook.com [40.107.104.61]) by mails.dpdk.org (Postfix) with ESMTP id 33FBA402CC for ; Tue, 30 Apr 2024 12:05:58 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Lza+C1LhbonjnCZ10BVzklX6ceS/wkoloV8oqH03u79IIbBghJa8Hi7IFgf1HlJK8T5SelwnaxSUYdgNUf7CN7PCr/HrnJO/YfEOFSpyXuD/ANGSF/wnYK3EkrYeAgdSEE0XwsUHnTg1ARjR+QGMfX6Ry5GYh8NueARbx/5VFphKSze+fYNguVzGxW5M5Gmi6N7W2oX2vU0kMGxdF1HtSQDKpAol5w0MblsDNL6pMGjdY/90DOZC6PaRD9V4E2obx1Q6CmuC23aXl+iVjqYOIFHoyIAwoJ05Ni/zZb3cuM2BwA+LO+H4+DMjX3pNLGooEAK4njuJui0z6kPdrZihjA== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=0RozYixkAPZQJvhse9bVeHJcmbJm//9Hq35KyszlGRk=; b=YkA2E1LnZDHWjTlEhJ5FWRb2iX7MBndXk0XNMUYUc7X7KNP5bE5L6jLZ0jiBdA/nuevlsIkBYfYvCjLUWetUXYWyanUeD7VfwsBhk5yXHC17BWFGhZuHdYD+wbmYqzt2Qn6046onZ1ySUFO6l2E64/Jm3Uf1H6i5BtFfo4t4TESTroZ+PLE5ItHWNQ/ZufWu9q7p8nwoTGag1QP08Q76MneB1FfCvhIDhm0Rm0fj80CPKE824fPD+K/Wk+L61U8IIKccIhL6sp4d4YpAsH3Z3z/96xfl9VIjiAm39mouIrOAXtF5l5DgeVtMv8dWHqS0M4caxdFY9MHBnDK8PVpSig== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 192.176.1.74) smtp.rcpttodomain=dpdk.org smtp.mailfrom=ericsson.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=ericsson.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ericsson.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=0RozYixkAPZQJvhse9bVeHJcmbJm//9Hq35KyszlGRk=; b=YS+f29YKlk0JYUw4gpGpmX1+IyU2AAX1ev0XyDl++q5llRtMU3k1gLLYTq1qPSWTTJLO2nny+NfWAeFeSivTFfnsx3DIzlZi2Eh87HwvHMZKABfqLdx+1sFyxhP2VcOY/ROYLKtKb4KPSNblsu3ONuklAhhAPu6bi/oG5aGZ+jGL8Pkg3pYs2OCjWwWq2Tps7VS/j3VCrR5DhWV6hiVZDqnnSDtXC58Q1rT2wUk1gJF8XBLJoM6gilvjRew3mnZTaXC5zL7rS6pc5pp8tYcTnnrvqGmIm8oK8c4sv9pY6emRJxrPMez1HyGBq00q2lzEIqmsMSZ5ihrVGU4+nG/tkA== Received: from DUZP191CA0041.EURP191.PROD.OUTLOOK.COM (2603:10a6:10:4f8::20) by DBAPR07MB6502.eurprd07.prod.outlook.com (2603:10a6:10:188::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.36; Tue, 30 Apr 2024 10:05:57 +0000 Received: from DB1PEPF000509F6.eurprd02.prod.outlook.com (2603:10a6:10:4f8:cafe::cf) by DUZP191CA0041.outlook.office365.com (2603:10a6:10:4f8::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7519.36 via Frontend Transport; Tue, 30 Apr 2024 10:05:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 192.176.1.74) smtp.mailfrom=ericsson.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=ericsson.com; Received-SPF: Pass (protection.outlook.com: domain of ericsson.com designates 192.176.1.74 as permitted sender) receiver=protection.outlook.com; client-ip=192.176.1.74; helo=oa.msg.ericsson.com; pr=C Received: from oa.msg.ericsson.com (192.176.1.74) by DB1PEPF000509F6.mail.protection.outlook.com (10.167.242.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7544.18 via Frontend Transport; Tue, 30 Apr 2024 10:05:56 +0000 Received: from seliicinfr00050.seli.gic.ericsson.se (153.88.142.248) by smtp-central.internal.ericsson.com (100.87.178.66) with Microsoft SMTP Server id 15.2.1544.9; Tue, 30 Apr 2024 12:05:55 +0200 Received: from breslau.. (seliicwb00002.seli.gic.ericsson.se [10.156.25.100]) by seliicinfr00050.seli.gic.ericsson.se (Postfix) with ESMTP id DCCAF1C006A; Tue, 30 Apr 2024 12:05:54 +0200 (CEST) From: =?utf-8?q?Mattias_R=C3=B6nnblom?= To: CC: , Heng Wang , "Stephen Hemminger" , Tyler Retzlaff , =?utf-8?q?Morten_Br=C3=B8rup?= , =?utf-8?q?Mattia?= =?utf-8?q?s_R=C3=B6nnblom?= Subject: [RFC v4 6/6] eal: add unit tests for atomic bit access functions Date: Tue, 30 Apr 2024 11:55:23 +0200 Message-ID: <20240430095523.108688-7-mattias.ronnblom@ericsson.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240430095523.108688-1-mattias.ronnblom@ericsson.com> References: <20240429095138.106849-2-mattias.ronnblom@ericsson.com> <20240430095523.108688-1-mattias.ronnblom@ericsson.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DB1PEPF000509F6:EE_|DBAPR07MB6502:EE_ X-MS-Office365-Filtering-Correlation-Id: 92a26675-b076-43d7-e2c8-08dc68fd2106 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230031|1800799015|36860700004|376005|82310400014; X-Microsoft-Antispam-Message-Info: =?utf-8?q?O8H39IEw4TP6ESn+0horXLGs1mzT9u7?= =?utf-8?q?xmdwenQzdylxOcUj6p4MiYc0WxjqX+ifIhIcxg0Sq3rA6yQUsp96B3p1gckurOCs3?= =?utf-8?q?lPUnaG4ViWAMoZNVSCz+lVI50+6ujnUXOKYVuPZnwc/moqoLJAxbX28rcquJwF3lj?= =?utf-8?q?nuvg6cLM1ymrufzuly35bHiTULklsGnhWJ7QAVeF3u5xinwC/eG0Y5YlJfhGyeuyy?= =?utf-8?q?66ki0FdxlV+HJFmTHoaljL4WoT4nDvXL0bCXuEKvjYFyHVQGqr/+goKuUbPtzs3gq?= =?utf-8?q?KQKMohKACy1C+7cCgefuqdnsc/TcKJBV91exqTPwVPGktAFJMghFdtX9s0lGqLbCF?= =?utf-8?q?04GvDQ/3bMe/qGfs4VR+o5Y0CItYbE0ewxhHq7Axpb/dEdCiPvP3eZ7awXKmv05Xs?= =?utf-8?q?v9kDlily7rpA3xatyb95E5M5MPOJGdfG2znYNQSRTfbqP3AK9/sXKkJwQGuLwnUcm?= =?utf-8?q?HeR/G6zw/e7C0ngjp64RwCuSAcUt60QX8V0OKUfErq7WcAYDEQuzeKWzObTBhQyEy?= =?utf-8?q?YiHZNY5va/pdOr+CvwJze0uOMKomnKCePrWInPMzILNEu8+ZVMl7LPA+CY2IbFmFi?= =?utf-8?q?qXhwre7IEkY/VGSWFUtL17JVdoNWvu3tQxyM58NqaECObJSP0NgR8qjbCqcYa/81l?= =?utf-8?q?75g5G6akVNYoSuq9+3cDm5F0M7azEef40kTaxe7YtkT1Ut8/CelIN4+wUU2yiLzga?= =?utf-8?q?jZg9+ULhrEB83Fb+fp471O9ZlWKEG4aMjN52hfJN0BHXu2tGUsBS2fHuTD6sPLCw3?= =?utf-8?q?6SQHIECve4rbuTuyw0mJZrbXDfHX9A1kNEf8T5JwHlGvRzpe8KQ9d5PD7tULIYz5j?= =?utf-8?q?Jb3YgfXrZbnuxGosgPqJNVige+5CfeZKIC7Pli21YoPz1cViRz3+sgYBu0m5JXZHj?= =?utf-8?q?xK+qiQus7UHLDnFPsX7z984iFTusM2tnHrzF8PAIYh6klLnTbpcmxy7hwbTbT+gEP?= =?utf-8?q?ZLdpAJ/AJaiASPa+uhZl+HCLFBx3YGEZVdVoWK0aoWoQQvYBdSfuyOvfX8H7IuLlw?= =?utf-8?q?ch7TRExcLja2rB29nZlOPF9r13YEg6PC9gPSYSC0T0WC1bj48Gl3CuEQQOuYzTuIR?= =?utf-8?q?TdXa5AJI3MDs+hZYnS5DsRM76LoECNEN+labp43n0OOtr9yseq7nAuCxkkBlEzhgq?= =?utf-8?q?KAj9vQpRQlPtWNADcNux2JzxipYANqhg0CQHC9L6QXJK4L20vqzQMnmOEm0rfq0Cn?= =?utf-8?q?t2XyzCJRtBmhNocR9irWFy01ASq+nrI/Mdfw/8qFmrAhTSMc3sqRC14eUV5e8hwOE?= =?utf-8?q?mc5Dph/5LitQthAqioOJd/ukDL9uduafTwMtA072frt+xmANxa5xDX5zZyUqmfbKG?= =?utf-8?q?Zn4VoYfKIOZ9?= X-Forefront-Antispam-Report: CIP:192.176.1.74; CTRY:SE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:oa.msg.ericsson.com; PTR:office365.se.ericsson.net; CAT:NONE; SFS:(13230031)(1800799015)(36860700004)(376005)(82310400014); DIR:OUT; SFP:1101; X-OriginatorOrg: ericsson.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Apr 2024 10:05:56.8944 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 92a26675-b076-43d7-e2c8-08dc68fd2106 X-MS-Exchange-CrossTenant-Id: 92e84ceb-fbfd-47ab-be52-080c6b87953f X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=92e84ceb-fbfd-47ab-be52-080c6b87953f; Ip=[192.176.1.74]; Helo=[oa.msg.ericsson.com] X-MS-Exchange-CrossTenant-AuthSource: DB1PEPF000509F6.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAPR07MB6502 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 Extend bitops tests to cover the rte_bit_atomic_[set|clear|assign|test|test_and_[set|clear|assign]]() family of functions. RFC v4: * Add atomicity test for atomic bit flip. RFC v3: * Rename variable 'main' to make ICC happy. Signed-off-by: Mattias Rönnblom Acked-by: Morten Brørup Acked-by: Tyler Retzlaff --- app/test/test_bitops.c | 315 ++++++++++++++++++++++++++++++++++- lib/eal/include/rte_bitops.h | 1 - 2 files changed, 314 insertions(+), 2 deletions(-) diff --git a/app/test/test_bitops.c b/app/test/test_bitops.c index 615ec6e563..abc07e8caf 100644 --- a/app/test/test_bitops.c +++ b/app/test/test_bitops.c @@ -3,10 +3,13 @@ * Copyright(c) 2024 Ericsson AB */ +#include #include -#include #include +#include +#include +#include #include #include "test.h" @@ -64,6 +67,304 @@ GEN_TEST_BIT_ACCESS(test_bit_once_access64, rte_bit_once_set, rte_bit_once_clear, rte_bit_once_assign, rte_bit_once_flip, rte_bit_once_test, 64) +#define bit_atomic_set(addr, nr) \ + rte_bit_atomic_set(addr, nr, rte_memory_order_relaxed) + +#define bit_atomic_clear(addr, nr) \ + rte_bit_atomic_clear(addr, nr, rte_memory_order_relaxed) + +#define bit_atomic_assign(addr, nr, value) \ + rte_bit_atomic_assign(addr, nr, value, rte_memory_order_relaxed) + +#define bit_atomic_flip(addr, nr) \ + rte_bit_atomic_flip(addr, nr, rte_memory_order_relaxed) + +#define bit_atomic_test(addr, nr) \ + rte_bit_atomic_test(addr, nr, rte_memory_order_relaxed) + +GEN_TEST_BIT_ACCESS(test_bit_atomic_access32, bit_atomic_set, + bit_atomic_clear, bit_atomic_assign, + bit_atomic_flip, bit_atomic_test, 32) + +GEN_TEST_BIT_ACCESS(test_bit_atomic_access64, bit_atomic_set, + bit_atomic_clear, bit_atomic_assign, + bit_atomic_flip, bit_atomic_test, 64) + +#define PARALLEL_TEST_RUNTIME 0.25 + +#define GEN_TEST_BIT_PARALLEL_ASSIGN(size) \ + \ + struct parallel_access_lcore ## size \ + { \ + unsigned int bit; \ + uint ## size ##_t *word; \ + bool failed; \ + }; \ + \ + static int \ + run_parallel_assign ## size(void *arg) \ + { \ + struct parallel_access_lcore ## size *lcore = arg; \ + uint64_t deadline = rte_get_timer_cycles() + \ + PARALLEL_TEST_RUNTIME * rte_get_timer_hz(); \ + bool value = false; \ + \ + do { \ + bool new_value = rte_rand() & 1; \ + bool use_test_and_modify = rte_rand() & 1; \ + bool use_assign = rte_rand() & 1; \ + \ + if (rte_bit_atomic_test(lcore->word, lcore->bit, \ + rte_memory_order_relaxed) != value) { \ + lcore->failed = true; \ + break; \ + } \ + \ + if (use_test_and_modify) { \ + bool old_value; \ + if (use_assign) \ + old_value = rte_bit_atomic_test_and_assign( \ + lcore->word, lcore->bit, new_value, \ + rte_memory_order_relaxed); \ + else { \ + old_value = new_value ? \ + rte_bit_atomic_test_and_set( \ + lcore->word, lcore->bit, \ + rte_memory_order_relaxed) : \ + rte_bit_atomic_test_and_clear( \ + lcore->word, lcore->bit, \ + rte_memory_order_relaxed); \ + } \ + if (old_value != value) { \ + lcore->failed = true; \ + break; \ + } \ + } else { \ + if (use_assign) \ + rte_bit_atomic_assign(lcore->word, lcore->bit, \ + new_value, \ + rte_memory_order_relaxed); \ + else { \ + if (new_value) \ + rte_bit_atomic_set( \ + lcore->word, lcore->bit, \ + rte_memory_order_relaxed); \ + else \ + rte_bit_atomic_clear( \ + lcore->word, lcore->bit, \ + rte_memory_order_relaxed); \ + } \ + } \ + \ + value = new_value; \ + } while (rte_get_timer_cycles() < deadline); \ + \ + return 0; \ + } \ + \ + static int \ + test_bit_atomic_parallel_assign ## size(void) \ + { \ + unsigned int worker_lcore_id; \ + uint ## size ## _t word = 0; \ + struct parallel_access_lcore ## size lmain = { \ + .word = &word \ + }; \ + struct parallel_access_lcore ## size lworker = { \ + .word = &word \ + }; \ + \ + if (rte_lcore_count() < 2) { \ + printf("Need multiple cores to run parallel test.\n"); \ + return TEST_SKIPPED; \ + } \ + \ + worker_lcore_id = rte_get_next_lcore(-1, 1, 0); \ + \ + lmain.bit = rte_rand_max(size); \ + do { \ + lworker.bit = rte_rand_max(size); \ + } while (lworker.bit == lmain.bit); \ + \ + int rc = rte_eal_remote_launch(run_parallel_assign ## size, \ + &lworker, worker_lcore_id); \ + TEST_ASSERT(rc == 0, "Worker thread launch failed"); \ + \ + run_parallel_assign ## size(&lmain); \ + \ + rte_eal_mp_wait_lcore(); \ + \ + TEST_ASSERT(!lmain.failed, "Main lcore atomic access failed"); \ + TEST_ASSERT(!lworker.failed, "Worker lcore atomic access " \ + "failed"); \ + \ + return TEST_SUCCESS; \ + } + +GEN_TEST_BIT_PARALLEL_ASSIGN(32) +GEN_TEST_BIT_PARALLEL_ASSIGN(64) + +#define GEN_TEST_BIT_PARALLEL_TEST_AND_MODIFY(size) \ + \ + struct parallel_test_and_set_lcore ## size \ + { \ + uint ## size ##_t *word; \ + unsigned int bit; \ + uint64_t flips; \ + }; \ + \ + static int \ + run_parallel_test_and_modify ## size(void *arg) \ + { \ + struct parallel_test_and_set_lcore ## size *lcore = arg; \ + uint64_t deadline = rte_get_timer_cycles() + \ + PARALLEL_TEST_RUNTIME * rte_get_timer_hz(); \ + do { \ + bool old_value; \ + bool new_value = rte_rand() & 1; \ + bool use_assign = rte_rand() & 1; \ + \ + if (use_assign) \ + old_value = rte_bit_atomic_test_and_assign( \ + lcore->word, lcore->bit, new_value, \ + rte_memory_order_relaxed); \ + else \ + old_value = new_value ? \ + rte_bit_atomic_test_and_set( \ + lcore->word, lcore->bit, \ + rte_memory_order_relaxed) : \ + rte_bit_atomic_test_and_clear( \ + lcore->word, lcore->bit, \ + rte_memory_order_relaxed); \ + if (old_value != new_value) \ + lcore->flips++; \ + } while (rte_get_timer_cycles() < deadline); \ + \ + return 0; \ + } \ + \ + static int \ + test_bit_atomic_parallel_test_and_modify ## size(void) \ + { \ + unsigned int worker_lcore_id; \ + uint ## size ## _t word = 0; \ + unsigned int bit = rte_rand_max(size); \ + struct parallel_test_and_set_lcore ## size lmain = { \ + .word = &word, \ + .bit = bit \ + }; \ + struct parallel_test_and_set_lcore ## size lworker = { \ + .word = &word, \ + .bit = bit \ + }; \ + \ + if (rte_lcore_count() < 2) { \ + printf("Need multiple cores to run parallel test.\n"); \ + return TEST_SKIPPED; \ + } \ + \ + worker_lcore_id = rte_get_next_lcore(-1, 1, 0); \ + \ + int rc = rte_eal_remote_launch(run_parallel_test_and_modify ## size, \ + &lworker, worker_lcore_id); \ + TEST_ASSERT(rc == 0, "Worker thread launch failed"); \ + \ + run_parallel_test_and_modify ## size(&lmain); \ + \ + rte_eal_mp_wait_lcore(); \ + \ + uint64_t total_flips = lmain.flips + lworker.flips; \ + bool expected_value = total_flips % 2; \ + \ + TEST_ASSERT(expected_value == rte_bit_test(&word, bit), \ + "After %"PRId64" flips, the bit value " \ + "should be %d", total_flips, expected_value); \ + \ + uint64_t expected_word = 0; \ + rte_bit_assign(&expected_word, bit, expected_value); \ + \ + TEST_ASSERT(expected_word == word, "Untouched bits have " \ + "changed value"); \ + \ + return TEST_SUCCESS; \ + } + +GEN_TEST_BIT_PARALLEL_TEST_AND_MODIFY(32) +GEN_TEST_BIT_PARALLEL_TEST_AND_MODIFY(64) + +#define GEN_TEST_BIT_PARALLEL_FLIP(size) \ + \ + struct parallel_flip_lcore ## size \ + { \ + uint ## size ##_t *word; \ + unsigned int bit; \ + uint64_t flips; \ + }; \ + \ + static int \ + run_parallel_flip ## size(void *arg) \ + { \ + struct parallel_flip_lcore ## size *lcore = arg; \ + uint64_t deadline = rte_get_timer_cycles() + \ + PARALLEL_TEST_RUNTIME * rte_get_timer_hz(); \ + do { \ + rte_bit_atomic_flip(lcore->word, lcore->bit, \ + rte_memory_order_relaxed); \ + lcore->flips++; \ + } while (rte_get_timer_cycles() < deadline); \ + \ + return 0; \ + } \ + \ + static int \ + test_bit_atomic_parallel_flip ## size(void) \ + { \ + unsigned int worker_lcore_id; \ + uint ## size ## _t word = 0; \ + unsigned int bit = rte_rand_max(size); \ + struct parallel_flip_lcore ## size lmain = { \ + .word = &word, \ + .bit = bit \ + }; \ + struct parallel_flip_lcore ## size lworker = { \ + .word = &word, \ + .bit = bit \ + }; \ + \ + if (rte_lcore_count() < 2) { \ + printf("Need multiple cores to run parallel test.\n"); \ + return TEST_SKIPPED; \ + } \ + \ + worker_lcore_id = rte_get_next_lcore(-1, 1, 0); \ + \ + int rc = rte_eal_remote_launch(run_parallel_flip ## size, \ + &lworker, worker_lcore_id); \ + TEST_ASSERT(rc == 0, "Worker thread launch failed"); \ + \ + run_parallel_flip ## size(&lmain); \ + \ + rte_eal_mp_wait_lcore(); \ + \ + uint64_t total_flips = lmain.flips + lworker.flips; \ + bool expected_value = total_flips % 2; \ + \ + TEST_ASSERT(expected_value == rte_bit_test(&word, bit), \ + "After %"PRId64" flips, the bit value " \ + "should be %d", total_flips, expected_value); \ + \ + uint64_t expected_word = 0; \ + rte_bit_assign(&expected_word, bit, expected_value); \ + \ + TEST_ASSERT(expected_word == word, "Untouched bits have " \ + "changed value"); \ + \ + return TEST_SUCCESS; \ + } + +GEN_TEST_BIT_PARALLEL_FLIP(32) +GEN_TEST_BIT_PARALLEL_FLIP(64) + static uint32_t val32; static uint64_t val64; @@ -182,6 +483,18 @@ static struct unit_test_suite test_suite = { TEST_CASE(test_bit_access64), TEST_CASE(test_bit_once_access32), TEST_CASE(test_bit_once_access64), + TEST_CASE(test_bit_access32), + TEST_CASE(test_bit_access64), + TEST_CASE(test_bit_once_access32), + TEST_CASE(test_bit_once_access64), + TEST_CASE(test_bit_atomic_access32), + TEST_CASE(test_bit_atomic_access64), + TEST_CASE(test_bit_atomic_parallel_assign32), + TEST_CASE(test_bit_atomic_parallel_assign64), + TEST_CASE(test_bit_atomic_parallel_test_and_modify32), + TEST_CASE(test_bit_atomic_parallel_test_and_modify64), + TEST_CASE(test_bit_atomic_parallel_flip32), + TEST_CASE(test_bit_atomic_parallel_flip64), TEST_CASE(test_bit_relaxed_set), TEST_CASE(test_bit_relaxed_clear), TEST_CASE(test_bit_relaxed_test_set_clear), diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index f014bd913e..fb771c6dfc 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -560,7 +560,6 @@ extern "C" { uint32_t *: __rte_bit_atomic_test_and_clear32, \ uint64_t *: __rte_bit_atomic_test_and_clear64)(addr, nr, \ memory_order) - /** * @warning * @b EXPERIMENTAL: this API may change without prior notice.