From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by sourceware.org (Postfix) with ESMTPS id 033B93856262 for ; Sat, 22 Apr 2023 00:24:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 033B93856262 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ed1-x52d.google.com with SMTP id 4fb4d7f45d1cf-504eac2f0b2so3822863a12.3 for ; Fri, 21 Apr 2023 17:24:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682123084; x=1684715084; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=mUCnNELRc28fugrOar9vgdbbSkFeTy2UYWMTWoVezh0=; b=HTBwcO4WDGI2WrHEwznNWks1wilPXrBlZdPJD7LGeh7NsgQw7sVpSk4NZfX6lOlbEU 7jogBZDJ3YHsy5Kuph+oM9J9w4gPt8l/knrEAaAbxKo0Y/kjJQ6emmBYP20+H4W4LF8x dPkwvmPhW8ycUHVz7TdjXchFWMrIOUXekSPuKcmk9OVEqXcdy7zmGQhmmjeEKYmflOB7 dnf74+CfLDsQzzI3g93eSztsrh6d62hNWDsk0jyD2uVWM4bsVx9jlLniess9h2G1P8+K a16MCMx6dHZJEzJhuqs2dGVLezWPIX6PQbNR1PjdmtM78BxtGAjp/WgkO4xgk2ObULda +ifw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682123084; x=1684715084; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mUCnNELRc28fugrOar9vgdbbSkFeTy2UYWMTWoVezh0=; b=Q2WdEaG/gbNvN/jSGWQToSjzOPY6vgjd7DhYAeee4CobdQnbdZwBuXtyytH1nqnI8J ArLDLUIkyWzJXe9318+7fSRd9TGBk7c8+3FJA3x6vxWHEziUamPSGSUEjCHYnfS2n01v jV8yC8ZPFU5XdNIhjXM5b+8mho2zFlYz0AmruiDKbYTiA3a1p1mEJq3fAYuiPSNNMvBk 5R3+GDNCu9M4x/JLGloRYICW17K5AX7yFihGWdXKPRD55zHr6KKcFnEG/4FK0ucRBcoK mqmzLZVk6K5dcXs9dgRF2Sd0QFc4QgSYEphf7E12cPje4rv8j2nUVbKXUNBH9WknfxQu cPBQ== X-Gm-Message-State: AAQBX9cyeWmWBZsyrGsVFPqCjZ9I5vef98+Nxo3Gk1cUKQAKlZPjJYf0 CGCSgKL5/WwzPewCSb3xhidqDCqedSzpVHtAVakMp1+l83U= X-Google-Smtp-Source: AKy350axHd0CMWA0N1uigjmsSrQRkjcMK4Le0O6nFUEwo5sI5ihzUzTdx1lGQuNlZCcmGsxZwKBcG3ZIaR43U1vw4AU= X-Received: by 2002:aa7:d50a:0:b0:4fb:953d:c3d0 with SMTP id y10-20020aa7d50a000000b004fb953dc3d0mr6631206edq.20.1682123084111; Fri, 21 Apr 2023 17:24:44 -0700 (PDT) MIME-Version: 1.0 References: <20230422002319.2592882-1-goldstein.w.n@gmail.com> In-Reply-To: <20230422002319.2592882-1-goldstein.w.n@gmail.com> From: Noah Goldstein Date: Fri, 21 Apr 2023 19:24:32 -0500 Message-ID: Subject: Re: [PATCH v1] Benchtest: Add benchtests for {wcs,str}lcpy and {wcs,str}lcat To: libc-alpha@sourceware.org Cc: hjl.tools@gmail.com, carlos@systemhalted.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-9.5 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 List-Id: On Fri, Apr 21, 2023 at 7:23=E2=80=AFPM Noah Goldstein wrote: > > 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 :=3D \ > strcpy \ > strcpy_chk \ > strcspn \ > + strlcat \ > + strlcpy \ > strlen \ > strncasecmp \ > strncat \ > @@ -188,6 +190,8 @@ wcsmbs-benchset :=3D \ > 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_ =3D (n); = \ > + tmp_n_ -=3D (dlen); = \ > + size_t tmp_len_ = \ > + =3D (tmp_n_) ? ((slen) < (tmp_n_) ? (slen) : ((tmp_n_) -1)) : 0; = \ > + (((tmp_n_) !=3D 0) && ((dst)[(dlen) + tmp_len_] !=3D 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 =3D STRLEN (src); > + dst_len =3D STRNLEN (dst, n); > + if (dst_len < n) > + { > + n -=3D dst_len; > + if (src_len < n) > + { > + n =3D src_len + 1; > + } > + MEMCPY (dst + dst_len, src, n - 1); > + dst[dst_len + n - 1] =3D 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_ =3D (n) ? ((len) < (n) ? (len) : ((n) -1)) : 0; = \ > + (((n) !=3D 0) && ((dst)[tmp_len_] !=3D 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 =3D STRLEN (src); > + if (n) > + { > + if (src_len < n) > + { > + n =3D src_len + 1; > + } > + > + MEMCPY (dst, src, n - 1); > + dst[n - 1] =3D 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 =3D STRLEN (dst), i, iters =3D INNER_LOOP_ITERS8; > + size_t k =3D DSTLEN (dst, n), i, iters =3D INNER_LOOP_ITERS8; > timing_t start, stop, cur; > > - if (CALL (impl, dst, src, n) !=3D dst) > + if (CALL (impl, dst, src, n) !=3D STRNCAT_RESULT (dst, src, slen, n, k= )) > { > error (0, 0, "Wrong result in function %s %p !=3D %p", impl->name, > - CALL (impl, dst, src, n), dst); > + (void *) CALL (impl, dst, src, n), > + (void *) STRNCAT_RESULT (dst, src, slen, n, k)); > ret =3D 1; > return; > } > > - size_t len =3D STRLEN (src); > - if (MEMCMP (dst + k, src, len + 1 > n ? n : len + 1) !=3D 0) > + if (CMP(dst, src, slen, n, k) !=3D 0) > { > error (0, 0, "Incorrect concatenation in function %s", impl->name)= ; > ret =3D 1; > return; > } > - if (n < len && dst[k + n] !=3D '\0') > + if (CHECK_NULL_TERM && n < slen && dst[k + n] !=3D '\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] =3D '\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 =3D INNER_LOOP_ITERS_LARGE / CHARBYTES; > timing_t start, stop, cur; > > - if (CALL (impl, dst, src, n) !=3D STRNCPY_RESULT (dst, len, n)) > + if (CALL (impl, dst, src, n) !=3D 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 =3D 1; > return; > } > > - if (memcmp (dst, src, (len > n ? n : len) * sizeof (CHAR)) !=3D 0) > + if (CMP(dst, src, len, n) !=3D 0) > { > error (0, 0, "Wrong result in function %s", impl->name); > ret =3D 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" > -- > 2.34.1 > NB: Based on "Implement strlcpy and strlcat [BZ #178]" by Florian.