Message ID | 20230422002319.2592882-1-goldstein.w.n@gmail.com |
---|---|
State | New |
Headers | show |
Series | [v1] Benchtest: Add benchtests for {wcs, str}lcpy and {wcs, str}lcat | expand |
On Fri, Apr 21, 2023 at 7:23 PM Noah Goldstein <goldstein.w.n@gmail.com> 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 := \ > 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 > <https://www.gnu.org/licenses/>. */ > > -#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 <wchar.h> > # 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 > + <https://www.gnu.org/licenses/>. */ > +#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 > + <https://www.gnu.org/licenses/>. */ > + > +#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 > <https://www.gnu.org/licenses/>. */ > > -#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 > + <https://www.gnu.org/licenses/>. */ > + > +#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 > + <https://www.gnu.org/licenses/>. */ > + > +#define WIDE 1 > +#include "bench-strlcpy.c" > -- > 2.34.1 > NB: Based on "Implement strlcpy and strlcat [BZ #178]" by Florian.
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 <https://www.gnu.org/licenses/>. */ -#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 <wchar.h> # 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 + <https://www.gnu.org/licenses/>. */ +#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 + <https://www.gnu.org/licenses/>. */ + +#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 <https://www.gnu.org/licenses/>. */ -#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 + <https://www.gnu.org/licenses/>. */ + +#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 + <https://www.gnu.org/licenses/>. */ + +#define WIDE 1 +#include "bench-strlcpy.c"