S390: Fix building with --disable-mutli-arch [BZ #31196]
[platform/upstream/glibc.git] / benchtests / bench-strncpy.c
1 /* Measure strncpy functions.
2    Copyright (C) 2013-2024 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18
19 #define BIG_CHAR MAX_CHAR
20
21 #ifdef WIDE
22 # define SMALL_CHAR 1273
23 #else
24 # define SMALL_CHAR 127
25 #endif /* !WIDE */
26
27 #include "json-lib.h"
28
29 #ifndef STRNCPY_RESULT
30 # define STRNCPY_RESULT(dst, len, n) dst
31 # define TEST_MAIN
32 # ifndef WIDE
33 #  define TEST_NAME "strncpy"
34 # else
35 #  define TEST_NAME "wcsncpy"
36 #  define generic_strncpy generic_wcsncpy
37 # endif /* WIDE */
38 # include "bench-string.h"
39
40 CHAR *
41 generic_strncpy (CHAR *dst, const CHAR *src, size_t n)
42 {
43   size_t nc = STRNLEN (src, n);
44   if (nc != n)
45     MEMSET (dst + nc, 0, n - nc);
46   return MEMCPY (dst, src, nc);
47 }
48
49 IMPL (STRNCPY, 1)
50 IMPL (generic_strncpy, 0)
51
52 #endif /* !STRNCPY_RESULT */
53
54 typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t);
55
56 static void
57 do_one_test (json_ctx_t *json_ctx, impl_t *impl, CHAR *dst, const CHAR *src,
58              size_t len, size_t n)
59 {
60   size_t i, iters = INNER_LOOP_ITERS_LARGE / CHARBYTES;
61   timing_t start, stop, cur;
62
63   if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, len, n))
64     {
65       error (0, 0, "Wrong result in function %s %p %p", impl->name,
66              CALL (impl, dst, src, n), dst);
67       ret = 1;
68       return;
69     }
70
71   if (memcmp (dst, src, (len > n ? n : len) * sizeof (CHAR)) != 0)
72     {
73       error (0, 0, "Wrong result in function %s", impl->name);
74       ret = 1;
75       return;
76     }
77
78   if (n > len)
79     {
80       size_t i;
81
82       for (i = len; i < n; ++i)
83         if (dst[i] != '\0')
84           {
85             error (0, 0, "Wrong result in function %s", impl->name);
86             ret = 1;
87             return;
88           }
89     }
90
91   TIMING_NOW (start);
92   for (i = 0; i < iters; ++i)
93     {
94       CALL (impl, dst, src, n);
95     }
96   TIMING_NOW (stop);
97
98   TIMING_DIFF (cur, start, stop);
99
100   json_element_double (json_ctx, (double) cur / (double) iters);
101 }
102
103 static void
104 do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len,
105          size_t n, int max_char)
106 {
107   size_t i;
108   CHAR *s1, *s2;
109
110   /* For wcsncpy: align1 and align2 here mean alignment not in bytes,
111      but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)).  */
112   align1 &= 7;
113   if ((align1 + len) * sizeof (CHAR) >= page_size)
114     return;
115
116   align2 &= 7;
117   if ((align2 + len) * sizeof (CHAR) >= page_size)
118     return;
119
120   s1 = (CHAR *) (buf1) + align1;
121   s2 = (CHAR *) (buf2) + align2;
122
123   for (i = 0; i < len; ++i)
124     s1[i] = 32 + 23 * i % (max_char - 32);
125   s1[len] = 0;
126   for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64;
127        ++i)
128     s1[i] = 32 + 32 * i % (max_char - 32);
129
130   json_element_object_begin (json_ctx);
131   json_attr_uint (json_ctx, "align1", align1);
132   json_attr_uint (json_ctx, "align2", align2);
133   json_attr_uint (json_ctx, "len", len);
134   json_attr_uint (json_ctx, "n", n);
135   json_attr_uint (json_ctx, "max_char", max_char);
136
137   json_array_begin (json_ctx, "timings");
138
139   FOR_EACH_IMPL (impl, 0)
140     do_one_test (json_ctx, impl, s2, s1, len, n);
141
142   json_array_end (json_ctx);
143   json_element_object_end (json_ctx);
144 }
145
146 static int
147 test_main (void)
148 {
149   json_ctx_t json_ctx;
150   size_t i, j;
151
152   test_init ();
153
154   json_init (&json_ctx, 0, stdout);
155
156   json_document_begin (&json_ctx);
157   json_attr_string (&json_ctx, "timing_type", TIMING_TYPE);
158
159   json_attr_object_begin (&json_ctx, "functions");
160   json_attr_object_begin (&json_ctx, TEST_NAME);
161   json_attr_string (&json_ctx, "bench-variant", "");
162
163   json_array_begin (&json_ctx, "ifuncs");
164   FOR_EACH_IMPL (impl, 0)
165     json_element_string (&json_ctx, impl->name);
166   json_array_end (&json_ctx);
167
168   json_array_begin (&json_ctx, "results");
169
170   for (i = 1; i < 8; ++i)
171     {
172       do_test (&json_ctx, i, i, 16, 16, SMALL_CHAR);
173       do_test (&json_ctx, i, i, 16, 16, BIG_CHAR);
174       do_test (&json_ctx, i, 2 * i, 16, 16, SMALL_CHAR);
175       do_test (&json_ctx, 2 * i, i, 16, 16, BIG_CHAR);
176       do_test (&json_ctx, 8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
177       do_test (&json_ctx, 2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
178       do_test (&json_ctx, 8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
179       do_test (&json_ctx, 2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
180     }
181
182   for (i = 1; i < 8; ++i)
183     {
184       do_test (&json_ctx, 0, 0, 4 << i, 8 << i, SMALL_CHAR);
185       do_test (&json_ctx, 0, 0, 16 << i, 8 << i, SMALL_CHAR);
186       do_test (&json_ctx, 8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
187       do_test (&json_ctx, 8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
188     }
189
190   for (i = 128; i < 2048; i += i)
191     {
192       for (j = i - 64; j <= i + 64; j += 32)
193         {
194           do_test (&json_ctx, 1, 0, i, j, SMALL_CHAR);
195           do_test (&json_ctx, 0, i, i, j, SMALL_CHAR);
196           do_test (&json_ctx, 0, 0, i, j, SMALL_CHAR);
197           do_test (&json_ctx, i, i, i, j, SMALL_CHAR);
198           do_test (&json_ctx, 1, 0, j, i, SMALL_CHAR);
199           do_test (&json_ctx, 0, i, j, i, SMALL_CHAR);
200           do_test (&json_ctx, 0, 0, j, i, SMALL_CHAR);
201           do_test (&json_ctx, i, i, j, i, SMALL_CHAR);
202         }
203     }
204
205   json_array_end (&json_ctx);
206   json_attr_object_end (&json_ctx);
207   json_attr_object_end (&json_ctx);
208   json_document_end (&json_ctx);
209
210   return ret;
211 }
212
213 #include <support/test-driver.c>