From patchwork Tue Mar 3 17:59:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 66219 X-Patchwork-Delegate: ajit.khaparde@broadcom.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7DD9BA0571; Tue, 3 Mar 2020 18:59:52 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 03F811C00E; Tue, 3 Mar 2020 18:59:45 +0100 (CET) Received: from mail-pf1-f194.google.com (mail-pf1-f194.google.com [209.85.210.194]) by dpdk.org (Postfix) with ESMTP id AC71E1BFF4 for ; Tue, 3 Mar 2020 18:59:43 +0100 (CET) Received: by mail-pf1-f194.google.com with SMTP id 2so1830000pfg.12 for ; Tue, 03 Mar 2020 09:59:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hTbR+MUCuQl/XjF9vP0peDzMe488+txf/Crskfsat+w=; b=rWnj2Qi2n/bFjMoFmr2MqPqa27wEu93lFDnvoNJAnXy3IvogRYrRtOKI5Kjyaa/lNb JwmgaCXyyZTJGNr9JCmx25BjnM4bKvram200hHEP/+7Fhw4m9d9wSb6NmG4MtDSEDwga E4ZjwUoTzMv+2tdJL84YDBsqbiQbleY3iYFe/M7LjHHpfk/V6OifFw2jXKSG1n1k3PrV tjcerweIQARxAxejxLzyA9SPebZlLT6+e+HVqxeh32LxqgQDmRMwXTRdGTWLWGmR7R8B oVlrkaXoMXTN7LY2AV680lSoEb3tifnznyicwkrdZPsWBSSuv3SNa963qe7z+LOnr4uy 076A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hTbR+MUCuQl/XjF9vP0peDzMe488+txf/Crskfsat+w=; b=ncXg7cDw2VQ4sbZYFHc7rLxMY18lCsnUfykKJMpoZ/BajfI/SnWkEXXhEsLfddaH/r TmUQt/XINin0WMyTkiSaCHaQxNeFWBJ0fYJAKuQyZPSluj5Uw1ittVe2rcc595d1cGXb Vf1dFDkpmh9eyT2xoaU1QSvPh0yLn1c3ByqN/WVrwW4XDR4zWEsiyIC4SWxXkWJYB9pU xaN6xagMvybtCkYd+VyUwm137RTkPHSJZHohS2RGCePRVXS1XCqVv1YWNH5DpVFgROp8 0DQmBQJ8mUEejp5BMcginWM+2CNTWs+ze/ebrgI7incK9cxnq/j5Raiso5BYaS6ZgSr3 BVnA== X-Gm-Message-State: ANhLgQ3Ss6BCjPw7hmHEyXg0n8d0l657AGSDTmAhKAPlUXQ/AQd6zwH+ BlNj/KGqjNW1WhFZlghLS/Y+kQ== X-Google-Smtp-Source: ADFU+vtJR/SwUVeYxn1xovxIzjRjxgxDqsd8bmfIqYhxJQchQPJNkPZKxsxPWS6KOYqUEhTsxx1tEQ== X-Received: by 2002:a62:1a03:: with SMTP id a3mr3985027pfa.214.1583258382707; Tue, 03 Mar 2020 09:59:42 -0800 (PST) Received: from hermes.corp.microsoft.com (204-195-22-127.wavecable.com. [204.195.22.127]) by smtp.gmail.com with ESMTPSA id w195sm22012158pfd.65.2020.03.03.09.59.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2020 09:59:41 -0800 (PST) From: Stephen Hemminger To: ajit.khaparde@broadcom.com, somnath.kotur@broadcom.com Cc: dev@dpdk.org, Stephen Hemminger Date: Tue, 3 Mar 2020 09:59:33 -0800 Message-Id: <20200303175938.14292-2-stephen@networkplumber.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200303175938.14292-1-stephen@networkplumber.org> References: <20200303175938.14292-1-stephen@networkplumber.org> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 1/6] eal: add portable way to check for math overflow X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Clang and recent versions of GCC has builtin functions to do most math operations and check for wraparound. On most architectures this is a just a math operation followed by a branch on carry set. But DPDK needs to be able to handle older GCC versions, and other compilers so a wrapper macro is needed. Chose to use a macro instead of inline functions to avoid having to write lots of variants for each numeric type. Signed-off-by: Stephen Hemminger --- lib/librte_eal/common/Makefile | 2 +- lib/librte_eal/common/include/rte_overflow.h | 74 ++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 lib/librte_eal/common/include/rte_overflow.h diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile index c2c6d92cd377..3794128b75b7 100644 --- a/lib/librte_eal/common/Makefile +++ b/lib/librte_eal/common/Makefile @@ -13,7 +13,7 @@ INC += rte_tailq.h rte_interrupts.h rte_alarm.h INC += rte_string_fns.h rte_version.h INC += rte_eal_memconfig.h INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_class.h -INC += rte_option.h +INC += rte_option.h rte_overflow.h INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h INC += rte_malloc.h rte_keepalive.h rte_time.h INC += rte_service.h rte_service_component.h diff --git a/lib/librte_eal/common/include/rte_overflow.h b/lib/librte_eal/common/include/rte_overflow.h new file mode 100644 index 000000000000..d61791371029 --- /dev/null +++ b/lib/librte_eal/common/include/rte_overflow.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Microsoft Corp + */ +#ifndef RTE_OVERFLOW_H_ +#define RTE_OVERFLOW_H_ +/** + * @file + * + * Math functions with overflow checking. + * Wrappers for the __builtin_XXX_overflow functions that exist + * in recent versions of GCC and CLANG but may not exist + * in older compilers. They are macros to allow use with any + * size of unsigned number. + * + * See: + * https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html + * https://github.com/nemequ/portable-snippets/tree/master/safe-math + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if defined(__has_builtin) +# if __has_builtin(__builtin_add_overflow) +# define RTE_HAVE_BUILTIN_OVERFLOW +# endif +#elif defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 5000) +# define RTE__HAVE_BUILTIN_OVERFLOW +#endif + +/** + * Safely add two bit unsigned numbers + * @param a + * One operand + * @param b + * Other operand + * @param res + * Pointer to the where result of a + b is stored. + * Must not be NULL + * @return + * return true if the result overflows and is therefore truncated. + */ +#ifdef RTE_HAVE_BUILTIN_OVERFLOW +#define rte_add_overflow(a, b, res) __builtin_add_overflow(a, b, res) +#else +#define rte_add_overflow(a, b, res) ({ *res = a + b; *res < a; }) +#endif + +/** + * Safely multiply two unsigned numbers + * @param a + * One operand + * @param b + * Other operand + * @param res + * Pointer to the where result of a + b is stored. + * Must not be NULL + * @return + * return true if the result overflows and is therefore truncated. + */ +#ifdef RTE_HAVE_BUILTIN_OVERFLOW +#define rte_mul_overflow(a, b, res) __builtin_mul_overflow(a, b, res) +#else +#define rte_mul_overflow(a, b, res) ({ *res = a * b; *res < a; }) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_OVERFLOW_H_ */