Jeff Johnston <jjohnstn <at> redhat.com>
writes:
> >>>
> >> Yes, go ahead. I assume you have verified
that the function still works
> >> correctly.
> >>
> > OK for this followon, which changes the generic C
code in the same manner
(also
> > tested)?
>
> Yes, thanks.
>
OK for this followup? This codifies my regression test into
version control,
rather than just this email thread. I tested with:
$ cd libc/string
$ gcc -Wall -o strchr -O2 -D_REGRESSION_TEST strchr.c
$ time ./strchr --all # C implementation
real 0m3.188s
user 0m3.171s
sys 0m0.030s
$ gcc -c -o strchr1.o -Dstrchr=strchr1
../machine/i386/strchr.S
$ gcc -Wall -o strchr -O2 -D_REGRESSION_TEST
-DTEST_STRCHR=strchr1
strchr.c strchr1.o
$ time ./strchr --all # Assembly implementation
real 0m2.922s
user 0m2.890s
sys 0m0.030s
If this approach is okay, then I will make similar changes
for the other
functions I have touched; am I pre-approved for checking
those in too? Do you
want me to also try and figure out how to hook this into
'make check'?
2008-05-28 Eric Blake <ebb9 byu.net>
Add test for recent changes.
* libc/string/strchr.c [_REGRESSION_TEST]: New section,
which can
optionally be compiled as a regression test.
Index: libc/string/strchr.c
============================================================
=======
RCS file: /cvs/src/src/newlib/libc/string/strchr.c,v
retrieving revision 1.3
diff -u -p -r1.3 strchr.c
--- libc/string/strchr.c 22 May 2008 02:31:46 -0000 1.3
+++ libc/string/strchr.c 28 May 2008 15:17:27 -0000
 -121,3
+121,101  _DEFUN (strchr, (s1, i),
return (char *)s;
return NULL;
}
+
+/* The remainder of this file can serve as a regression
test. Compile
+ with -D_REGRESSION_TEST, and optionally with
+ -DTEST_STRCHR=strchr_alt when linked with strchr_alt.o,
to ensure
+ correct operation and allow timing tests. */
+#ifdef _REGRESSION_TEST
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <assert.h>
+
+# ifdef TEST_STRCHR
+char *TEST_STRCHR (const char *, int);
+# else
+# define TEST_STRCHR strchr
+# endif
+
+static void
+test (size_t size, size_t repeat, size_t offset, int goal)
+{
+ char *buf = malloc (size + 1);
+ char *expected;
+ assert (buf);
+ switch (goal)
+ {
+ case 0:
+ expected = buf + size;
+ break;
+ case 1:
+ expected = (size > 1 && offset < size -
1) ? buf + offset : NULL;
+ break;
+ case 2:
+ expected = offset < size ? buf + size - 1 : NULL;
+ break;
+ default:
+ expected = NULL;
+ break;
+ }
+ if (size)
+ {
+ memset (buf, 1, size - 1);
+ buf[size - 1] = 2;
+ }
+ buf[size] = 0;
+ buf += offset;
+ while (repeat--)
+ assert (TEST_STRCHR (buf, goal) == expected);
+ buf -= offset;
+ free (buf);
+}
+
+int
+main (int argc, char **argv)
+{
+ if (argc == 2 && strcmp (argv[1],
"--all") == 0)
+ {
+ int i, j, k;
+
+ /* Ensure all alignments for both start and target
work. */
+ for (i = 0; i <= 32; i++)
+ for (j = 0; j < i; j++)
+ for (k = 0; k <= 3; k++)
+ test (i, 1, j, k);
+ /* Multiple runs to make timing easier. */
+ test (1000000, 1000, 0, 0);
+ test (1000000, 1000, 1, 0);
+ test (1000000, 1000, 0, 1);
+ test (1000000, 1000, 1, 1);
+ test (1000000, 1000, 0, 2);
+ test (1000000, 1000, 1, 2);
+ test (1000000, 1000, 0, 3);
+ test (1000000, 1000, 1, 3);
+ return 0;
+ }
+ if (argc < 5)
+ {
+ printf ("usage: %s --alln", argv[0]);
+ printf (" or: %s size repeat offset
goaln", argv[0]);
+ printf ("t--all - run a canned set of
testsn");
+ printf ("tsize - buffer size to search
inn");
+ printf ("trepeat - times to repeat
searchn");
+ printf ("toffset - offset within buf to start
search, <= sizen");
+ printf ("tgoal - 0 for end, 1 for beginning, 2
for next to last, 3 for
missn");
+ return 1;
+ }
+ size_t size = strtol (argv[1], NULL, 0);
+ size_t repeat = strtol (argv[2], NULL, 0);
+ size_t offset = strtol (argv[3], NULL, 0);
+ int goal = strtol (argv[4], NULL, 0);
+ if (!repeat)
+ repeat = 1;
+ if (size < offset)
+ offset = size;
+ test (size, repeat, offset, goal);
+ return 0;
+}
+
+#endif /* _REGRESSION_TEST */
|