From patchwork Sat Apr 22 00:23:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Noah Goldstein X-Patchwork-Id: 1772184 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=bOvhp8tF; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Q3BwK5LPwz1ybF for ; Sat, 22 Apr 2023 10:24:17 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EDB3C385415E for ; Sat, 22 Apr 2023 00:24:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EDB3C385415E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1682123053; bh=KqymBd6N12b/IR1Z0A4mLLOVvEEgs2XdqZ27Xvq/Dgg=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=bOvhp8tFLQybVHKvNkZdoXTeUnvUbIBMIzCbZcW8HoUJzKG9QI3uR5SnHfhTV1DVX cuA6ajydS1o76pEaLLc0JD6U7VPPc9B/Iuo5a77fWRd4DwrSqRsKXsMOX0itY+2Bja qe1DK7Ij3igVf3L6ynDiKQfckuU4VJL8BLLpmoPk= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by sourceware.org (Postfix) with ESMTPS id 7FAD8385702B for ; Sat, 22 Apr 2023 00:23:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7FAD8385702B Received: by mail-ed1-x52c.google.com with SMTP id 4fb4d7f45d1cf-506bfe81303so3798410a12.1 for ; Fri, 21 Apr 2023 17:23:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682123006; x=1684715006; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=KqymBd6N12b/IR1Z0A4mLLOVvEEgs2XdqZ27Xvq/Dgg=; b=lH+b54YTzo/JE+T3RLr+DJBs/aImwfSds0lIk8TYSKMOXLjXrFkCHP79iQwX2GS0WB p1kYa8RJ2oxq7ke98/H7zxdUOOclZEoGZlHKu3ibfemFFAXwcYWmzIbkdsHVNLzz4k4+ ixyBM7pJtMdptbhBDX8ud31b88DHKC+KbooRswX7F3bfiXPUqY/7porx2JOKPaG+edu4 mO+R62OxCm7GEXxy6yAtP6dSNGkp8OltKG50m0FODzxsVinXKuBznt3hb6Uf4EUVLK/p ERfkuzA8wEuo0qX9gbaS+X9esh13OmSeL5dvatGwZDfw7L6HzTI6FMRhzQp8BwcxlT16 aXAA== X-Gm-Message-State: AAQBX9f0bRmBlFC/W7t5VmttTul74FNFPAvnG1sluddPSPodGiChva8l 07O1y+I93aLoUWYksn+kBAbF+cORBkA= X-Google-Smtp-Source: AKy350bdJPY/47vEkTdIM/WGzVfONtWft5lez9choSKDtYxUKCPx6HjtT9Nc3jJsFBmagTH37SgVDw== X-Received: by 2002:aa7:c398:0:b0:504:e9cc:de35 with SMTP id k24-20020aa7c398000000b00504e9ccde35mr5486916edq.0.1682123005854; Fri, 21 Apr 2023 17:23:25 -0700 (PDT) Received: from noahgold-desk.intel.com ([192.55.54.52]) by smtp.gmail.com with ESMTPSA id ca22-20020aa7cd76000000b00506a58f29acsm2308268edb.65.2023.04.21.17.23.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Apr 2023 17:23:25 -0700 (PDT) To: libc-alpha@sourceware.org Cc: goldstein.w.n@gmail.com, hjl.tools@gmail.com, carlos@systemhalted.org Subject: [PATCH v1] Benchtest: Add benchtests for {wcs, str}lcpy and {wcs, str}lcat Date: Fri, 21 Apr 2023 19:23:19 -0500 Message-Id: <20230422002319.2592882-1-goldstein.w.n@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Noah Goldstein via Libc-alpha From: Noah Goldstein Reply-To: Noah Goldstein Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Mostly reuses the existing code for strncpy/strncat respectively. --- benchtests/Makefile | 4 +++ benchtests/bench-stpncpy.c | 2 +- benchtests/bench-string.h | 24 +++++++------ benchtests/bench-strlcat.c | 65 +++++++++++++++++++++++++++++++++++ benchtests/bench-strlcpy.c | 63 ++++++++++++++++++++++++++++++++++ benchtests/bench-strncat.c | 69 +++++++++++++++++++++++--------------- benchtests/bench-strncpy.c | 22 +++++++++--- benchtests/bench-wcslcat.c | 20 +++++++++++ benchtests/bench-wcslcpy.c | 20 +++++++++++ 9 files changed, 246 insertions(+), 43 deletions(-) create mode 100644 benchtests/bench-strlcat.c create mode 100644 benchtests/bench-strlcpy.c create mode 100644 benchtests/bench-wcslcat.c create mode 100644 benchtests/bench-wcslcpy.c diff --git a/benchtests/Makefile b/benchtests/Makefile index 5bd763a19d..336a3555f9 100644 --- a/benchtests/Makefile +++ b/benchtests/Makefile @@ -162,6 +162,8 @@ string-benchset := \ strcpy \ strcpy_chk \ strcspn \ + strlcat \ + strlcpy \ strlen \ strncasecmp \ strncat \ @@ -188,6 +190,8 @@ wcsmbs-benchset := \ wcscmp \ wcscpy \ wcscspn \ + wcslcat \ + wcslcpy \ wcslen \ wcsncat \ wcsncmp \ diff --git a/benchtests/bench-stpncpy.c b/benchtests/bench-stpncpy.c index adc81a58ba..e824a2d3c1 100644 --- a/benchtests/bench-stpncpy.c +++ b/benchtests/bench-stpncpy.c @@ -16,7 +16,7 @@ License along with the GNU C Library; if not, see . */ -#define STRNCPY_RESULT(dst, len, n) ((dst) + ((len) > (n) ? (n) : (len))) +#define STRNCPY_RESULT(dst, src, len, n) ((dst) + ((len) > (n) ? (n) : (len))) #define TEST_MAIN #ifndef WIDE # define TEST_NAME "stpncpy" diff --git a/benchtests/bench-string.h b/benchtests/bench-string.h index dbe7084e60..44d6042142 100644 --- a/benchtests/bench-string.h +++ b/benchtests/bench-string.h @@ -75,21 +75,23 @@ extern impl_t __start_impls[], __stop_impls[]; # define MEMCMP memcmp # define MEMCPY memcpy # define MEMSET memset +# define STPCPY stpcpy +# define STPNCPY stpncpy # define STRCAT strcat -# define STRLEN strlen -# define STRCMP strcmp # define STRCHR strchr +# define STRCMP strcmp # define STRCPY strcpy -# define STRNLEN strnlen # define STRCSPN strcspn +# define STRLCPY strlcpy +# define STRLEN strlen # define STRNCAT strncat # define STRNCMP strncmp # define STRNCPY strncpy +# define STRNLEN strnlen # define STRPBRK strpbrk # define STRRCHR strrchr # define STRSPN strspn -# define STPCPY stpcpy -# define STPNCPY stpncpy +# define STRLCAT strlcat # else # include # define CHAR wchar_t @@ -100,21 +102,23 @@ extern impl_t __start_impls[], __stop_impls[]; # define MEMCMP wmemcmp # define MEMCPY wmemcpy # define MEMSET wmemset +# define STPCPY wcpcpy +# define STPNCPY wcpncpy # define STRCAT wcscat -# define STRLEN wcslen -# define STRCMP wcscmp # define STRCHR wcschr +# define STRCMP wcscmp # define STRCPY wcscpy -# define STRNLEN wcsnlen # define STRCSPN wcscspn +# define STRLCAT wcslcat +# define STRLCPY wcslcpy +# define STRLEN wcslen # define STRNCAT wcsncat # define STRNCMP wcsncmp # define STRNCPY wcsncpy +# define STRNLEN wcsnlen # define STRPBRK wcspbrk # define STRRCHR wcsrchr # define STRSPN wcsspn -# define STPCPY wcpcpy -# define STPNCPY wcpncpy # endif /* WIDE */ # define TEST_FUNCTION test_main diff --git a/benchtests/bench-strlcat.c b/benchtests/bench-strlcat.c new file mode 100644 index 0000000000..cb97c60aa0 --- /dev/null +++ b/benchtests/bench-strlcat.c @@ -0,0 +1,65 @@ +/* Measure stplcpy functions. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ +#define DSTLEN(dst, n) STRNLEN (dst, n) +#define STRNCAT_RESULT(dst, src, slen, n, dlen) ((dlen) + STRLEN (src)) +#define CMP(dst, src, slen, n, dlen) \ + ({ \ + size_t tmp_n_ = (n); \ + tmp_n_ -= (dlen); \ + size_t tmp_len_ \ + = (tmp_n_) ? ((slen) < (tmp_n_) ? (slen) : ((tmp_n_) -1)) : 0; \ + (((tmp_n_) != 0) && ((dst)[(dlen) + tmp_len_] != 0)) \ + || memcmp ((dst) + (dlen), src, tmp_len_ * sizeof (CHAR)); \ + }) + +#define CHECK_NULL_TERM 0 +#define TEST_MAIN +#ifndef WIDE +# define TEST_NAME "strlcat" +#else +# define generic_strlcat generic_wcslcat +# define TEST_NAME "wcslcat" +#endif /* WIDE */ +#include "bench-string.h" + +#define PROTO typedef size_t (*proto_t) (CHAR *, const CHAR *, size_t) + +size_t +generic_strlcat (CHAR *dst, const CHAR *src, size_t n) +{ + size_t src_len, dst_len; + src_len = STRLEN (src); + dst_len = STRNLEN (dst, n); + if (dst_len < n) + { + n -= dst_len; + if (src_len < n) + { + n = src_len + 1; + } + MEMCPY (dst + dst_len, src, n - 1); + dst[dst_len + n - 1] = 0; + } + + return dst_len + src_len; +} + +IMPL (STRLCAT, 1) +IMPL (generic_strlcat, 0) + +#include "bench-strncat.c" diff --git a/benchtests/bench-strlcpy.c b/benchtests/bench-strlcpy.c new file mode 100644 index 0000000000..d87e0f5bc5 --- /dev/null +++ b/benchtests/bench-strlcpy.c @@ -0,0 +1,63 @@ +/* Measure stplcpy functions. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define STRNCPY_RESULT(dst, src, len, n) STRLEN (src) +#define CMP(dst, src, len, n) \ + ({ \ + size_t tmp_len_ = (n) ? ((len) < (n) ? (len) : ((n) -1)) : 0; \ + (((n) != 0) && ((dst)[tmp_len_] != 0)) \ + || memcmp (dst, src, tmp_len_ * sizeof (CHAR)); \ + }) +#define NEED_ZFILL 0 +#define TEST_MAIN +#ifndef WIDE +# define STRLEN strlen +# define MEMCPY memcpy +# define TEST_NAME "strlcpy" +#else +# define STRLEN wcslen +# define MEMCPY wmemcpy +# define generic_strlcpy generic_wcslcpy +# define TEST_NAME "wcslcpy" +#endif /* WIDE */ +#include "bench-string.h" + +#define PROTO typedef size_t (*proto_t) (CHAR *, const CHAR *, size_t) + +size_t +generic_strlcpy (CHAR *dst, const CHAR *src, size_t n) +{ + size_t src_len; + src_len = STRLEN (src); + if (n) + { + if (src_len < n) + { + n = src_len + 1; + } + + MEMCPY (dst, src, n - 1); + dst[n - 1] = 0; + } + return src_len; +} + +IMPL (STRLCPY, 1) +IMPL (generic_strlcpy, 0) + +#include "bench-strncpy.c" diff --git a/benchtests/bench-strncat.c b/benchtests/bench-strncat.c index e4792a9c3d..5dfab339a5 100644 --- a/benchtests/bench-strncat.c +++ b/benchtests/bench-strncat.c @@ -16,26 +16,21 @@ License along with the GNU C Library; if not, see . */ -#define TEST_MAIN -#ifndef WIDE -# define TEST_NAME "strncat" -#else -# define TEST_NAME "wcsncat" -# define generic_strncat generic_wcsncat -#endif /* WIDE */ -#include "bench-string.h" - -#define BIG_CHAR MAX_CHAR - -#ifndef WIDE -# define SMALL_CHAR 127 -#else -# define SMALL_CHAR 1273 -#endif /* WIDE */ +#ifndef STRNCAT_RESULT +#define CHECK_NULL_TERM 1 +#define STRNCAT_RESULT(dst, src, slen, n, dlen) dst +# define CMP(dst, src, slen, n, dlen) \ + MEMCMP ((dst) + (dlen), src, (slen) + 1 > (n) ? (n) : (slen) + 1) +# define DSTLEN(dst, n) STRLEN(dst) +# define TEST_MAIN +# ifndef WIDE +# define TEST_NAME "strncat" +# else +# define TEST_NAME "wcsncat" +# define generic_strncat generic_wcsncat +# endif /* WIDE */ -#include "json-lib.h" - -typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t); +#include "bench-string.h" CHAR * generic_strncat (CHAR *dst, const CHAR *src, size_t n) @@ -50,29 +45,49 @@ generic_strncat (CHAR *dst, const CHAR *src, size_t n) IMPL (STRNCAT, 2) IMPL (generic_strncat, 0) +#endif + + +#define BIG_CHAR MAX_CHAR + +#ifndef WIDE +# define SMALL_CHAR 127 +#else +# define SMALL_CHAR 1273 +#endif /* WIDE */ + +#include "json-lib.h" + +#ifndef PROTO +typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t); +#else +PROTO; +#endif + + static void do_one_test (json_ctx_t *json_ctx, impl_t *impl, CHAR *dst, const CHAR *src, - size_t n) + size_t slen, size_t n) { - size_t k = STRLEN (dst), i, iters = INNER_LOOP_ITERS8; + size_t k = DSTLEN (dst, n), i, iters = INNER_LOOP_ITERS8; timing_t start, stop, cur; - if (CALL (impl, dst, src, n) != dst) + if (CALL (impl, dst, src, n) != STRNCAT_RESULT (dst, src, slen, n, k)) { error (0, 0, "Wrong result in function %s %p != %p", impl->name, - CALL (impl, dst, src, n), dst); + (void *) CALL (impl, dst, src, n), + (void *) STRNCAT_RESULT (dst, src, slen, n, k)); ret = 1; return; } - size_t len = STRLEN (src); - if (MEMCMP (dst + k, src, len + 1 > n ? n : len + 1) != 0) + if (CMP(dst, src, slen, n, k) != 0) { error (0, 0, "Incorrect concatenation in function %s", impl->name); ret = 1; return; } - if (n < len && dst[k + n] != '\0') + if (CHECK_NULL_TERM && n < slen && dst[k + n] != '\0') { error (0, 0, "There is no zero in the end of output string in %s", impl->name); @@ -133,7 +148,7 @@ do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len1, FOR_EACH_IMPL (impl, 0) { s2[len2] = '\0'; - do_one_test (json_ctx, impl, s2, s1, n); + do_one_test (json_ctx, impl, s2, s1, len1, n); } json_array_end (json_ctx); diff --git a/benchtests/bench-strncpy.c b/benchtests/bench-strncpy.c index d90e3c55e2..bd762803b0 100644 --- a/benchtests/bench-strncpy.c +++ b/benchtests/bench-strncpy.c @@ -26,8 +26,16 @@ #include "json-lib.h" +#ifndef CMP +# define CMP(dst, src, len, n) \ + memcmp (dst, src, ((len) > (n) ? (n) : (len)) * sizeof (CHAR)) +#endif +#ifndef NEED_ZFILL +# define NEED_ZFILL 1 +#endif + #ifndef STRNCPY_RESULT -# define STRNCPY_RESULT(dst, len, n) dst +# define STRNCPY_RESULT(dst, src, len, n) dst # define TEST_MAIN # ifndef WIDE # define TEST_NAME "strncpy" @@ -51,7 +59,11 @@ IMPL (generic_strncpy, 0) #endif /* !STRNCPY_RESULT */ +#ifndef PROTO typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t); +#else +PROTO; +#endif static void do_one_test (json_ctx_t *json_ctx, impl_t *impl, CHAR *dst, const CHAR *src, @@ -60,22 +72,22 @@ do_one_test (json_ctx_t *json_ctx, impl_t *impl, CHAR *dst, const CHAR *src, size_t i, iters = INNER_LOOP_ITERS_LARGE / CHARBYTES; timing_t start, stop, cur; - if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, len, n)) + if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, src, len, n)) { error (0, 0, "Wrong result in function %s %p %p", impl->name, - CALL (impl, dst, src, n), dst); + (void *) CALL (impl, dst, src, n), dst); ret = 1; return; } - if (memcmp (dst, src, (len > n ? n : len) * sizeof (CHAR)) != 0) + if (CMP(dst, src, len, n) != 0) { error (0, 0, "Wrong result in function %s", impl->name); ret = 1; return; } - if (n > len) + if (NEED_ZFILL && n > len) { size_t i; diff --git a/benchtests/bench-wcslcat.c b/benchtests/bench-wcslcat.c new file mode 100644 index 0000000000..02f1331579 --- /dev/null +++ b/benchtests/bench-wcslcat.c @@ -0,0 +1,20 @@ +/* Measure wcslcat functions. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define WIDE 1 +#include "bench-strlcat.c" diff --git a/benchtests/bench-wcslcpy.c b/benchtests/bench-wcslcpy.c new file mode 100644 index 0000000000..9389b531a5 --- /dev/null +++ b/benchtests/bench-wcslcpy.c @@ -0,0 +1,20 @@ +/* Measure wcslcpy functions. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define WIDE 1 +#include "bench-strlcpy.c"