public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v1] Benchtest: Add benchtests for {wcs,str}lcpy and {wcs,str}lcat
@ 2023-04-22  0:23 Noah Goldstein
  2023-04-22  0:24 ` Noah Goldstein
  0 siblings, 1 reply; 2+ messages in thread
From: Noah Goldstein @ 2023-04-22  0:23 UTC (permalink / raw)
  To: libc-alpha; +Cc: goldstein.w.n, hjl.tools, carlos

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


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-04-22  0:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-22  0:23 [PATCH v1] Benchtest: Add benchtests for {wcs,str}lcpy and {wcs,str}lcat Noah Goldstein
2023-04-22  0:24 ` Noah Goldstein

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).