1 /* Measure strcasecmp functions.
2    Copyright (C) 2013-2022 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 #include <ctype.h>
20 #define TEST_MAIN
21 #define TEST_NAME "strcasecmp"
22 #include "bench-string.h"
23 #include "json-lib.h"
24 
25 typedef int (*proto_t) (const char *, const char *);
26 static int simple_strcasecmp (const char *, const char *);
27 
28 IMPL (simple_strcasecmp, 0)
29 IMPL (strcasecmp, 1)
30 
31 static int
simple_strcasecmp(const char * s1,const char * s2)32 simple_strcasecmp (const char *s1, const char *s2)
33 {
34   int ret;
35 
36   while ((ret = ((unsigned char) tolower (*s1)
37 		 - (unsigned char) tolower (*s2))) == 0
38 	 && *s1++)
39     ++s2;
40   return ret;
41 }
42 
43 static void
do_one_test(json_ctx_t * json_ctx,impl_t * impl,const char * s1,const char * s2,int exp_result)44 do_one_test (json_ctx_t *json_ctx, impl_t *impl, const char *s1,
45              const char *s2, int exp_result)
46 {
47   size_t i, iters = INNER_LOOP_ITERS;
48   timing_t start, stop, cur;
49   int result = CALL (impl, s1, s2);
50   if ((exp_result == 0 && result != 0)
51       || (exp_result < 0 && result >= 0)
52       || (exp_result > 0 && result <= 0))
53     {
54       error (0, 0, "Wrong result in function %s %d %d", impl->name,
55 	     result, exp_result);
56       ret = 1;
57       return;
58     }
59 
60   TIMING_NOW (start);
61   for (i = 0; i < iters; ++i)
62     {
63       CALL (impl, s1, s2);
64     }
65   TIMING_NOW (stop);
66 
67   TIMING_DIFF (cur, start, stop);
68 
69   json_element_double (json_ctx, (double) cur / (double) iters);
70 }
71 
72 static void
do_test(json_ctx_t * json_ctx,size_t align1,size_t align2,size_t len,int max_char,int exp_result)73 do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len,
74          int max_char, int exp_result)
75 {
76   size_t i;
77   char *s1, *s2;
78 
79   if (len == 0)
80     return;
81 
82   align1 &= 7;
83   if (align1 + len + 1 >= page_size)
84     return;
85 
86   align2 &= 7;
87   if (align2 + len + 1 >= page_size)
88     return;
89 
90   json_element_object_begin (json_ctx);
91   json_attr_uint (json_ctx, "length", len);
92   json_attr_uint (json_ctx, "align1", align1);
93   json_attr_uint (json_ctx, "align2", align2);
94   json_attr_uint (json_ctx, "max_char", max_char);
95   json_array_begin (json_ctx, "timings");
96 
97   s1 = (char *) (buf1 + align1);
98   s2 = (char *) (buf2 + align2);
99 
100   for (i = 0; i < len; i++)
101     {
102       s1[i] = toupper (1 + 23 * i % max_char);
103       s2[i] = tolower (s1[i]);
104     }
105 
106   s1[len] = s2[len] = 0;
107   s1[len + 1] = 23;
108   s2[len + 1] = 24 + exp_result;
109   if ((s2[len - 1] == 'z' && exp_result == -1)
110       || (s2[len - 1] == 'a' && exp_result == 1))
111     s1[len - 1] += exp_result;
112   else
113     s2[len - 1] -= exp_result;
114 
115   FOR_EACH_IMPL (impl, 0)
116     do_one_test (json_ctx, impl, s1, s2, exp_result);
117 
118   json_array_end (json_ctx);
119   json_element_object_end (json_ctx);
120 }
121 
122 int
test_main(void)123 test_main (void)
124 {
125   json_ctx_t json_ctx;
126   size_t i;
127 
128   test_init ();
129 
130   json_init (&json_ctx, 0, stdout);
131 
132   json_document_begin (&json_ctx);
133   json_attr_string (&json_ctx, "timing_type", TIMING_TYPE);
134 
135   json_attr_object_begin (&json_ctx, "functions");
136   json_attr_object_begin (&json_ctx, TEST_NAME);
137   json_attr_string (&json_ctx, "bench-variant", "");
138 
139   json_array_begin (&json_ctx, "ifuncs");
140   FOR_EACH_IMPL (impl, 0)
141     json_element_string (&json_ctx, impl->name);
142   json_array_end (&json_ctx);
143 
144   json_array_begin (&json_ctx, "results");
145 
146   for (i = 1; i < 16; ++i)
147     {
148       do_test (&json_ctx, i, i, i, 127, 0);
149       do_test (&json_ctx, i, i, i, 127, 1);
150       do_test (&json_ctx, i, i, i, 127, -1);
151     }
152 
153   for (i = 1; i < 10; ++i)
154     {
155       do_test (&json_ctx, 0, 0, 2 << i, 127, 0);
156       do_test (&json_ctx, 0, 0, 2 << i, 254, 0);
157       do_test (&json_ctx, 0, 0, 2 << i, 127, 1);
158       do_test (&json_ctx, 0, 0, 2 << i, 254, 1);
159       do_test (&json_ctx, 0, 0, 2 << i, 127, -1);
160       do_test (&json_ctx, 0, 0, 2 << i, 254, -1);
161     }
162 
163   for (i = 1; i < 8; ++i)
164     {
165       do_test (&json_ctx, i, 2 * i, 8 << i, 127, 0);
166       do_test (&json_ctx, 2 * i, i, 8 << i, 254, 0);
167       do_test (&json_ctx, i, 2 * i, 8 << i, 127, 1);
168       do_test (&json_ctx, 2 * i, i, 8 << i, 254, 1);
169       do_test (&json_ctx, i, 2 * i, 8 << i, 127, -1);
170       do_test (&json_ctx, 2 * i, i, 8 << i, 254, -1);
171     }
172 
173   json_array_end (&json_ctx);
174   json_attr_object_end (&json_ctx);
175   json_attr_object_end (&json_ctx);
176   json_document_end (&json_ctx);
177 
178   return ret;
179 }
180 
181 #include <support/test-driver.c>
182