From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9EEB44638A; Wed, 12 Mar 2025 20:28:57 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 96EBB40DD7; Wed, 12 Mar 2025 20:28:48 +0100 (CET) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mails.dpdk.org (Postfix) with ESMTP id 3570A40663 for ; Wed, 12 Mar 2025 20:28:44 +0100 (CET) Received: by linux.microsoft.com (Postfix, from userid 1213) id 66826210B158; Wed, 12 Mar 2025 12:28:43 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 66826210B158 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1741807723; bh=0LhHCfUe6WQsXk5n0cgdVuIwPrLRox229Xux1qu7EgM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hJ4nFcioMZO2wjk2vKUSANxpwtcK13fLLzYYozhKp1KZnX9zhMeiZbjXwinlnJc4p ao+nAiFBGTfls/K8XpGFswNP+Kmu+Ns/UKMcP0Svrw06pePyVvPYcm5P6cswDRtFwV ZOBjj5VlGl1ehOH8PdH/NcTO63/V6jEB2D4Axd0Q= From: Andre Muezerie To: andremue@linux.microsoft.com Cc: bruce.richardson@intel.com, dev@dpdk.org, sameh.gobriel@intel.com, vladimir.medvedkin@intel.com, yipeng1.wang@intel.com Subject: [PATCH v3 1/3] eal: add function rte_size_to_str Date: Wed, 12 Mar 2025 12:28:32 -0700 Message-Id: <1741807714-26748-2-git-send-email-andremue@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1741807714-26748-1-git-send-email-andremue@linux.microsoft.com> References: <1741291408-26509-1-git-send-email-andremue@linux.microsoft.com> <1741807714-26748-1-git-send-email-andremue@linux.microsoft.com> 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 It's common to use %' in the printf format specifier to make large numbers more easily readable by having the thousands grouped. However, this grouping does not work on Windows. Therefore, a function is needed to make uint64_t numbers more easily readable. There are at least two tests that can benefit from this new function. Signed-off-by: Andre Muezerie --- lib/eal/common/eal_common_string_fns.c | 44 ++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 31 ++++++++++++++++++ lib/eal/version.map | 3 ++ 3 files changed, 78 insertions(+) diff --git a/lib/eal/common/eal_common_string_fns.c b/lib/eal/common/eal_common_string_fns.c index 9ca2045b18..4cc7f35652 100644 --- a/lib/eal/common/eal_common_string_fns.c +++ b/lib/eal/common/eal_common_string_fns.c @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -87,6 +88,12 @@ rte_str_to_size(const char *str) endptr++; /* allow 1 space gap */ switch (*endptr) { + case 'E': case 'e': + size *= 1024; /* fall-through */ + case 'P': case 'p': + size *= 1024; /* fall-through */ + case 'T': case 't': + size *= 1024; /* fall-through */ case 'G': case 'g': size *= 1024; /* fall-through */ case 'M': case 'm': @@ -98,3 +105,40 @@ rte_str_to_size(const char *str) } return size; } + +int +rte_size_to_str(char *buf, int buf_size, + uint64_t count, bool use_iec) +{ + const char *prefix = "kMGTPE"; + const unsigned int base = use_iec ? 1024 : 1000; + uint64_t powi = 1; + uint16_t powj = 1; + uint8_t precision = 2; + + if (count < base) + return snprintf(buf, buf_size, "%"PRIu64" ", count); + + /* increase value by a factor of 1000/1024 and store + * if result is something a human can read + */ + for (;;) { + powi *= base; + if (count / base < powi) + break; + + if (!prefix[1]) + break; + ++prefix; + } + + /* try to guess a good number of digits for precision */ + for (; precision > 0; precision--) { + powj *= 10; + if (count / powi < powj) + break; + } + + return snprintf(buf, buf_size, "%.*f %c%s", precision, + (double)count / powi, *prefix, use_iec ? "i" : ""); +} diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h index 386f11ae40..781c56adcd 100644 --- a/lib/eal/include/rte_common.h +++ b/lib/eal/include/rte_common.h @@ -14,9 +14,11 @@ #include #include +#include #include #include +#include #include /* OS specific include */ @@ -919,6 +921,35 @@ __extension__ typedef uint64_t RTE_MARKER64[0]; uint64_t rte_str_to_size(const char *str); +/** + * Converts the uint64_t value provided to a human-readable string. + * It null-terminates the string, truncating the data if needed. + * + * Sample outputs with "use_iec" disabled and enabled: + * 0 : "0 ", "0 " + * 700 : "700 ", "700 " + * 1000 : "1.00 k", "1000 " + * 1024 : "1.02 k", "1.00 ki" + * 21474836480 : "21.5 G", "20.0 Gi" + * 109951162777600 : "110 T", "100 Ti" + * + * @param buf + * Buffer to write the string to. + * @param buf_size + * Size of the buffer. + * @param count + * Number to convert. + * @param use_iec + * If true, use IEC units (1024-based), otherwise use SI units (1000-based). + * @return + * Number of characters written (not including the null-terminator), + * or that would have been required when the buffer is too small. + */ +__rte_experimental +int +rte_size_to_str(char *buf, int buf_size, + uint64_t count, bool use_iec); + /** * Function to terminate the application immediately, printing an error * message and returning the exit_code back to the shell. diff --git a/lib/eal/version.map b/lib/eal/version.map index a20c713eb1..01b6a7c190 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -398,6 +398,9 @@ EXPERIMENTAL { # added in 24.11 rte_bitset_to_str; rte_lcore_var_alloc; + + # added in 25.07 + rte_size_to_str; }; INTERNAL { -- 2.48.1.vfs.0.1