| diff -pruN glibc-2.17-c758a686/benchtests/acosh-inputs glibc-2.17-c758a686.new/benchtests/acosh-inputs |
| |
| |
| @@ -0,0 +1,5 @@ |
| +0.1 |
| +0.2 |
| +0.3 |
| +0.4 |
| +0.5 |
| diff -pruN glibc-2.17-c758a686/benchtests/acos-inputs glibc-2.17-c758a686.new/benchtests/acos-inputs |
| |
| |
| @@ -0,0 +1,7 @@ |
| +0.5 |
| +0.1 |
| +0.2 |
| +0.3 |
| +0.4 |
| +0.8 |
| +0.7 |
| diff -pruN glibc-2.17-c758a686/benchtests/asinh-inputs glibc-2.17-c758a686.new/benchtests/asinh-inputs |
| |
| |
| @@ -0,0 +1,5 @@ |
| +0.1 |
| +0.2 |
| +0.3 |
| +0.4 |
| +0.5 |
| diff -pruN glibc-2.17-c758a686/benchtests/asin-inputs glibc-2.17-c758a686.new/benchtests/asin-inputs |
| |
| |
| @@ -0,0 +1,7 @@ |
| +0.5 |
| +0.1 |
| +0.2 |
| +0.3 |
| +0.4 |
| +0.8 |
| +0.7 |
| diff -pruN glibc-2.17-c758a686/benchtests/atanh-inputs glibc-2.17-c758a686.new/benchtests/atanh-inputs |
| |
| |
| @@ -0,0 +1,5 @@ |
| +0.1 |
| +0.2 |
| +0.3 |
| +0.4 |
| +0.5 |
| diff -pruN glibc-2.17-c758a686/benchtests/atan-inputs glibc-2.17-c758a686.new/benchtests/atan-inputs |
| |
| |
| @@ -0,0 +1,9 @@ |
| +0x1.000000c5cba86p0 |
| +0x1.000001883003ap0 |
| +0x1.00000dfb2b674p0 |
| +# atan slowest path at 768 bits |
| +# Implemented in sysdeps/ieee754/dbl-64/mpatan.c |
| +## name: 768bits |
| +0x1.000000c5cba87p0 |
| +0x1.000001883003bp0 |
| +0x1.00000dfb2b675p0 |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-bcopy.c glibc-2.17-c758a686.new/benchtests/bench-bcopy.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure bcopy functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_BCOPY |
| +#include "bench-memmove.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-bcopy-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-bcopy-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of bcopy function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-bcopy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-bzero.c glibc-2.17-c758a686.new/benchtests/bench-bzero.c |
| |
| |
| @@ -0,0 +1,19 @@ |
| +/* Measure bzero functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| +#define TEST_BZERO |
| +#include "bench-memset.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-bzero-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-bzero-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of bzero function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-bzero.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memccpy.c glibc-2.17-c758a686.new/benchtests/bench-memccpy.c |
| |
| |
| @@ -0,0 +1,169 @@ |
| +/* Measure memccpy functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "memccpy" |
| +#include "bench-string.h" |
| + |
| +void *simple_memccpy (void *, const void *, int, size_t); |
| +void *stupid_memccpy (void *, const void *, int, size_t); |
| + |
| +IMPL (stupid_memccpy, 0) |
| +IMPL (simple_memccpy, 0) |
| +IMPL (memccpy, 1) |
| + |
| +void * |
| +simple_memccpy (void *dst, const void *src, int c, size_t n) |
| +{ |
| + const char *s = src; |
| + char *d = dst; |
| + |
| + while (n-- > 0) |
| + if ((*d++ = *s++) == (char) c) |
| + return d; |
| + |
| + return NULL; |
| +} |
| + |
| +void * |
| +stupid_memccpy (void *dst, const void *src, int c, size_t n) |
| +{ |
| + void *p = memchr (src, c, n); |
| + |
| + if (p != NULL) |
| + return mempcpy (dst, src, p - src + 1); |
| + |
| + memcpy (dst, src, n); |
| + return NULL; |
| +} |
| + |
| +typedef void *(*proto_t) (void *, const void *, int c, size_t); |
| + |
| +static void |
| +do_one_test (impl_t *impl, void *dst, const void *src, int c, size_t len, |
| + size_t n) |
| +{ |
| + void *expect = len > n ? NULL : (char *) dst + len; |
| + if (CALL (impl, dst, src, c, n) != expect) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + CALL (impl, dst, src, c, n), expect); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (memcmp (dst, src, len > n ? n : len) != 0) |
| + { |
| + error (0, 0, "Wrong result in function %s", impl->name); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute__ ((unused)); |
| + hp_timing_t stop __attribute__ ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, dst, src, c, n); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, int c, size_t len, size_t n, |
| + int max_char) |
| +{ |
| + size_t i; |
| + char *s1, *s2; |
| + |
| + align1 &= 7; |
| + if (align1 + len >= page_size) |
| + return; |
| + |
| + align2 &= 7; |
| + if (align2 + len >= page_size) |
| + return; |
| + |
| + s1 = (char *) (buf1 + align1); |
| + s2 = (char *) (buf2 + align2); |
| + |
| + for (i = 0; i < len - 1; ++i) |
| + { |
| + s1[i] = 32 + 23 * i % (max_char - 32); |
| + if (s1[i] == (char) c) |
| + --s1[i]; |
| + } |
| + s1[len - 1] = c; |
| + for (i = len; i + align1 < page_size && i < len + 64; ++i) |
| + s1[i] = 32 + 32 * i % (max_char - 32); |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, n %4zd, char %d, alignment %2zd/%2zd:", len, n, c, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s2, s1, c, len, n); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%28s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, i, 12, 16, 16, 127); |
| + do_test (i, i, 23, 16, 16, 255); |
| + do_test (i, 2 * i, 28, 16, 16, 127); |
| + do_test (2 * i, i, 31, 16, 16, 255); |
| + do_test (8 - i, 2 * i, 1, 1 << i, 2 << i, 127); |
| + do_test (2 * i, 8 - i, 17, 2 << i, 1 << i, 127); |
| + do_test (8 - i, 2 * i, 0, 1 << i, 2 << i, 255); |
| + do_test (2 * i, 8 - i, i, 2 << i, 1 << i, 255); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 0, i, 4 << i, 8 << i, 127); |
| + do_test (0, 0, i, 16 << i, 8 << i, 127); |
| + do_test (8 - i, 2 * i, i, 4 << i, 8 << i, 127); |
| + do_test (8 - i, 2 * i, i, 16 << i, 8 << i, 127); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memccpy-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-memccpy-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of memccpy function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-memccpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memchr.c glibc-2.17-c758a686.new/benchtests/bench-memchr.c |
| |
| |
| @@ -0,0 +1,137 @@ |
| +/* Measure memchr functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "memchr" |
| +#include "bench-string.h" |
| + |
| +typedef char *(*proto_t) (const char *, int, size_t); |
| +char *simple_memchr (const char *, int, size_t); |
| + |
| +IMPL (simple_memchr, 0) |
| +IMPL (memchr, 1) |
| + |
| +char * |
| +simple_memchr (const char *s, int c, size_t n) |
| +{ |
| + while (n--) |
| + if (*s++ == (char) c) |
| + return (char *) s - 1; |
| + return NULL; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res) |
| +{ |
| + char *res = CALL (impl, s, c, n); |
| + if (res != exp_res) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + res, exp_res); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s, c, n); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align, size_t pos, size_t len, int seek_char) |
| +{ |
| + size_t i; |
| + char *result; |
| + |
| + align &= 7; |
| + if (align + len >= page_size) |
| + return; |
| + |
| + for (i = 0; i < len; ++i) |
| + { |
| + buf1[align + i] = 1 + 23 * i % 127; |
| + if (buf1[align + i] == seek_char) |
| + buf1[align + i] = seek_char + 1; |
| + } |
| + buf1[align + len] = 0; |
| + |
| + if (pos < len) |
| + { |
| + buf1[align + pos] = seek_char; |
| + buf1[align + len] = -seek_char; |
| + result = (char *) (buf1 + align + pos); |
| + } |
| + else |
| + { |
| + result = NULL; |
| + buf1[align + len] = seek_char; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd:", pos, align); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, (char *) (buf1 + align), seek_char, len, result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%20s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 16 << i, 2048, 23); |
| + do_test (i, 64, 256, 23); |
| + do_test (0, 16 << i, 2048, 0); |
| + do_test (i, 64, 256, 0); |
| + } |
| + for (i = 1; i < 32; ++i) |
| + { |
| + do_test (0, i, i + 1, 23); |
| + do_test (0, i, i + 1, 0); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memchr-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-memchr-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of memchr function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-memchr.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memcmp.c glibc-2.17-c758a686.new/benchtests/bench-memcmp.c |
| |
| |
| @@ -0,0 +1,183 @@ |
| +/* Measure memcmp functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#ifdef WIDE |
| +# define TEST_NAME "wmemcmp" |
| +#else |
| +# define TEST_NAME "memcmp" |
| +#endif |
| +#include "bench-string.h" |
| +#ifdef WIDE |
| +# include <inttypes.h> |
| +# include <wchar.h> |
| + |
| +# define MEMCMP wmemcmp |
| +# define MEMCPY wmemcpy |
| +# define SIMPLE_MEMCMP simple_wmemcmp |
| +# define CHAR wchar_t |
| +# define UCHAR wchar_t |
| +# define CHARBYTES 4 |
| +# define CHAR__MIN WCHAR_MIN |
| +# define CHAR__MAX WCHAR_MAX |
| +int |
| +simple_wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n) |
| +{ |
| + int ret = 0; |
| + /* Warning! |
| + wmemcmp has to use SIGNED comparison for elements. |
| + memcmp has to use UNSIGNED comparison for elemnts. |
| + */ |
| + while (n-- && (ret = *s1 < *s2 ? -1 : *s1 == *s2 ? 0 : 1) == 0) {s1++; s2++;} |
| + return ret; |
| +} |
| +#else |
| +# include <limits.h> |
| + |
| +# define MEMCMP memcmp |
| +# define MEMCPY memcpy |
| +# define SIMPLE_MEMCMP simple_memcmp |
| +# define CHAR char |
| +# define MAX_CHAR 255 |
| +# define UCHAR unsigned char |
| +# define CHARBYTES 1 |
| +# define CHAR__MIN CHAR_MIN |
| +# define CHAR__MAX CHAR_MAX |
| + |
| +int |
| +simple_memcmp (const char *s1, const char *s2, size_t n) |
| +{ |
| + int ret = 0; |
| + |
| + while (n-- && (ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) == 0); |
| + return ret; |
| +} |
| +#endif |
| + |
| +typedef int (*proto_t) (const CHAR *, const CHAR *, size_t); |
| + |
| +IMPL (SIMPLE_MEMCMP, 0) |
| +IMPL (MEMCMP, 1) |
| + |
| +static void |
| +do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t len, |
| + int exp_result) |
| +{ |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s1, s2, len); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len, int exp_result) |
| +{ |
| + size_t i; |
| + CHAR *s1, *s2; |
| + |
| + if (len == 0) |
| + return; |
| + |
| + align1 &= 63; |
| + if (align1 + (len + 1) * CHARBYTES >= page_size) |
| + return; |
| + |
| + align2 &= 63; |
| + if (align2 + (len + 1) * CHARBYTES >= page_size) |
| + return; |
| + |
| + s1 = (CHAR *) (buf1 + align1); |
| + s2 = (CHAR *) (buf2 + align2); |
| + |
| + for (i = 0; i < len; i++) |
| + s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % CHAR__MAX; |
| + |
| + s1[len] = align1; |
| + s2[len] = align2; |
| + s2[len - 1] -= exp_result; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s1, s2, len, exp_result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 16; ++i) |
| + { |
| + do_test (i * CHARBYTES, i * CHARBYTES, i, 0); |
| + do_test (i * CHARBYTES, i * CHARBYTES, i, 1); |
| + do_test (i * CHARBYTES, i * CHARBYTES, i, -1); |
| + } |
| + |
| + for (i = 0; i < 16; ++i) |
| + { |
| + do_test (0, 0, i, 0); |
| + do_test (0, 0, i, 1); |
| + do_test (0, 0, i, -1); |
| + } |
| + |
| + for (i = 1; i < 10; ++i) |
| + { |
| + do_test (0, 0, 2 << i, 0); |
| + do_test (0, 0, 2 << i, 1); |
| + do_test (0, 0, 2 << i, -1); |
| + do_test (0, 0, 16 << i, 0); |
| + do_test ((8 - i) * CHARBYTES, (2 * i) * CHARBYTES, 16 << i, 0); |
| + do_test (0, 0, 16 << i, 1); |
| + do_test (0, 0, 16 << i, -1); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 0); |
| + do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 1); |
| + do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, -1); |
| + } |
| + |
| + return ret; |
| +} |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memcmp-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-memcmp-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of memcmp function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-memcmp.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memcpy.c glibc-2.17-c758a686.new/benchtests/bench-memcpy.c |
| |
| |
| @@ -0,0 +1,163 @@ |
| +/* Measure memcpy functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#ifndef MEMCPY_RESULT |
| +# define MEMCPY_RESULT(dst, len) dst |
| +# define MIN_PAGE_SIZE 131072 |
| +# define TEST_MAIN |
| +# define TEST_NAME "memcpy" |
| +# include "bench-string.h" |
| + |
| +char *simple_memcpy (char *, const char *, size_t); |
| +char *builtin_memcpy (char *, const char *, size_t); |
| + |
| +IMPL (simple_memcpy, 0) |
| +IMPL (builtin_memcpy, 0) |
| +IMPL (memcpy, 1) |
| + |
| +char * |
| +simple_memcpy (char *dst, const char *src, size_t n) |
| +{ |
| + char *ret = dst; |
| + while (n--) |
| + *dst++ = *src++; |
| + return ret; |
| +} |
| + |
| +char * |
| +builtin_memcpy (char *dst, const char *src, size_t n) |
| +{ |
| + return __builtin_memcpy (dst, src, n); |
| +} |
| +#endif |
| + |
| +typedef char *(*proto_t) (char *, const char *, size_t); |
| + |
| +static void |
| +do_one_test (impl_t *impl, char *dst, const char *src, |
| + size_t len) |
| +{ |
| + if (CALL (impl, dst, src, len) != MEMCPY_RESULT (dst, len)) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + CALL (impl, dst, src, len), MEMCPY_RESULT (dst, len)); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (memcmp (dst, src, len) != 0) |
| + { |
| + error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", |
| + impl->name, dst, src); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, dst, src, len); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len) |
| +{ |
| + size_t i, j; |
| + char *s1, *s2; |
| + |
| + align1 &= 63; |
| + if (align1 + len >= page_size) |
| + return; |
| + |
| + align2 &= 63; |
| + if (align2 + len >= page_size) |
| + return; |
| + |
| + s1 = (char *) (buf1 + align1); |
| + s2 = (char *) (buf2 + align2); |
| + |
| + for (i = 0, j = 1; i < len; i++, j += 23) |
| + s1[i] = j; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s2, s1, len); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 0; i < 18; ++i) |
| + { |
| + do_test (0, 0, 1 << i); |
| + do_test (i, 0, 1 << i); |
| + do_test (0, i, 1 << i); |
| + do_test (i, i, 1 << i); |
| + } |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + do_test (0, 0, i); |
| + do_test (i, 0, i); |
| + do_test (0, i, i); |
| + do_test (i, i, i); |
| + } |
| + |
| + for (i = 3; i < 32; ++i) |
| + { |
| + if ((i & (i - 1)) == 0) |
| + continue; |
| + do_test (0, 0, 16 * i); |
| + do_test (i, 0, 16 * i); |
| + do_test (0, i, 16 * i); |
| + do_test (i, i, 16 * i); |
| + } |
| + |
| + do_test (0, 0, getpagesize ()); |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memcpy-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-memcpy-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of memcpy function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-memcpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memmem.c glibc-2.17-c758a686.new/benchtests/bench-memmem.c |
| |
| |
| @@ -0,0 +1,172 @@ |
| +/* Measure memmem functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "memmem" |
| +#define BUF1PAGES 20 |
| +#define ITERATIONS 500 |
| +#include "bench-string.h" |
| + |
| +typedef char *(*proto_t) (const void *, size_t, const void *, size_t); |
| +void *simple_memmem (const void *, size_t, const void *, size_t); |
| + |
| +IMPL (simple_memmem, 0) |
| +IMPL (memmem, 1) |
| + |
| +void * |
| +simple_memmem (const void *haystack, size_t haystack_len, const void *needle, |
| + size_t needle_len) |
| +{ |
| + const char *begin; |
| + const char *const last_possible |
| + = (const char *) haystack + haystack_len - needle_len; |
| + |
| + if (needle_len == 0) |
| + /* The first occurrence of the empty string is deemed to occur at |
| + the beginning of the string. */ |
| + return (void *) haystack; |
| + |
| + /* Sanity check, otherwise the loop might search through the whole |
| + memory. */ |
| + if (__builtin_expect (haystack_len < needle_len, 0)) |
| + return NULL; |
| + |
| + for (begin = (const char *) haystack; begin <= last_possible; ++begin) |
| + if (begin[0] == ((const char *) needle)[0] && |
| + !memcmp ((const void *) &begin[1], |
| + (const void *) ((const char *) needle + 1), |
| + needle_len - 1)) |
| + return (void *) begin; |
| + |
| + return NULL; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, const void *haystack, size_t haystack_len, |
| + const void *needle, size_t needle_len, const void *expected) |
| +{ |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, haystack, haystack_len, needle, needle_len); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (const char *str, size_t len, size_t idx) |
| +{ |
| + char tmpbuf[len]; |
| + |
| + memcpy (tmpbuf, buf1 + idx, len); |
| + memcpy (buf1 + idx, str, len); |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("String %s, offset %zd:", str, idx); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx); |
| + |
| + memcpy (buf1 + idx, tmpbuf, len); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +static void |
| +do_random_tests (void) |
| +{ |
| + for (size_t n = 0; n < ITERATIONS; ++n) |
| + { |
| + char tmpbuf[32]; |
| + |
| + size_t shift = random () % 11; |
| + size_t rel = random () % ((2 << (shift + 1)) * 64); |
| + size_t idx = MIN ((2 << shift) * 64 + rel, BUF1PAGES * page_size - 2); |
| + size_t len = random () % (sizeof (tmpbuf) - 1) + 1; |
| + len = MIN (len, BUF1PAGES * page_size - idx - 1); |
| + memcpy (tmpbuf, buf1 + idx, len); |
| + for (size_t i = random () % len / 2 + 1; i > 0; --i) |
| + { |
| + size_t off = random () % len; |
| + char ch = '0' + random () % 10; |
| + |
| + buf1[idx + off] = ch; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("String %.*s, offset %zd:", (int) len, buf1 + idx, idx); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len, |
| + buf1 + idx); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| + |
| + memcpy (buf1 + idx, tmpbuf, len); |
| + } |
| +} |
| + |
| +static const char *const strs[] = |
| + { |
| + "00000", "00112233", "0123456789", "0000111100001111", |
| + "00000111110000022222", "012345678901234567890", |
| + "abc0", "aaaa0", "abcabc0" |
| + }; |
| + |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 0; i < BUF1PAGES * page_size; ++i) |
| + buf1[i] = 60 + random () % 32; |
| + |
| + for (i = 0; i < sizeof (strs) / sizeof (strs[0]); ++i) |
| + for (size_t j = 0; j < 120; j += 7) |
| + { |
| + size_t len = strlen (strs[i]); |
| + |
| + do_test (strs[i], len, j); |
| + } |
| + |
| + do_random_tests (); |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memmem-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-memmem-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of memmem function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-memmem.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memmove.c glibc-2.17-c758a686.new/benchtests/bench-memmove.c |
| |
| |
| @@ -0,0 +1,188 @@ |
| +/* Measure memmove functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#ifdef TEST_BCOPY |
| +# define TEST_NAME "bcopy" |
| +#else |
| +# define TEST_NAME "memmove" |
| +#endif |
| +#include "bench-string.h" |
| + |
| +char *simple_memmove (char *, const char *, size_t); |
| + |
| +#ifdef TEST_BCOPY |
| +typedef void (*proto_t) (const char *, char *, size_t); |
| +void simple_bcopy (const char *, char *, size_t); |
| + |
| +IMPL (simple_bcopy, 0) |
| +IMPL (bcopy, 1) |
| + |
| +void |
| +simple_bcopy (const char *src, char *dst, size_t n) |
| +{ |
| + simple_memmove (dst, src, n); |
| +} |
| +#else |
| +typedef char *(*proto_t) (char *, const char *, size_t); |
| + |
| +IMPL (simple_memmove, 0) |
| +IMPL (memmove, 1) |
| +#endif |
| + |
| +char * |
| +inhibit_loop_to_libcall |
| +simple_memmove (char *dst, const char *src, size_t n) |
| +{ |
| + char *ret = dst; |
| + if (src < dst) |
| + { |
| + dst += n; |
| + src += n; |
| + while (n--) |
| + *--dst = *--src; |
| + } |
| + else |
| + while (n--) |
| + *dst++ = *src++; |
| + return ret; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src, |
| + size_t len) |
| +{ |
| + memcpy (src, orig_src, len); |
| +#ifdef TEST_BCOPY |
| + CALL (impl, src, dst, len); |
| +#else |
| + char *res; |
| + |
| + res = CALL (impl, dst, src, len); |
| + if (res != dst) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + res, dst); |
| + ret = 1; |
| + return; |
| + } |
| +#endif |
| + |
| + if (memcmp (dst, orig_src, len) != 0) |
| + { |
| + error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", |
| + impl->name, dst, src); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| +#ifdef TEST_BCOPY |
| + CALL (impl, src, dst, len); |
| +#else |
| + CALL (impl, dst, src, len); |
| +#endif |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len) |
| +{ |
| + size_t i, j; |
| + char *s1, *s2; |
| + |
| + align1 &= 63; |
| + if (align1 + len >= page_size) |
| + return; |
| + |
| + align2 &= 63; |
| + if (align2 + len >= page_size) |
| + return; |
| + |
| + s1 = (char *) (buf1 + align1); |
| + s2 = (char *) (buf2 + align2); |
| + |
| + for (i = 0, j = 1; i < len; i++, j += 23) |
| + s1[i] = j; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s2, (char *) (buf2 + align1), s1, len); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 0; i < 14; ++i) |
| + { |
| + do_test (0, 32, 1 << i); |
| + do_test (32, 0, 1 << i); |
| + do_test (0, i, 1 << i); |
| + do_test (i, 0, 1 << i); |
| + } |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + do_test (0, 32, i); |
| + do_test (32, 0, i); |
| + do_test (0, i, i); |
| + do_test (i, 0, i); |
| + } |
| + |
| + for (i = 3; i < 32; ++i) |
| + { |
| + if ((i & (i - 1)) == 0) |
| + continue; |
| + do_test (0, 32, 16 * i); |
| + do_test (32, 0, 16 * i); |
| + do_test (0, i, 16 * i); |
| + do_test (i, 0, 16 * i); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memmove-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-memmove-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of memmove function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-memmove.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-mempcpy.c glibc-2.17-c758a686.new/benchtests/bench-mempcpy.c |
| |
| |
| @@ -0,0 +1,37 @@ |
| +/* Measure mempcpy functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define MEMCPY_RESULT(dst, len) (dst) + (len) |
| +#define TEST_MAIN |
| +#define TEST_NAME "mempcpy" |
| +#include "bench-string.h" |
| + |
| +char *simple_mempcpy (char *, const char *, size_t); |
| + |
| +IMPL (simple_mempcpy, 0) |
| +IMPL (mempcpy, 1) |
| + |
| +char * |
| +simple_mempcpy (char *dst, const char *src, size_t n) |
| +{ |
| + while (n--) |
| + *dst++ = *src++; |
| + return dst; |
| +} |
| + |
| +#include "bench-memcpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-mempcpy-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-mempcpy-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of mempcpy function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-mempcpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memset.c glibc-2.17-c758a686.new/benchtests/bench-memset.c |
| |
| |
| @@ -0,0 +1,170 @@ |
| +/* Measure memset functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#ifdef TEST_BZERO |
| +# define TEST_NAME "bzero" |
| +#else |
| +# define TEST_NAME "memset" |
| +#endif |
| +#define MIN_PAGE_SIZE 131072 |
| +#include "bench-string.h" |
| + |
| +char *simple_memset (char *, int, size_t); |
| + |
| +#ifdef TEST_BZERO |
| +typedef void (*proto_t) (char *, size_t); |
| +void simple_bzero (char *, size_t); |
| +void builtin_bzero (char *, size_t); |
| + |
| +IMPL (simple_bzero, 0) |
| +IMPL (builtin_bzero, 0) |
| +IMPL (bzero, 1) |
| + |
| +void |
| +simple_bzero (char *s, size_t n) |
| +{ |
| + simple_memset (s, 0, n); |
| +} |
| + |
| +void |
| +builtin_bzero (char *s, size_t n) |
| +{ |
| + __builtin_bzero (s, n); |
| +} |
| +#else |
| +typedef char *(*proto_t) (char *, int, size_t); |
| +char *builtin_memset (char *, int, size_t); |
| + |
| +IMPL (simple_memset, 0) |
| +IMPL (builtin_memset, 0) |
| +IMPL (memset, 1) |
| + |
| +char * |
| +builtin_memset (char *s, int c, size_t n) |
| +{ |
| + return __builtin_memset (s, c, n); |
| +} |
| +#endif |
| + |
| +char * |
| +inhibit_loop_to_libcall |
| +simple_memset (char *s, int c, size_t n) |
| +{ |
| + char *r = s, *end = s + n; |
| + while (r < end) |
| + *r++ = c; |
| + return s; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, char *s, int c __attribute ((unused)), size_t n) |
| +{ |
| + char tstbuf[n]; |
| +#ifdef TEST_BZERO |
| + simple_bzero (tstbuf, n); |
| + CALL (impl, s, n); |
| + if (memcmp (s, tstbuf, n) != 0) |
| +#else |
| + char *res = CALL (impl, s, c, n); |
| + if (res != s |
| + || simple_memset (tstbuf, c, n) != tstbuf |
| + || memcmp (s, tstbuf, n) != 0) |
| +#endif |
| + { |
| + error (0, 0, "Wrong result in function %s", impl->name); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| +#ifdef TEST_BZERO |
| + CALL (impl, s, n); |
| +#else |
| + CALL (impl, s, c, n); |
| +#endif |
| + |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align, int c, size_t len) |
| +{ |
| + align &= 7; |
| + if (align + len > page_size) |
| + return; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, (char *) buf1 + align, c, len); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + int c = 0; |
| + |
| + test_init (); |
| + |
| + printf ("%24s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| +#ifndef TEST_BZERO |
| + for (c = -65; c <= 130; c += 65) |
| +#endif |
| + { |
| + for (i = 0; i < 18; ++i) |
| + do_test (0, c, 1 << i); |
| + for (i = 1; i < 32; ++i) |
| + { |
| + do_test (i, c, i); |
| + if (i & (i - 1)) |
| + do_test (0, c, i); |
| + } |
| + do_test (1, c, 14); |
| + do_test (3, c, 1024); |
| + do_test (4, c, 64); |
| + do_test (2, c, 25); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-memset-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-memset-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of memset function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-memset.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-modf.c glibc-2.17-c758a686.new/benchtests/bench-modf.c |
| |
| |
| @@ -0,0 +1,44 @@ |
| +/* Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +extern double modf (double, double *); |
| + |
| +#define CALL_BENCH_FUNC(j, i) modf (in[j].arg0, &i); |
| + |
| +struct args |
| +{ |
| + volatile double arg0; |
| +} in[] = |
| +{ |
| + { 42.42 }, |
| + { -42.42 } |
| +}; |
| + |
| +#define NUM_VARIANTS 1 |
| +#define NUM_SAMPLES(v) (sizeof (in) / sizeof (struct args)) |
| + |
| +static volatile double ret = 0.0; |
| +#define BENCH_FUNC(v, j) \ |
| +({ \ |
| + double iptr; \ |
| + ret = CALL_BENCH_FUNC (j, iptr); \ |
| +}) |
| + |
| +#define FUNCNAME "modf" |
| +#define VARIANT(v) FUNCNAME "()" |
| + |
| +#include "bench-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-rawmemchr.c glibc-2.17-c758a686.new/benchtests/bench-rawmemchr.c |
| |
| |
| @@ -0,0 +1,133 @@ |
| +/* Measure memchr functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#include <assert.h> |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "rawmemchr" |
| +#include "bench-string.h" |
| + |
| +typedef char *(*proto_t) (const char *, int); |
| +char *simple_rawmemchr (const char *, int); |
| + |
| +IMPL (simple_rawmemchr, 0) |
| +IMPL (rawmemchr, 1) |
| + |
| +char * |
| +simple_rawmemchr (const char *s, int c) |
| +{ |
| + while (1) |
| + if (*s++ == (char) c) |
| + return (char *) s - 1; |
| + return NULL; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s, int c, char *exp_res) |
| +{ |
| + char *res = CALL (impl, s, c); |
| + if (res != exp_res) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + res, exp_res); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s, c); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align, size_t pos, size_t len, int seek_char) |
| +{ |
| + size_t i; |
| + char *result; |
| + |
| + align &= 7; |
| + if (align + len >= page_size) |
| + return; |
| + |
| + for (i = 0; i < len; ++i) |
| + { |
| + buf1[align + i] = 1 + 23 * i % 127; |
| + if (buf1[align + i] == seek_char) |
| + buf1[align + i] = seek_char + 1; |
| + } |
| + buf1[align + len] = 0; |
| + |
| + assert (pos < len); |
| + |
| + buf1[align + pos] = seek_char; |
| + buf1[align + len] = -seek_char; |
| + result = (char *) (buf1 + align + pos); |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd:", pos, align); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, (char *) (buf1 + align), seek_char, result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%20s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 7; ++i) |
| + { |
| + do_test (0, 16 << i, 2048, 23); |
| + do_test (i, 64, 256, 23); |
| + do_test (0, 16 << i, 2048, 0); |
| + do_test (i, 64, 256, 0); |
| + } |
| + for (i = 1; i < 32; ++i) |
| + { |
| + do_test (0, i, i + 1, 23); |
| + do_test (0, i, i + 1, 0); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-rawmemchr-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-rawmemchr-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of rawmemchr function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-rawmemchr.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-skeleton.c glibc-2.17-c758a686.new/benchtests/bench-skeleton.c |
| |
| |
| @@ -0,0 +1,110 @@ |
| +/* Skeleton for benchmark programs. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#include <string.h> |
| +#include <stdint.h> |
| +#include <stdio.h> |
| +#include <time.h> |
| +#include <inttypes.h> |
| +#include "bench-timing.h" |
| + |
| +volatile unsigned int dontoptimize = 0; |
| + |
| +void |
| +startup (void) |
| +{ |
| + /* This loop should cause CPU to switch to maximal freqency. |
| + This makes subsequent measurement more accurate. We need a side effect |
| + to prevent the loop being deleted by compiler. |
| + This should be enough to cause CPU to speed up and it is simpler than |
| + running loop for constant time. This is used when user does not have root |
| + access to set a constant freqency. */ |
| + for (int k = 0; k < 10000000; k++) |
| + dontoptimize += 23 * dontoptimize + 2; |
| +} |
| + |
| +#define TIMESPEC_AFTER(a, b) \ |
| + (((a).tv_sec == (b).tv_sec) ? \ |
| + ((a).tv_nsec > (b).tv_nsec) : \ |
| + ((a).tv_sec > (b).tv_sec)) |
| +int |
| +main (int argc, char **argv) |
| +{ |
| + unsigned long i, k; |
| + struct timespec runtime; |
| + timing_t start, end; |
| + |
| + startup(); |
| + |
| + memset (&runtime, 0, sizeof (runtime)); |
| + |
| + unsigned long iters; |
| + |
| + TIMING_INIT (iters); |
| + |
| + for (int v = 0; v < NUM_VARIANTS; v++) |
| + { |
| + /* Run for approximately DURATION seconds. */ |
| + clock_gettime (CLOCK_MONOTONIC_RAW, &runtime); |
| + runtime.tv_sec += DURATION; |
| + |
| + double d_total_i = 0; |
| + timing_t total = 0, max = 0, min = 0x7fffffffffffffff; |
| + while (1) |
| + { |
| + for (i = 0; i < NUM_SAMPLES (v); i++) |
| + { |
| + uint64_t cur; |
| + TIMING_NOW (start); |
| + for (k = 0; k < iters; k++) |
| + BENCH_FUNC (v, i); |
| + TIMING_NOW (end); |
| + |
| + TIMING_DIFF (cur, start, end); |
| + |
| + if (cur > max) |
| + max = cur; |
| + |
| + if (cur < min) |
| + min = cur; |
| + |
| + TIMING_ACCUM (total, cur); |
| + |
| + d_total_i += iters; |
| + } |
| + struct timespec curtime; |
| + |
| + memset (&curtime, 0, sizeof (curtime)); |
| + clock_gettime (CLOCK_MONOTONIC_RAW, &curtime); |
| + if (TIMESPEC_AFTER (curtime, runtime)) |
| + goto done; |
| + } |
| + |
| + double d_total_s; |
| + double d_iters; |
| + |
| + done: |
| + d_total_s = total; |
| + d_iters = iters; |
| + |
| + TIMING_PRINT_STATS (VARIANT (v), d_total_s, d_iters, d_total_i, max, |
| + min); |
| + } |
| + |
| + return 0; |
| +} |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-stpcpy.c glibc-2.17-c758a686.new/benchtests/bench-stpcpy.c |
| |
| |
| @@ -0,0 +1,36 @@ |
| +/* Measure stpcpy functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define STRCPY_RESULT(dst, len) ((dst) + (len)) |
| +#define TEST_MAIN |
| +#define TEST_NAME "stpcpy" |
| +#include "bench-string.h" |
| + |
| +char *simple_stpcpy (char *, const char *); |
| + |
| +IMPL (simple_stpcpy, 0) |
| +IMPL (stpcpy, 1) |
| + |
| +char * |
| +simple_stpcpy (char *dst, const char *src) |
| +{ |
| + while ((*dst++ = *src++) != '\0'); |
| + return dst - 1; |
| +} |
| + |
| +#include "bench-strcpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-stpcpy_chk.c glibc-2.17-c758a686.new/benchtests/bench-stpcpy_chk.c |
| |
| |
| @@ -0,0 +1,45 @@ |
| +/* Measure stpcpy checking functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define STRCPY_RESULT(dst, len) ((dst) + (len)) |
| +#define TEST_MAIN |
| +#define TEST_NAME "stpcpy_chk" |
| +#include "bench-string.h" |
| + |
| +extern void __attribute__ ((noreturn)) __chk_fail (void); |
| +char *simple_stpcpy_chk (char *, const char *, size_t); |
| +extern char *normal_stpcpy (char *, const char *, size_t) |
| + __asm ("stpcpy"); |
| +extern char *__stpcpy_chk (char *, const char *, size_t); |
| + |
| +IMPL (simple_stpcpy_chk, 0) |
| +IMPL (normal_stpcpy, 1) |
| +IMPL (__stpcpy_chk, 2) |
| + |
| +char * |
| +simple_stpcpy_chk (char *dst, const char *src, size_t len) |
| +{ |
| + if (! len) |
| + __chk_fail (); |
| + while ((*dst++ = *src++) != '\0') |
| + if (--len == 0) |
| + __chk_fail (); |
| + return dst - 1; |
| +} |
| + |
| +#include "bench-strcpy_chk.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-stpcpy_chk-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-stpcpy_chk-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of stpcpy checking function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-stpcpy_chk.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-stpcpy-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-stpcpy-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of stpcpy function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-stpcpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-stpncpy.c glibc-2.17-c758a686.new/benchtests/bench-stpncpy.c |
| |
| |
| @@ -0,0 +1,59 @@ |
| +/* Measure stpncpy functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define STRNCPY_RESULT(dst, len, n) ((dst) + ((len) > (n) ? (n) : (len))) |
| +#define TEST_MAIN |
| +#define TEST_NAME "stpncpy" |
| +#include "bench-string.h" |
| + |
| +char *simple_stpncpy (char *, const char *, size_t); |
| +char *stupid_stpncpy (char *, const char *, size_t); |
| + |
| +IMPL (stupid_stpncpy, 0) |
| +IMPL (simple_stpncpy, 0) |
| +IMPL (stpncpy, 1) |
| + |
| +char * |
| +simple_stpncpy (char *dst, const char *src, size_t n) |
| +{ |
| + while (n--) |
| + if ((*dst++ = *src++) == '\0') |
| + { |
| + size_t i; |
| + |
| + for (i = 0; i < n; ++i) |
| + dst[i] = '\0'; |
| + return dst - 1; |
| + } |
| + return dst; |
| +} |
| + |
| +char * |
| +stupid_stpncpy (char *dst, const char *src, size_t n) |
| +{ |
| + size_t nc = strnlen (src, n); |
| + size_t i; |
| + |
| + for (i = 0; i < nc; ++i) |
| + dst[i] = src[i]; |
| + for (; i < n; ++i) |
| + dst[i] = '\0'; |
| + return dst + nc; |
| +} |
| + |
| +#include "bench-strncpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-stpncpy-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-stpncpy-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of stpncpy function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-stpncpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcasecmp.c glibc-2.17-c758a686.new/benchtests/bench-strcasecmp.c |
| |
| |
| @@ -0,0 +1,183 @@ |
| +/* Measure strcasecmp functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#include <ctype.h> |
| +#define TEST_MAIN |
| +#define TEST_NAME "strcasecmp" |
| +#include "bench-string.h" |
| + |
| +typedef int (*proto_t) (const char *, const char *); |
| +static int simple_strcasecmp (const char *, const char *); |
| +static int stupid_strcasecmp (const char *, const char *); |
| + |
| +IMPL (stupid_strcasecmp, 0) |
| +IMPL (simple_strcasecmp, 0) |
| +IMPL (strcasecmp, 1) |
| + |
| +static int |
| +simple_strcasecmp (const char *s1, const char *s2) |
| +{ |
| + int ret; |
| + |
| + while ((ret = ((unsigned char) tolower (*s1) |
| + - (unsigned char) tolower (*s2))) == 0 |
| + && *s1++) |
| + ++s2; |
| + return ret; |
| +} |
| + |
| +static int |
| +stupid_strcasecmp (const char *s1, const char *s2) |
| +{ |
| + size_t ns1 = strlen (s1) + 1, ns2 = strlen (s2) + 1; |
| + size_t n = ns1 < ns2 ? ns1 : ns2; |
| + int ret = 0; |
| + |
| + while (n--) |
| + { |
| + if ((ret = ((unsigned char) tolower (*s1) |
| + - (unsigned char) tolower (*s2))) != 0) |
| + break; |
| + ++s1; |
| + ++s2; |
| + } |
| + return ret; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result) |
| +{ |
| + int result = CALL (impl, s1, s2); |
| + if ((exp_result == 0 && result != 0) |
| + || (exp_result < 0 && result >= 0) |
| + || (exp_result > 0 && result <= 0)) |
| + { |
| + error (0, 0, "Wrong result in function %s %d %d", impl->name, |
| + result, exp_result); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s1, s2); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len, int max_char, |
| + int exp_result) |
| +{ |
| + size_t i; |
| + char *s1, *s2; |
| + |
| + if (len == 0) |
| + return; |
| + |
| + align1 &= 7; |
| + if (align1 + len + 1 >= page_size) |
| + return; |
| + |
| + align2 &= 7; |
| + if (align2 + len + 1 >= page_size) |
| + return; |
| + |
| + s1 = (char *) (buf1 + align1); |
| + s2 = (char *) (buf2 + align2); |
| + |
| + for (i = 0; i < len; i++) |
| + { |
| + s1[i] = toupper (1 + 23 * i % max_char); |
| + s2[i] = tolower (s1[i]); |
| + } |
| + |
| + s1[len] = s2[len] = 0; |
| + s1[len + 1] = 23; |
| + s2[len + 1] = 24 + exp_result; |
| + if ((s2[len - 1] == 'z' && exp_result == -1) |
| + || (s2[len - 1] == 'a' && exp_result == 1)) |
| + s1[len - 1] += exp_result; |
| + else |
| + s2[len - 1] -= exp_result; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s1, s2, exp_result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 16; ++i) |
| + { |
| + do_test (i, i, i, 127, 0); |
| + do_test (i, i, i, 127, 1); |
| + do_test (i, i, i, 127, -1); |
| + } |
| + |
| + for (i = 1; i < 10; ++i) |
| + { |
| + do_test (0, 0, 2 << i, 127, 0); |
| + do_test (0, 0, 2 << i, 254, 0); |
| + do_test (0, 0, 2 << i, 127, 1); |
| + do_test (0, 0, 2 << i, 254, 1); |
| + do_test (0, 0, 2 << i, 127, -1); |
| + do_test (0, 0, 2 << i, 254, -1); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 2 * i, 8 << i, 127, 0); |
| + do_test (2 * i, i, 8 << i, 254, 0); |
| + do_test (i, 2 * i, 8 << i, 127, 1); |
| + do_test (2 * i, i, 8 << i, 254, 1); |
| + do_test (i, 2 * i, 8 << i, 127, -1); |
| + do_test (2 * i, i, 8 << i, 254, -1); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcasecmp-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strcasecmp-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strcasecmp function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strcasecmp.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcasestr.c glibc-2.17-c758a686.new/benchtests/bench-strcasestr.c |
| |
| |
| @@ -0,0 +1,186 @@ |
| +/* Measure strcasestr functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "strcasestr" |
| +#include "bench-string.h" |
| + |
| + |
| +#define STRCASESTR simple_strcasestr |
| +#define NO_ALIAS |
| +#define __strncasecmp strncasecmp |
| +#include "../string/strcasestr.c" |
| + |
| + |
| +static char * |
| +stupid_strcasestr (const char *s1, const char *s2) |
| +{ |
| + ssize_t s1len = strlen (s1); |
| + ssize_t s2len = strlen (s2); |
| + |
| + if (s2len > s1len) |
| + return NULL; |
| + |
| + for (ssize_t i = 0; i <= s1len - s2len; ++i) |
| + { |
| + size_t j; |
| + for (j = 0; j < s2len; ++j) |
| + if (tolower (s1[i + j]) != tolower (s2[j])) |
| + break; |
| + if (j == s2len) |
| + return (char *) s1 + i; |
| + } |
| + |
| + return NULL; |
| +} |
| + |
| + |
| +typedef char *(*proto_t) (const char *, const char *); |
| + |
| +IMPL (stupid_strcasestr, 0) |
| +IMPL (simple_strcasestr, 0) |
| +IMPL (strcasestr, 1) |
| + |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) |
| +{ |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~(hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s1, s2); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len1, size_t len2, |
| + int fail) |
| +{ |
| + char *s1 = (char *) (buf1 + align1); |
| + char *s2 = (char *) (buf2 + align2); |
| + |
| + static const char d[] = "1234567890abcxyz"; |
| +#define dl (sizeof (d) - 1) |
| + char *ss2 = s2; |
| + for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0) |
| + { |
| + size_t t = l > dl ? dl : l; |
| + ss2 = mempcpy (ss2, d, t); |
| + } |
| + s2[len2] = '\0'; |
| + |
| + if (fail) |
| + { |
| + char *ss1 = s1; |
| + for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0) |
| + { |
| + size_t t = l > dl ? dl : l; |
| + memcpy (ss1, d, t); |
| + ++ss1[len2 > 7 ? 7 : len2 - 1]; |
| + ss1 += t; |
| + } |
| + } |
| + else |
| + { |
| + memset (s1, '0', len1); |
| + for (size_t i = 0; i < len2; ++i) |
| + s1[len1 - len2 + i] = toupper (s2[i]); |
| + } |
| + s1[len1] = '\0'; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", |
| + len1, len2, align1, align2, fail ? "fail" : "found"); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +static int |
| +test_main (void) |
| +{ |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (size_t klen = 2; klen < 32; ++klen) |
| + for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen) |
| + { |
| + do_test (0, 0, hlen, klen, 0); |
| + do_test (0, 0, hlen, klen, 1); |
| + do_test (0, 3, hlen, klen, 0); |
| + do_test (0, 3, hlen, klen, 1); |
| + do_test (0, 9, hlen, klen, 0); |
| + do_test (0, 9, hlen, klen, 1); |
| + do_test (0, 15, hlen, klen, 0); |
| + do_test (0, 15, hlen, klen, 1); |
| + |
| + do_test (3, 0, hlen, klen, 0); |
| + do_test (3, 0, hlen, klen, 1); |
| + do_test (3, 3, hlen, klen, 0); |
| + do_test (3, 3, hlen, klen, 1); |
| + do_test (3, 9, hlen, klen, 0); |
| + do_test (3, 9, hlen, klen, 1); |
| + do_test (3, 15, hlen, klen, 0); |
| + do_test (3, 15, hlen, klen, 1); |
| + |
| + do_test (9, 0, hlen, klen, 0); |
| + do_test (9, 0, hlen, klen, 1); |
| + do_test (9, 3, hlen, klen, 0); |
| + do_test (9, 3, hlen, klen, 1); |
| + do_test (9, 9, hlen, klen, 0); |
| + do_test (9, 9, hlen, klen, 1); |
| + do_test (9, 15, hlen, klen, 0); |
| + do_test (9, 15, hlen, klen, 1); |
| + |
| + do_test (15, 0, hlen, klen, 0); |
| + do_test (15, 0, hlen, klen, 1); |
| + do_test (15, 3, hlen, klen, 0); |
| + do_test (15, 3, hlen, klen, 1); |
| + do_test (15, 9, hlen, klen, 0); |
| + do_test (15, 9, hlen, klen, 1); |
| + do_test (15, 15, hlen, klen, 0); |
| + do_test (15, 15, hlen, klen, 1); |
| + } |
| + |
| + do_test (0, 0, page_size - 1, 16, 0); |
| + do_test (0, 0, page_size - 1, 16, 1); |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcasestr-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strcasestr-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strcasestr function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strcasestr.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcat.c glibc-2.17-c758a686.new/benchtests/bench-strcat.c |
| |
| |
| @@ -0,0 +1,155 @@ |
| +/* Measure strcat functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "strcat" |
| +#include "bench-string.h" |
| + |
| +typedef char *(*proto_t) (char *, const char *); |
| +char *simple_strcat (char *, const char *); |
| + |
| +IMPL (simple_strcat, 0) |
| +IMPL (strcat, 1) |
| + |
| +char * |
| +simple_strcat (char *dst, const char *src) |
| +{ |
| + char *ret = dst; |
| + while (*dst++ != '\0'); |
| + --dst; |
| + while ((*dst++ = *src++) != '\0'); |
| + return ret; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, char *dst, const char *src) |
| +{ |
| + size_t k = strlen (dst); |
| + if (CALL (impl, dst, src) != dst) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + CALL (impl, dst, src), dst); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (strcmp (dst + k, src) != 0) |
| + { |
| + error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", |
| + impl->name, dst, src); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + dst[k] = '\0'; |
| + HP_TIMING_NOW (start); |
| + CALL (impl, dst, src); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len1, size_t len2, int max_char) |
| +{ |
| + size_t i; |
| + char *s1, *s2; |
| + |
| + align1 &= 7; |
| + if (align1 + len1 >= page_size) |
| + return; |
| + |
| + align2 &= 7; |
| + if (align2 + len1 + len2 >= page_size) |
| + return; |
| + |
| + s1 = (char *) (buf1 + align1); |
| + s2 = (char *) (buf2 + align2); |
| + |
| + for (i = 0; i < len1; ++i) |
| + s1[i] = 32 + 23 * i % (max_char - 32); |
| + s1[len1] = '\0'; |
| + |
| + for (i = 0; i < len2; i++) |
| + s2[i] = 32 + 23 * i % (max_char - 32); |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len1, len2, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + { |
| + s2[len2] = '\0'; |
| + do_one_test (impl, s2, s1); |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%28s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 0; i < 16; ++i) |
| + { |
| + do_test (0, 0, i, i, 127); |
| + do_test (0, 0, i, i, 255); |
| + do_test (0, i, i, i, 127); |
| + do_test (i, 0, i, i, 255); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 0, 8 << i, 8 << i, 127); |
| + do_test (8 - i, 2 * i, 8 << i, 8 << i, 127); |
| + do_test (0, 0, 8 << i, 2 << i, 127); |
| + do_test (8 - i, 2 * i, 8 << i, 2 << i, 127); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 2 * i, 8 << i, 1, 127); |
| + do_test (2 * i, i, 8 << i, 1, 255); |
| + do_test (i, i, 8 << i, 10, 127); |
| + do_test (i, i, 8 << i, 10, 255); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcat-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strcat-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strcat function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strcat.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strchr.c glibc-2.17-c758a686.new/benchtests/bench-strchr.c |
| |
| |
| @@ -0,0 +1,206 @@ |
| +/* Measure STRCHR functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#ifndef WIDE |
| +# ifdef USE_FOR_STRCHRNUL |
| +# define TEST_NAME "strchrnul" |
| +# else |
| +# define TEST_NAME "strchr" |
| +# endif |
| +#else |
| +# define TEST_NAME "wcschr" |
| +#endif |
| +#include "bench-string.h" |
| + |
| +#ifndef WIDE |
| +# ifdef USE_FOR_STRCHRNUL |
| +# define STRCHR strchrnul |
| +# define stupid_STRCHR stupid_STRCHRNUL |
| +# define simple_STRCHR simple_STRCHRNUL |
| +# else |
| +# define STRCHR strchr |
| +# endif |
| +# define STRLEN strlen |
| +# define CHAR char |
| +# define BIG_CHAR CHAR_MAX |
| +# define MIDDLE_CHAR 127 |
| +# define SMALL_CHAR 23 |
| +# define UCHAR unsigned char |
| +#else |
| +# include <wchar.h> |
| +# define STRCHR wcschr |
| +# define STRLEN wcslen |
| +# define CHAR wchar_t |
| +# define BIG_CHAR WCHAR_MAX |
| +# define MIDDLE_CHAR 1121 |
| +# define SMALL_CHAR 851 |
| +# define UCHAR wchar_t |
| +#endif |
| + |
| +#ifdef USE_FOR_STRCHRNUL |
| +# define NULLRET(endptr) endptr |
| +#else |
| +# define NULLRET(endptr) NULL |
| +#endif |
| + |
| + |
| +typedef CHAR *(*proto_t) (const CHAR *, int); |
| + |
| +CHAR * |
| +simple_STRCHR (const CHAR *s, int c) |
| +{ |
| + for (; *s != (CHAR) c; ++s) |
| + if (*s == '\0') |
| + return NULLRET ((CHAR *) s); |
| + return (CHAR *) s; |
| +} |
| + |
| +CHAR * |
| +stupid_STRCHR (const CHAR *s, int c) |
| +{ |
| + size_t n = STRLEN (s) + 1; |
| + |
| + while (n--) |
| + if (*s++ == (CHAR) c) |
| + return (CHAR *) s - 1; |
| + return NULLRET ((CHAR *) s - 1); |
| +} |
| + |
| +IMPL (stupid_STRCHR, 0) |
| +IMPL (simple_STRCHR, 0) |
| +IMPL (STRCHR, 1) |
| + |
| +static void |
| +do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res) |
| +{ |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s, c); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char) |
| +/* For wcschr: align here means align not in bytes, |
| + but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)) |
| + len for wcschr here isn't in bytes but it's number of wchar_t symbols. */ |
| +{ |
| + size_t i; |
| + CHAR *result; |
| + CHAR *buf = (CHAR *) buf1; |
| + align &= 15; |
| + if ((align + len) * sizeof (CHAR) >= page_size) |
| + return; |
| + |
| + for (i = 0; i < len; ++i) |
| + { |
| + buf[align + i] = 32 + 23 * i % max_char; |
| + if (buf[align + i] == seek_char) |
| + buf[align + i] = seek_char + 1; |
| + else if (buf[align + i] == 0) |
| + buf[align + i] = 1; |
| + } |
| + buf[align + len] = 0; |
| + |
| + if (pos < len) |
| + { |
| + buf[align + pos] = seek_char; |
| + result = buf + align + pos; |
| + } |
| + else if (seek_char == 0) |
| + result = buf + align + len; |
| + else |
| + result = NULLRET (buf + align + len); |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment in bytes %2zd:", |
| + pos, align * sizeof (CHAR)); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, buf + align, seek_char, result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%20s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR); |
| + do_test (i, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 64, 256, SMALL_CHAR, MIDDLE_CHAR); |
| + do_test (i, 64, 256, SMALL_CHAR, BIG_CHAR); |
| + } |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + do_test (0, i, i + 1, SMALL_CHAR, MIDDLE_CHAR); |
| + do_test (0, i, i + 1, SMALL_CHAR, BIG_CHAR); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 16 << i, 2048, 0, MIDDLE_CHAR); |
| + do_test (i, 16 << i, 2048, 0, MIDDLE_CHAR); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 64, 256, 0, MIDDLE_CHAR); |
| + do_test (i, 64, 256, 0, BIG_CHAR); |
| + } |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + do_test (0, i, i + 1, 0, MIDDLE_CHAR); |
| + do_test (0, i, i + 1, 0, BIG_CHAR); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strchr-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strchr-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strchr function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strchr.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strchrnul.c glibc-2.17-c758a686.new/benchtests/bench-strchrnul.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure strchrnul function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define USE_FOR_STRCHRNUL 1 |
| +#include "bench-strchr.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strchrnul-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strchrnul-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strchrnul function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strchrnul.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcmp.c glibc-2.17-c758a686.new/benchtests/bench-strcmp.c |
| |
| |
| @@ -0,0 +1,247 @@ |
| +/* Measure strcmp and wcscmp functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#ifdef WIDE |
| +# define TEST_NAME "wcscmp" |
| +#else |
| +# define TEST_NAME "strcmp" |
| +#endif |
| +#include "bench-string.h" |
| + |
| +#ifdef WIDE |
| +# include <wchar.h> |
| + |
| +# define L(str) L##str |
| +# define STRCMP wcscmp |
| +# define STRCPY wcscpy |
| +# define STRLEN wcslen |
| +# define MEMCPY wmemcpy |
| +# define SIMPLE_STRCMP simple_wcscmp |
| +# define STUPID_STRCMP stupid_wcscmp |
| +# define CHAR wchar_t |
| +# define UCHAR wchar_t |
| +# define CHARBYTES 4 |
| +# define CHARBYTESLOG 2 |
| +# define CHARALIGN __alignof__ (CHAR) |
| +# define MIDCHAR 0x7fffffff |
| +# define LARGECHAR 0xfffffffe |
| +# define CHAR__MAX WCHAR_MAX |
| +# define CHAR__MIN WCHAR_MIN |
| + |
| +/* Wcscmp uses signed semantics for comparison, not unsigned */ |
| +/* Avoid using substraction since possible overflow */ |
| + |
| +int |
| +simple_wcscmp (const wchar_t *s1, const wchar_t *s2) |
| +{ |
| + wchar_t c1, c2; |
| + do |
| + { |
| + c1 = *s1++; |
| + c2 = *s2++; |
| + if (c2 == L'\0') |
| + return c1 - c2; |
| + } |
| + while (c1 == c2); |
| + |
| + return c1 < c2 ? -1 : 1; |
| +} |
| + |
| +int |
| +stupid_wcscmp (const wchar_t *s1, const wchar_t *s2) |
| +{ |
| + size_t ns1 = wcslen (s1) + 1; |
| + size_t ns2 = wcslen (s2) + 1; |
| + size_t n = ns1 < ns2 ? ns1 : ns2; |
| + int ret = 0; |
| + |
| + wchar_t c1, c2; |
| + |
| + while (n--) { |
| + c1 = *s1++; |
| + c2 = *s2++; |
| + if ((ret = c1 < c2 ? -1 : c1 == c2 ? 0 : 1) != 0) |
| + break; |
| + } |
| + return ret; |
| +} |
| + |
| +#else |
| +# include <limits.h> |
| + |
| +# define L(str) str |
| +# define STRCMP strcmp |
| +# define STRCPY strcpy |
| +# define STRLEN strlen |
| +# define MEMCPY memcpy |
| +# define SIMPLE_STRCMP simple_strcmp |
| +# define STUPID_STRCMP stupid_strcmp |
| +# define CHAR char |
| +# define UCHAR unsigned char |
| +# define CHARBYTES 1 |
| +# define CHARBYTESLOG 0 |
| +# define CHARALIGN 1 |
| +# define MIDCHAR 0x7f |
| +# define LARGECHAR 0xfe |
| +# define CHAR__MAX CHAR_MAX |
| +# define CHAR__MIN CHAR_MIN |
| + |
| +/* Strcmp uses unsigned semantics for comparison. */ |
| +int |
| +simple_strcmp (const char *s1, const char *s2) |
| +{ |
| + int ret; |
| + |
| + while ((ret = *(unsigned char *) s1 - *(unsigned char*) s2++) == 0 && *s1++); |
| + return ret; |
| +} |
| + |
| +int |
| +stupid_strcmp (const char *s1, const char *s2) |
| +{ |
| + size_t ns1 = strlen (s1) + 1; |
| + size_t ns2 = strlen (s2) + 1; |
| + size_t n = ns1 < ns2 ? ns1 : ns2; |
| + int ret = 0; |
| + |
| + while (n--) |
| + if ((ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) != 0) |
| + break; |
| + return ret; |
| +} |
| +#endif |
| + |
| +typedef int (*proto_t) (const CHAR *, const CHAR *); |
| + |
| +IMPL (STUPID_STRCMP, 1) |
| +IMPL (SIMPLE_STRCMP, 1) |
| +IMPL (STRCMP, 1) |
| + |
| +static void |
| +do_one_test (impl_t *impl, |
| + const CHAR *s1, const CHAR *s2, |
| + int exp_result) |
| +{ |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s1, s2); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len, int max_char, |
| + int exp_result) |
| +{ |
| + size_t i; |
| + |
| + CHAR *s1, *s2; |
| + |
| + if (len == 0) |
| + return; |
| + |
| + align1 &= 63; |
| + if (align1 + (len + 1) * CHARBYTES >= page_size) |
| + return; |
| + |
| + align2 &= 63; |
| + if (align2 + (len + 1) * CHARBYTES >= page_size) |
| + return; |
| + |
| + /* Put them close to the end of page. */ |
| + i = align1 + CHARBYTES * (len + 2); |
| + s1 = (CHAR *) (buf1 + ((page_size - i) / 16 * 16) + align1); |
| + i = align2 + CHARBYTES * (len + 2); |
| + s2 = (CHAR *) (buf2 + ((page_size - i) / 16 * 16) + align2); |
| + |
| + for (i = 0; i < len; i++) |
| + s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char; |
| + |
| + s1[len] = s2[len] = 0; |
| + s1[len + 1] = 23; |
| + s2[len + 1] = 24 + exp_result; |
| + s2[len - 1] -= exp_result; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s1, s2, exp_result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 32; ++i) |
| + { |
| + do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 0); |
| + do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 1); |
| + do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, -1); |
| + } |
| + |
| + for (i = 1; i < 10 + CHARBYTESLOG; ++i) |
| + { |
| + do_test (0, 0, 2 << i, MIDCHAR, 0); |
| + do_test (0, 0, 2 << i, LARGECHAR, 0); |
| + do_test (0, 0, 2 << i, MIDCHAR, 1); |
| + do_test (0, 0, 2 << i, LARGECHAR, 1); |
| + do_test (0, 0, 2 << i, MIDCHAR, -1); |
| + do_test (0, 0, 2 << i, LARGECHAR, -1); |
| + do_test (0, CHARBYTES * i, 2 << i, MIDCHAR, 1); |
| + do_test (CHARBYTES * i, CHARBYTES * (i + 1), 2 << i, LARGECHAR, 1); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 0); |
| + do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 0); |
| + do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 1); |
| + do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 1); |
| + do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, -1); |
| + do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, -1); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcmp-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strcmp-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strcmp function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strcmp.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcpy.c glibc-2.17-c758a686.new/benchtests/bench-strcpy.c |
| |
| |
| @@ -0,0 +1,183 @@ |
| +/* Measure strcpy functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#ifdef WIDE |
| +# include <wchar.h> |
| +# define CHAR wchar_t |
| +# define UCHAR wchar_t |
| +# define sfmt "ls" |
| +# define BIG_CHAR WCHAR_MAX |
| +# define SMALL_CHAR 1273 |
| +# define STRCMP wcscmp |
| +# define MEMCMP wmemcmp |
| +# define MEMSET wmemset |
| +#else |
| +# define CHAR char |
| +# define UCHAR unsigned char |
| +# define sfmt "s" |
| +# define BIG_CHAR CHAR_MAX |
| +# define SMALL_CHAR 127 |
| +# define STRCMP strcmp |
| +# define MEMCMP memcmp |
| +# define MEMSET memset |
| +#endif |
| + |
| +#ifndef STRCPY_RESULT |
| +# define STRCPY_RESULT(dst, len) dst |
| +# define TEST_MAIN |
| +# ifndef WIDE |
| +# define TEST_NAME "strcpy" |
| +# else |
| +# define TEST_NAME "wcscpy" |
| +# endif |
| +# include "bench-string.h" |
| +# ifndef WIDE |
| +# define SIMPLE_STRCPY simple_strcpy |
| +# define STRCPY strcpy |
| +# else |
| +# define SIMPLE_STRCPY simple_wcscpy |
| +# define STRCPY wcscpy |
| +# endif |
| + |
| +CHAR *SIMPLE_STRCPY (CHAR *, const CHAR *); |
| + |
| +IMPL (SIMPLE_STRCPY, 0) |
| +IMPL (STRCPY, 1) |
| + |
| +CHAR * |
| +SIMPLE_STRCPY (CHAR *dst, const CHAR *src) |
| +{ |
| + CHAR *ret = dst; |
| + while ((*dst++ = *src++) != '\0'); |
| + return ret; |
| +} |
| +#endif |
| + |
| +typedef CHAR *(*proto_t) (CHAR *, const CHAR *); |
| + |
| +static void |
| +do_one_test (impl_t *impl, CHAR *dst, const CHAR *src, |
| + size_t len __attribute__((unused))) |
| +{ |
| + if (CALL (impl, dst, src) != STRCPY_RESULT (dst, len)) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + CALL (impl, dst, src), STRCPY_RESULT (dst, len)); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (STRCMP (dst, src) != 0) |
| + { |
| + error (0, 0, |
| + "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"", |
| + impl->name, dst, src); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused));; |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, dst, src); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len, int max_char) |
| +{ |
| + size_t i; |
| + CHAR *s1, *s2; |
| +/* For wcscpy: align1 and align2 here mean alignment not in bytes, |
| + but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)) |
| + len for wcschr here isn't in bytes but it's number of wchar_t symbols. */ |
| + align1 &= 7; |
| + if ((align1 + len) * sizeof(CHAR) >= page_size) |
| + return; |
| + |
| + align2 &= 7; |
| + if ((align2 + len) * sizeof(CHAR) >= page_size) |
| + return; |
| + |
| + s1 = (CHAR *) (buf1) + align1; |
| + s2 = (CHAR *) (buf2) + align2; |
| + |
| + for (i = 0; i < len; i++) |
| + s1[i] = 32 + 23 * i % (max_char - 32); |
| + s1[len] = 0; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignments in bytes %2zd/%2zd:", len, align1 * sizeof(CHAR), align2 * sizeof(CHAR)); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s2, s1, len); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 0; i < 16; ++i) |
| + { |
| + do_test (0, 0, i, SMALL_CHAR); |
| + do_test (0, 0, i, BIG_CHAR); |
| + do_test (0, i, i, SMALL_CHAR); |
| + do_test (i, 0, i, BIG_CHAR); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 0, 8 << i, SMALL_CHAR); |
| + do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 2 * i, 8 << i, SMALL_CHAR); |
| + do_test (2 * i, i, 8 << i, BIG_CHAR); |
| + do_test (i, i, 8 << i, SMALL_CHAR); |
| + do_test (i, i, 8 << i, BIG_CHAR); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcpy_chk.c glibc-2.17-c758a686.new/benchtests/bench-strcpy_chk.c |
| |
| |
| @@ -0,0 +1,262 @@ |
| +/* Measure __strcpy_chk functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#ifndef STRCPY_RESULT |
| +# define STRCPY_RESULT(dst, len) dst |
| +# define TEST_MAIN |
| +# define TEST_NAME "strcpy_chk" |
| +# include "bench-string.h" |
| + |
| +/* This test case implicitly tests the availability of the __chk_fail |
| + symbol, which is part of the public ABI and may be used |
| + externally. */ |
| +extern void __attribute__ ((noreturn)) __chk_fail (void); |
| +char *simple_strcpy_chk (char *, const char *, size_t); |
| +extern char *normal_strcpy (char *, const char *, size_t) |
| + __asm ("strcpy"); |
| +extern char *__strcpy_chk (char *, const char *, size_t); |
| + |
| +IMPL (simple_strcpy_chk, 0) |
| +IMPL (normal_strcpy, 1) |
| +IMPL (__strcpy_chk, 2) |
| + |
| +char * |
| +simple_strcpy_chk (char *dst, const char *src, size_t len) |
| +{ |
| + char *ret = dst; |
| + if (! len) |
| + __chk_fail (); |
| + while ((*dst++ = *src++) != '\0') |
| + if (--len == 0) |
| + __chk_fail (); |
| + return ret; |
| +} |
| +#endif |
| + |
| +#include <fcntl.h> |
| +#include <paths.h> |
| +#include <setjmp.h> |
| +#include <signal.h> |
| + |
| +volatile int chk_fail_ok; |
| +jmp_buf chk_fail_buf; |
| + |
| +static void |
| +handler (int sig) |
| +{ |
| + if (chk_fail_ok) |
| + { |
| + chk_fail_ok = 0; |
| + longjmp (chk_fail_buf, 1); |
| + } |
| + else |
| + _exit (127); |
| +} |
| + |
| +typedef char *(*proto_t) (char *, const char *, size_t); |
| + |
| +static void |
| +do_one_test (impl_t *impl, char *dst, const char *src, |
| + size_t len, size_t dlen) |
| +{ |
| + char *res; |
| + if (dlen <= len) |
| + { |
| + if (impl->test == 1) |
| + return; |
| + |
| + chk_fail_ok = 1; |
| + if (setjmp (chk_fail_buf) == 0) |
| + { |
| + res = CALL (impl, dst, src, dlen); |
| + printf ("*** Function %s (%zd; %zd) did not __chk_fail\n", |
| + impl->name, len, dlen); |
| + chk_fail_ok = 0; |
| + ret = 1; |
| + } |
| + return; |
| + } |
| + else |
| + res = CALL (impl, dst, src, dlen); |
| + |
| + if (res != STRCPY_RESULT (dst, len)) |
| + { |
| + printf ("Wrong result in function %s %p %p\n", impl->name, |
| + res, STRCPY_RESULT (dst, len)); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (strcmp (dst, src) != 0) |
| + { |
| + printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n", |
| + impl->name, dst, src); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused));; |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, dst, src, dlen); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char) |
| +{ |
| + size_t i; |
| + char *s1, *s2; |
| + |
| + align1 &= 7; |
| + if (align1 + len >= page_size) |
| + return; |
| + |
| + align2 &= 7; |
| + if (align2 + len >= page_size) |
| + return; |
| + |
| + s1 = (char *) buf1 + align1; |
| + s2 = (char *) buf2 + align2; |
| + |
| + for (i = 0; i < len; i++) |
| + s1[i] = 32 + 23 * i % (max_char - 32); |
| + s1[len] = 0; |
| + |
| + if (HP_TIMING_AVAIL && dlen > len) |
| + printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s2, s1, len, dlen); |
| + |
| + if (HP_TIMING_AVAIL && dlen > len) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + struct sigaction sa; |
| + sa.sa_handler = handler; |
| + sa.sa_flags = 0; |
| + sigemptyset (&sa.sa_mask); |
| + |
| + sigaction (SIGABRT, &sa, NULL); |
| + |
| + /* Avoid all the buffer overflow messages on stderr. */ |
| + int fd = open (_PATH_DEVNULL, O_WRONLY); |
| + if (fd == -1) |
| + close (STDERR_FILENO); |
| + else |
| + { |
| + dup2 (fd, STDERR_FILENO); |
| + close (fd); |
| + } |
| + setenv ("LIBC_FATAL_STDERR_", "1", 1); |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 0; i < 16; ++i) |
| + { |
| + do_test (0, 0, i, i + 1, 127); |
| + do_test (0, 0, i, i + 1, 255); |
| + do_test (0, i, i, i + 1, 127); |
| + do_test (i, 0, i, i + 1, 255); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 0, 8 << i, (8 << i) + 1, 127); |
| + do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127); |
| + do_test (2 * i, i, (8 << i), (8 << i) + 1, 255); |
| + do_test (i, i, (8 << i), (8 << i) + 1, 127); |
| + do_test (i, i, (8 << i), (8 << i) + 1, 255); |
| + } |
| + |
| + for (i = 0; i < 16; ++i) |
| + { |
| + do_test (0, 0, i, i + 256, 127); |
| + do_test (0, 0, i, i + 256, 255); |
| + do_test (0, i, i, i + 256, 127); |
| + do_test (i, 0, i, i + 256, 255); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 0, 8 << i, (8 << i) + 256, 127); |
| + do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127); |
| + do_test (2 * i, i, (8 << i), (8 << i) + 256, 255); |
| + do_test (i, i, (8 << i), (8 << i) + 256, 127); |
| + do_test (i, i, (8 << i), (8 << i) + 256, 255); |
| + } |
| + |
| + for (i = 0; i < 16; ++i) |
| + { |
| + do_test (0, 0, i, i, 127); |
| + do_test (0, 0, i, i + 2, 255); |
| + do_test (0, i, i, i + 3, 127); |
| + do_test (i, 0, i, i + 4, 255); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 0, 8 << i, (8 << i) - 15, 127); |
| + do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 2 * i, (8 << i), (8 << i) + i, 127); |
| + do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255); |
| + do_test (i, i, (8 << i), (8 << i) + i + 2, 127); |
| + do_test (i, i, (8 << i), (8 << i) + i + 3, 255); |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcpy_chk-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strcpy_chk-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strcpy checking function. |
| + Copyright (C) 2012-2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strcpy_chk.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcpy-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strcpy-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strcpy function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strcpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcspn.c glibc-2.17-c758a686.new/benchtests/bench-strcspn.c |
| |
| |
| @@ -0,0 +1,59 @@ |
| +/* Measure strcspn functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define STRPBRK_RESULT(s, pos) (pos) |
| +#define RES_TYPE size_t |
| +#define TEST_MAIN |
| +#define TEST_NAME "strcspn" |
| +#include "bench-string.h" |
| + |
| +typedef size_t (*proto_t) (const char *, const char *); |
| +size_t simple_strcspn (const char *, const char *); |
| +size_t stupid_strcspn (const char *, const char *); |
| + |
| +IMPL (stupid_strcspn, 0) |
| +IMPL (simple_strcspn, 0) |
| +IMPL (strcspn, 1) |
| + |
| +size_t |
| +simple_strcspn (const char *s, const char *rej) |
| +{ |
| + const char *r, *str = s; |
| + char c; |
| + |
| + while ((c = *s++) != '\0') |
| + for (r = rej; *r != '\0'; ++r) |
| + if (*r == c) |
| + return s - str - 1; |
| + return s - str - 1; |
| +} |
| + |
| +size_t |
| +stupid_strcspn (const char *s, const char *rej) |
| +{ |
| + size_t ns = strlen (s), nrej = strlen (rej); |
| + size_t i, j; |
| + |
| + for (i = 0; i < ns; ++i) |
| + for (j = 0; j < nrej; ++j) |
| + if (s[i] == rej[j]) |
| + return i; |
| + return i; |
| +} |
| + |
| +#include "bench-strpbrk.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strcspn-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strcspn-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strcspn function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strcspn.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-string.h glibc-2.17-c758a686.new/benchtests/bench-string.h |
| |
| |
| @@ -0,0 +1,212 @@ |
| +/* Measure string and memory functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#include <sys/cdefs.h> |
| + |
| +typedef struct |
| +{ |
| + const char *name; |
| + void (*fn) (void); |
| + long test; |
| +} impl_t; |
| +extern impl_t __start_impls[], __stop_impls[]; |
| + |
| +#define IMPL(name, test) \ |
| + impl_t tst_ ## name \ |
| + __attribute__ ((section ("impls"), aligned (sizeof (void *)))) \ |
| + = { __STRING (name), (void (*) (void))name, test }; |
| + |
| +#ifdef TEST_MAIN |
| + |
| +# ifndef _GNU_SOURCE |
| +# define _GNU_SOURCE |
| +# endif |
| + |
| +# undef __USE_STRING_INLINES |
| + |
| +# include <stdio.h> |
| +# include <stdlib.h> |
| +# include <string.h> |
| +# include <sys/mman.h> |
| +# include <sys/param.h> |
| +# include <unistd.h> |
| +# include <fcntl.h> |
| +# include <error.h> |
| +# include <errno.h> |
| +# include <time.h> |
| +# include <ifunc-impl-list.h> |
| +# define GL(x) _##x |
| +# define GLRO(x) _##x |
| +# include <hp-timing.h> |
| + |
| + |
| +# define TEST_FUNCTION test_main () |
| +# define TIMEOUT (4 * 60) |
| +# define OPT_ITERATIONS 10000 |
| +# define OPT_RANDOM 10001 |
| +# define OPT_SEED 10002 |
| + |
| +unsigned char *buf1, *buf2; |
| +int ret, do_srandom; |
| +unsigned int seed; |
| +size_t page_size; |
| + |
| +hp_timing_t _dl_hp_timing_overhead; |
| + |
| +# ifndef ITERATIONS |
| +size_t iterations = 100000; |
| +# define ITERATIONS_OPTIONS \ |
| + { "iterations", required_argument, NULL, OPT_ITERATIONS }, |
| +# define ITERATIONS_PROCESS \ |
| + case OPT_ITERATIONS: \ |
| + iterations = strtoul (optarg, NULL, 0); \ |
| + break; |
| +# define ITERATIONS iterations |
| +# else |
| +# define ITERATIONS_OPTIONS |
| +# define ITERATIONS_PROCESS |
| +# endif |
| + |
| +# define CMDLINE_OPTIONS ITERATIONS_OPTIONS \ |
| + { "random", no_argument, NULL, OPT_RANDOM }, \ |
| + { "seed", required_argument, NULL, OPT_SEED }, |
| +# define CMDLINE_PROCESS ITERATIONS_PROCESS \ |
| + case OPT_RANDOM: \ |
| + { \ |
| + int fdr = open ("/dev/urandom", O_RDONLY); \ |
| + \ |
| + if (fdr < 0 || read (fdr, &seed, sizeof(seed)) != sizeof (seed)) \ |
| + seed = time (NULL); \ |
| + if (fdr >= 0) \ |
| + close (fdr); \ |
| + do_srandom = 1; \ |
| + break; \ |
| + } \ |
| + \ |
| + case OPT_SEED: \ |
| + seed = strtoul (optarg, NULL, 0); \ |
| + do_srandom = 1; \ |
| + break; |
| + |
| +# define CALL(impl, ...) \ |
| + (* (proto_t) (impl)->fn) (__VA_ARGS__) |
| + |
| +# if defined TEST_IFUNC && defined TEST_NAME |
| +/* Increase size of FUNC_LIST if assert is triggered at run-time. */ |
| +static struct libc_ifunc_impl func_list[32]; |
| +static int func_count; |
| +static int impl_count = -1; |
| +static impl_t *impl_array; |
| + |
| +# define FOR_EACH_IMPL(impl, notall) \ |
| + impl_t *impl; \ |
| + int count; \ |
| + if (impl_count == -1) \ |
| + { \ |
| + impl_count = 0; \ |
| + if (func_count != 0) \ |
| + { \ |
| + int f; \ |
| + impl_t *skip = NULL, *a; \ |
| + for (impl = __start_impls; impl < __stop_impls; ++impl) \ |
| + if (strcmp (impl->name, TEST_NAME) == 0) \ |
| + skip = impl; \ |
| + else \ |
| + impl_count++; \ |
| + a = impl_array = malloc ((impl_count + func_count) * \ |
| + sizeof (impl_t)); \ |
| + for (impl = __start_impls; impl < __stop_impls; ++impl) \ |
| + if (impl != skip) \ |
| + *a++ = *impl; \ |
| + for (f = 0; f < func_count; f++) \ |
| + if (func_list[f].usable) \ |
| + { \ |
| + a->name = func_list[f].name; \ |
| + a->fn = func_list[f].fn; \ |
| + a->test = 1; \ |
| + a++; \ |
| + } \ |
| + impl_count = a - impl_array; \ |
| + } \ |
| + else \ |
| + { \ |
| + impl_count = __stop_impls - __start_impls; \ |
| + impl_array = __start_impls; \ |
| + } \ |
| + } \ |
| + impl = impl_array; \ |
| + for (count = 0; count < impl_count; ++count, ++impl) \ |
| + if (!notall || impl->test) |
| +# else /* ! (defined TEST_IFUNC && defined TEST_NAME) */ |
| +# define FOR_EACH_IMPL(impl, notall) \ |
| + for (impl_t *impl = __start_impls; impl < __stop_impls; ++impl) \ |
| + if (!notall || impl->test) |
| +# endif /* ! (defined TEST_IFUNC && defined TEST_NAME) */ |
| + |
| +# define HP_TIMING_BEST(best_time, start, end) \ |
| + do \ |
| + { \ |
| + hp_timing_t tmptime; \ |
| + HP_TIMING_DIFF (tmptime, start + _dl_hp_timing_overhead, end); \ |
| + if (best_time > tmptime) \ |
| + best_time = tmptime; \ |
| + } \ |
| + while (0) |
| + |
| +# ifndef BUF1PAGES |
| +# define BUF1PAGES 1 |
| +# endif |
| + |
| +static void |
| +test_init (void) |
| +{ |
| +# if defined TEST_IFUNC && defined TEST_NAME |
| + func_count = __libc_ifunc_impl_list (TEST_NAME, func_list, |
| + (sizeof func_list |
| + / sizeof func_list[0])); |
| +# endif |
| + |
| + page_size = 2 * getpagesize (); |
| +# ifdef MIN_PAGE_SIZE |
| + if (page_size < MIN_PAGE_SIZE) |
| + page_size = MIN_PAGE_SIZE; |
| +# endif |
| + buf1 = mmap (0, (BUF1PAGES + 1) * page_size, PROT_READ | PROT_WRITE, |
| + MAP_PRIVATE | MAP_ANON, -1, 0); |
| + if (buf1 == MAP_FAILED) |
| + error (EXIT_FAILURE, errno, "mmap failed"); |
| + if (mprotect (buf1 + BUF1PAGES * page_size, page_size, PROT_NONE)) |
| + error (EXIT_FAILURE, errno, "mprotect failed"); |
| + buf2 = mmap (0, 2 * page_size, PROT_READ | PROT_WRITE, |
| + MAP_PRIVATE | MAP_ANON, -1, 0); |
| + if (buf2 == MAP_FAILED) |
| + error (EXIT_FAILURE, errno, "mmap failed"); |
| + if (mprotect (buf2 + page_size, page_size, PROT_NONE)) |
| + error (EXIT_FAILURE, errno, "mprotect failed"); |
| + HP_TIMING_DIFF_INIT (); |
| + if (do_srandom) |
| + { |
| + printf ("Setting seed to 0x%x\n", seed); |
| + srandom (seed); |
| + } |
| + |
| + memset (buf1, 0xa5, BUF1PAGES * page_size); |
| + memset (buf2, 0x5a, page_size); |
| +} |
| + |
| +#endif /* TEST_MAIN */ |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strlen.c glibc-2.17-c758a686.new/benchtests/bench-strlen.c |
| |
| |
| @@ -0,0 +1,149 @@ |
| +/* Measure STRLEN functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#ifndef WIDE |
| +# define TEST_NAME "strlen" |
| +#else |
| +# define TEST_NAME "wcslen" |
| +#endif |
| +#include "bench-string.h" |
| + |
| +#ifndef WIDE |
| +# define STRLEN strlen |
| +# define CHAR char |
| +# define MAX_CHAR CHAR_MAX |
| +#else |
| +# include <wchar.h> |
| +# define STRLEN wcslen |
| +# define CHAR wchar_t |
| +# define MAX_CHAR WCHAR_MAX |
| +#endif |
| + |
| +typedef size_t (*proto_t) (const CHAR *); |
| + |
| +size_t |
| +simple_STRLEN (const CHAR *s) |
| +{ |
| + const CHAR *p; |
| + |
| + for (p = s; *p; ++p); |
| + return p - s; |
| +} |
| + |
| +#ifndef WIDE |
| +size_t |
| +builtin_strlen (const CHAR *p) |
| +{ |
| + return __builtin_strlen (p); |
| +} |
| +IMPL (builtin_strlen, 0) |
| +#endif |
| + |
| +IMPL (simple_STRLEN, 0) |
| +IMPL (STRLEN, 1) |
| + |
| + |
| +static void |
| +do_one_test (impl_t *impl, const CHAR *s, size_t exp_len) |
| +{ |
| + size_t len = CALL (impl, s); |
| + if (len != exp_len) |
| + { |
| + error (0, 0, "Wrong result in function %s %zd %zd", impl->name, |
| + len, exp_len); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align, size_t len) |
| +{ |
| + size_t i; |
| + |
| + align &= 63; |
| + if (align + sizeof(CHAR) * len >= page_size) |
| + return; |
| + |
| + CHAR *buf = (CHAR *) (buf1); |
| + |
| + for (i = 0; i < len; ++i) |
| + buf[align + i] = 1 + 11111 * i % MAX_CHAR; |
| + buf[align + len] = 0; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd:", len, align); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, (CHAR *) (buf + align), len); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%20s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + /* Checking with only 4 * N alignments for wcslen, other alignments are wrong for wchar_t type arrays*/ |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (sizeof(CHAR) * i, i); |
| + do_test (0, i); |
| + } |
| + |
| + for (i = 2; i <= 12; ++i) |
| + { |
| + do_test (0, 1 << i); |
| + do_test (sizeof(CHAR) * 7, 1 << i); |
| + do_test (sizeof(CHAR) * i, 1 << i); |
| + do_test (sizeof(CHAR) * i, (size_t)((1 << i) / 1.5)); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strlen-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strlen-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strlen function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strlen.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strncasecmp.c glibc-2.17-c758a686.new/benchtests/bench-strncasecmp.c |
| |
| |
| @@ -0,0 +1,213 @@ |
| +/* Measure strncasecmp functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#include <ctype.h> |
| +#define TEST_MAIN |
| +#define TEST_NAME "strncasecmp" |
| +#include "bench-string.h" |
| + |
| +typedef int (*proto_t) (const char *, const char *, size_t); |
| +static int simple_strncasecmp (const char *, const char *, size_t); |
| +static int stupid_strncasecmp (const char *, const char *, size_t); |
| + |
| +IMPL (stupid_strncasecmp, 0) |
| +IMPL (simple_strncasecmp, 0) |
| +IMPL (strncasecmp, 1) |
| + |
| +static int |
| +simple_strncasecmp (const char *s1, const char *s2, size_t n) |
| +{ |
| + int ret; |
| + |
| + if (n == 0) |
| + return 0; |
| + |
| + while ((ret = ((unsigned char) tolower (*s1) |
| + - (unsigned char) tolower (*s2))) == 0 |
| + && *s1++) |
| + { |
| + if (--n == 0) |
| + return 0; |
| + ++s2; |
| + } |
| + return ret; |
| +} |
| + |
| +static int |
| +stupid_strncasecmp (const char *s1, const char *s2, size_t max) |
| +{ |
| + size_t ns1 = strlen (s1) + 1; |
| + size_t ns2 = strlen (s2) + 1; |
| + size_t n = ns1 < ns2 ? ns1 : ns2; |
| + if (n > max) |
| + n = max; |
| + int ret = 0; |
| + |
| + while (n--) |
| + { |
| + if ((ret = ((unsigned char) tolower (*s1) |
| + - (unsigned char) tolower (*s2))) != 0) |
| + break; |
| + ++s1; |
| + ++s2; |
| + } |
| + return ret; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, |
| + int exp_result) |
| +{ |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s1, s2, n); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char, |
| + int exp_result) |
| +{ |
| + size_t i; |
| + char *s1, *s2; |
| + |
| + if (len == 0) |
| + return; |
| + |
| + align1 &= 7; |
| + if (align1 + len + 1 >= page_size) |
| + return; |
| + |
| + align2 &= 7; |
| + if (align2 + len + 1 >= page_size) |
| + return; |
| + |
| + s1 = (char *) (buf1 + align1); |
| + s2 = (char *) (buf2 + align2); |
| + |
| + for (i = 0; i < len; i++) |
| + { |
| + s1[i] = toupper (1 + 23 * i % max_char); |
| + s2[i] = tolower (s1[i]); |
| + } |
| + |
| + s1[len] = s2[len] = 0; |
| + s1[len + 1] = 23; |
| + s2[len + 1] = 24 + exp_result; |
| + if ((s2[len - 1] == 'z' && exp_result == -1) |
| + || (s2[len - 1] == 'a' && exp_result == 1)) |
| + s1[len - 1] += exp_result; |
| + else |
| + s2[len - 1] -= exp_result; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s1, s2, n, exp_result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 16; ++i) |
| + { |
| + do_test (i, i, i - 1, i, 127, 0); |
| + |
| + do_test (i, i, i, i, 127, 0); |
| + do_test (i, i, i, i, 127, 1); |
| + do_test (i, i, i, i, 127, -1); |
| + |
| + do_test (i, i, i + 1, i, 127, 0); |
| + do_test (i, i, i + 1, i, 127, 1); |
| + do_test (i, i, i + 1, i, 127, -1); |
| + } |
| + |
| + for (i = 1; i < 10; ++i) |
| + { |
| + do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0); |
| + do_test (0, 0, 2 << i, 2 << i, 254, 0); |
| + do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0); |
| + |
| + do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0); |
| + |
| + do_test (0, 0, 2 << i, 2 << i, 127, 1); |
| + do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1); |
| + |
| + do_test (0, 0, 2 << i, 2 << i, 254, 1); |
| + do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1); |
| + |
| + do_test (0, 0, 2 << i, 2 << i, 127, -1); |
| + do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1); |
| + |
| + do_test (0, 0, 2 << i, 2 << i, 254, -1); |
| + do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0); |
| + do_test (i, 2 * i, 8 << i, 8 << i, 127, 0); |
| + do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0); |
| + |
| + do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0); |
| + do_test (2 * i, i, 8 << i, 8 << i, 254, 0); |
| + do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0); |
| + |
| + do_test (i, 2 * i, 8 << i, 8 << i, 127, 1); |
| + do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1); |
| + |
| + do_test (2 * i, i, 8 << i, 8 << i, 254, 1); |
| + do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1); |
| + |
| + do_test (i, 2 * i, 8 << i, 8 << i, 127, -1); |
| + do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1); |
| + |
| + do_test (2 * i, i, 8 << i, 8 << i, 254, -1); |
| + do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strncasecmp-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strncasecmp-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strncasecmp function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strncasecmp.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strncat.c glibc-2.17-c758a686.new/benchtests/bench-strncat.c |
| |
| |
| @@ -0,0 +1,168 @@ |
| +/* Measure strncat functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "strncat" |
| +#include "bench-string.h" |
| + |
| +typedef char *(*proto_t) (char *, const char *, size_t); |
| +char *stupid_strncat (char *, const char *, size_t); |
| +char *simple_strncat (char *, const char *, size_t); |
| + |
| +IMPL (stupid_strncat, 0) |
| +IMPL (strncat, 2) |
| + |
| +char * |
| +stupid_strncat (char *dst, const char *src, size_t n) |
| +{ |
| + char *ret = dst; |
| + while (*dst++ != '\0'); |
| + --dst; |
| + while (n--) |
| + if ( (*dst++ = *src++) == '\0') |
| + return ret; |
| + *dst = '\0'; |
| + return ret; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, char *dst, const char *src, size_t n) |
| +{ |
| + size_t k = strlen (dst); |
| + if (CALL (impl, dst, src, n) != dst) |
| + { |
| + error (0, 0, "Wrong result in function %s %p != %p", impl->name, |
| + CALL (impl, dst, src, n), dst); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + size_t len = strlen (src); |
| + if (memcmp (dst + k, src, len + 1 > n ? n : len + 1) != 0) |
| + { |
| + error (0, 0, "Incorrect cancatination in function %s", |
| + impl->name); |
| + ret = 1; |
| + return; |
| + } |
| + if (n < len && dst[k + n] != '\0') |
| + { |
| + error (0, 0, "There is no zero in the end of output string in %s", |
| + impl->name); |
| + ret = 1; |
| + return; |
| + } |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + dst[k] = '\0'; |
| + HP_TIMING_NOW (start); |
| + CALL (impl, dst, src, n); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len1, size_t len2, |
| + size_t n, int max_char) |
| +{ |
| + size_t i; |
| + char *s1, *s2; |
| + |
| + align1 &= 7; |
| + if (align1 + len1 >= page_size) |
| + return; |
| + if (align1 + n > page_size) |
| + return; |
| + align2 &= 7; |
| + if (align2 + len1 + len2 >= page_size) |
| + return; |
| + if (align2 + len1 + n > page_size) |
| + return; |
| + s1 = (char *) (buf1 + align1); |
| + s2 = (char *) (buf2 + align2); |
| + |
| + for (i = 0; i < len1; ++i) |
| + s1[i] = 32 + 23 * i % (max_char - 32); |
| + s1[len1] = '\0'; |
| + |
| + for (i = 0; i < len2; i++) |
| + s2[i] = 32 + 23 * i % (max_char - 32); |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd/%4zd, alignment %2zd/%2zd, N %4zd:", |
| + len1, len2, align1, align2, n); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + { |
| + s2[len2] = '\0'; |
| + do_one_test (impl, s2, s1, n); |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +main (void) |
| +{ |
| + size_t i, n; |
| + |
| + test_init (); |
| + |
| + printf ("%28s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (n = 2; n <= 2048; n*=4) |
| + { |
| + do_test (0, 2, 2, 2, n, 127); |
| + do_test (0, 0, 4, 4, n, 127); |
| + do_test (4, 0, 4, 4, n, 255); |
| + do_test (0, 0, 8, 8, n, 127); |
| + do_test (0, 8, 8, 8, n, 127); |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 0, 8 << i, 8 << i, n, 127); |
| + do_test (8 - i, 2 * i, 8 << i, 8 << i, n, 127); |
| + do_test (0, 0, 8 << i, 2 << i, n, 127); |
| + do_test (8 - i, 2 * i, 8 << i, 2 << i, n, 127); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 2 * i, 8 << i, 1, n, 127); |
| + do_test (2 * i, i, 8 << i, 1, n, 255); |
| + do_test (i, i, 8 << i, 10, n, 127); |
| + } |
| + } |
| + |
| + return ret; |
| +} |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strncat-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strncat-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strncat function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strncat.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strncmp.c glibc-2.17-c758a686.new/benchtests/bench-strncmp.c |
| |
| |
| @@ -0,0 +1,249 @@ |
| +/* Measure strncmp functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "strncmp" |
| +#include "bench-string.h" |
| + |
| +typedef int (*proto_t) (const char *, const char *, size_t); |
| +int simple_strncmp (const char *, const char *, size_t); |
| +int stupid_strncmp (const char *, const char *, size_t); |
| + |
| +IMPL (stupid_strncmp, 0) |
| +IMPL (simple_strncmp, 0) |
| +IMPL (strncmp, 1) |
| + |
| +int |
| +simple_strncmp (const char *s1, const char *s2, size_t n) |
| +{ |
| + int ret = 0; |
| + |
| + while (n-- && (ret = *(unsigned char *) s1 - * (unsigned char *) s2++) == 0 |
| + && *s1++); |
| + return ret; |
| +} |
| + |
| +int |
| +stupid_strncmp (const char *s1, const char *s2, size_t n) |
| +{ |
| + size_t ns1 = strnlen (s1, n) + 1, ns2 = strnlen (s2, n) + 1; |
| + int ret = 0; |
| + |
| + n = ns1 < n ? ns1 : n; |
| + n = ns2 < n ? ns2 : n; |
| + while (n-- && (ret = *(unsigned char *) s1++ - * (unsigned char *) s2++) == 0); |
| + return ret; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, |
| + int exp_result) |
| +{ |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s1, s2, n); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char, |
| + int exp_result) |
| +{ |
| + size_t i, align_n; |
| + char *s1, *s2; |
| + |
| + if (n == 0) |
| + { |
| + s1 = (char*)(buf1 + page_size); |
| + s2 = (char*)(buf2 + page_size); |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd/%4zd:", len, n); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s1, s2, n, 0); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| + |
| + return; |
| + } |
| + |
| + align1 &= 15; |
| + align2 &= 15; |
| + align_n = (page_size - n) & 15; |
| + |
| + s1 = (char*)(buf1 + page_size - n); |
| + s2 = (char*)(buf2 + page_size - n); |
| + |
| + if (align1 < align_n) |
| + s1 -= (align_n - align1); |
| + |
| + if (align2 < align_n) |
| + s2 -= (align_n - align2); |
| + |
| + for (i = 0; i < n; i++) |
| + s1[i] = s2[i] = 1 + 23 * i % max_char; |
| + |
| + if (len < n) |
| + { |
| + s1[len] = 0; |
| + s2[len] = 0; |
| + if (exp_result < 0) |
| + s2[len] = 32; |
| + else if (exp_result > 0) |
| + s1[len] = 64; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s1, s2, n, exp_result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, |
| + int exp_result) |
| +{ |
| + size_t i; |
| + char *s1, *s2; |
| + |
| + if (n == 0) |
| + return; |
| + |
| + align1 &= 7; |
| + if (align1 + n + 1 >= page_size) |
| + return; |
| + |
| + align2 &= 7; |
| + if (align2 + n + 1 >= page_size) |
| + return; |
| + |
| + s1 = (char*)(buf1 + align1); |
| + s2 = (char*)(buf2 + align2); |
| + |
| + for (i = 0; i < n; i++) |
| + s1[i] = s2[i] = 1 + 23 * i % max_char; |
| + |
| + s1[n] = 24 + exp_result; |
| + s2[n] = 23; |
| + s1[len] = 0; |
| + s2[len] = 0; |
| + if (exp_result < 0) |
| + s2[len] = 32; |
| + else if (exp_result > 0) |
| + s1[len] = 64; |
| + if (len >= n) |
| + s2[n - 1] -= exp_result; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, (char*)s1, (char*)s2, n, exp_result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i =0; i < 16; ++i) |
| + { |
| + do_test (0, 0, 8, i, 127, 0); |
| + do_test (0, 0, 8, i, 127, -1); |
| + do_test (0, 0, 8, i, 127, 1); |
| + do_test (i, i, 8, i, 127, 0); |
| + do_test (i, i, 8, i, 127, 1); |
| + do_test (i, i, 8, i, 127, -1); |
| + do_test (i, 2 * i, 8, i, 127, 0); |
| + do_test (2 * i, i, 8, i, 127, 1); |
| + do_test (i, 3 * i, 8, i, 127, -1); |
| + do_test (0, 0, 8, i, 255, 0); |
| + do_test (0, 0, 8, i, 255, -1); |
| + do_test (0, 0, 8, i, 255, 1); |
| + do_test (i, i, 8, i, 255, 0); |
| + do_test (i, i, 8, i, 255, 1); |
| + do_test (i, i, 8, i, 255, -1); |
| + do_test (i, 2 * i, 8, i, 255, 0); |
| + do_test (2 * i, i, 8, i, 255, 1); |
| + do_test (i, 3 * i, 8, i, 255, -1); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 0, 8 << i, 16 << i, 127, 0); |
| + do_test (0, 0, 8 << i, 16 << i, 127, 1); |
| + do_test (0, 0, 8 << i, 16 << i, 127, -1); |
| + do_test (0, 0, 8 << i, 16 << i, 255, 0); |
| + do_test (0, 0, 8 << i, 16 << i, 255, 1); |
| + do_test (0, 0, 8 << i, 16 << i, 255, -1); |
| + do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 0); |
| + do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 1); |
| + do_test (2 * i, i, 8 << i, 16 << i, 255, 0); |
| + do_test (2 * i, i, 8 << i, 16 << i, 255, 1); |
| + } |
| + |
| + do_test_limit (0, 0, 0, 0, 127, 0); |
| + do_test_limit (4, 0, 21, 20, 127, 0); |
| + do_test_limit (0, 4, 21, 20, 127, 0); |
| + do_test_limit (8, 0, 25, 24, 127, 0); |
| + do_test_limit (0, 8, 25, 24, 127, 0); |
| + |
| + for (i = 0; i < 8; ++i) |
| + { |
| + do_test_limit (0, 0, 17 - i, 16 - i, 127, 0); |
| + do_test_limit (0, 0, 17 - i, 16 - i, 255, 0); |
| + do_test_limit (0, 0, 15 - i, 16 - i, 127, 0); |
| + do_test_limit (0, 0, 15 - i, 16 - i, 127, 1); |
| + do_test_limit (0, 0, 15 - i, 16 - i, 127, -1); |
| + do_test_limit (0, 0, 15 - i, 16 - i, 255, 0); |
| + do_test_limit (0, 0, 15 - i, 16 - i, 255, 1); |
| + do_test_limit (0, 0, 15 - i, 16 - i, 255, -1); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strncmp-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strncmp-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strncmp function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strncmp.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strncpy.c glibc-2.17-c758a686.new/benchtests/bench-strncpy.c |
| |
| |
| @@ -0,0 +1,180 @@ |
| +/* Measure strncpy functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#ifndef STRNCPY_RESULT |
| +# define STRNCPY_RESULT(dst, len, n) dst |
| +# define TEST_MAIN |
| +# define TEST_NAME "strncpy" |
| +# include "bench-string.h" |
| + |
| +char *simple_strncpy (char *, const char *, size_t); |
| +char *stupid_strncpy (char *, const char *, size_t); |
| + |
| +IMPL (stupid_strncpy, 0) |
| +IMPL (simple_strncpy, 0) |
| +IMPL (strncpy, 1) |
| + |
| +char * |
| +simple_strncpy (char *dst, const char *src, size_t n) |
| +{ |
| + char *ret = dst; |
| + while (n--) |
| + if ((*dst++ = *src++) == '\0') |
| + { |
| + while (n--) |
| + *dst++ = '\0'; |
| + return ret; |
| + } |
| + return ret; |
| +} |
| + |
| +char * |
| +stupid_strncpy (char *dst, const char *src, size_t n) |
| +{ |
| + size_t nc = strnlen (src, n); |
| + size_t i; |
| + |
| + for (i = 0; i < nc; ++i) |
| + dst[i] = src[i]; |
| + for (; i < n; ++i) |
| + dst[i] = '\0'; |
| + return dst; |
| +} |
| +#endif |
| + |
| +typedef char *(*proto_t) (char *, const char *, size_t); |
| + |
| +static void |
| +do_one_test (impl_t *impl, char *dst, const char *src, size_t len, size_t n) |
| +{ |
| + if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, len, n)) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + CALL (impl, dst, src, n), dst); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (memcmp (dst, src, len > n ? n : len) != 0) |
| + { |
| + error (0, 0, "Wrong result in function %s", impl->name); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (n > len) |
| + { |
| + size_t i; |
| + |
| + for (i = len; i < n; ++i) |
| + if (dst [i] != '\0') |
| + { |
| + error (0, 0, "Wrong result in function %s", impl->name); |
| + ret = 1; |
| + return; |
| + } |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute__ ((unused)); |
| + hp_timing_t stop __attribute__ ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, dst, src, n); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char) |
| +{ |
| + size_t i; |
| + char *s1, *s2; |
| + |
| + align1 &= 7; |
| + if (align1 + len >= page_size) |
| + return; |
| + |
| + align2 &= 7; |
| + if (align2 + len >= page_size) |
| + return; |
| + |
| + s1 = (char *) (buf1 + align1); |
| + s2 = (char *) (buf2 + align2); |
| + |
| + for (i = 0; i < len; ++i) |
| + s1[i] = 32 + 23 * i % (max_char - 32); |
| + s1[len] = 0; |
| + for (i = len + 1; i + align1 < page_size && i < len + 64; ++i) |
| + s1[i] = 32 + 32 * i % (max_char - 32); |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, n %4zd, alignment %2zd/%2zd:", len, n, align1, align2); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s2, s1, len, n); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%28s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, i, 16, 16, 127); |
| + do_test (i, i, 16, 16, 255); |
| + do_test (i, 2 * i, 16, 16, 127); |
| + do_test (2 * i, i, 16, 16, 255); |
| + do_test (8 - i, 2 * i, 1 << i, 2 << i, 127); |
| + do_test (2 * i, 8 - i, 2 << i, 1 << i, 127); |
| + do_test (8 - i, 2 * i, 1 << i, 2 << i, 255); |
| + do_test (2 * i, 8 - i, 2 << i, 1 << i, 255); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 0, 4 << i, 8 << i, 127); |
| + do_test (0, 0, 16 << i, 8 << i, 127); |
| + do_test (8 - i, 2 * i, 4 << i, 8 << i, 127); |
| + do_test (8 - i, 2 * i, 16 << i, 8 << i, 127); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strncpy-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strncpy-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strncpy function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strncpy.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strnlen.c glibc-2.17-c758a686.new/benchtests/bench-strnlen.c |
| |
| |
| @@ -0,0 +1,139 @@ |
| +/* Measure strlen functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "strnlen" |
| +#include "bench-string.h" |
| + |
| +typedef size_t (*proto_t) (const char *, size_t); |
| +size_t simple_strnlen (const char *, size_t); |
| + |
| +IMPL (simple_strnlen, 0) |
| +IMPL (strnlen, 1) |
| + |
| +size_t |
| +simple_strnlen (const char *s, size_t maxlen) |
| +{ |
| + size_t i; |
| + |
| + for (i = 0; i < maxlen && s[i]; ++i); |
| + return i; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s, size_t maxlen, size_t exp_len) |
| +{ |
| + size_t len = CALL (impl, s, maxlen); |
| + if (len != exp_len) |
| + { |
| + error (0, 0, "Wrong result in function %s %zd %zd", impl->name, |
| + len, exp_len); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s, maxlen); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align, size_t len, size_t maxlen, int max_char) |
| +{ |
| + size_t i; |
| + |
| + align &= 7; |
| + if (align + len >= page_size) |
| + return; |
| + |
| + for (i = 0; i < len; ++i) |
| + buf1[align + i] = 1 + 7 * i % max_char; |
| + buf1[align + len] = 0; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd:", len, align); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, (char *) (buf1 + align), maxlen, MIN (len, maxlen)); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%20s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, i, i - 1, 127); |
| + do_test (0, i, i, 127); |
| + do_test (0, i, i + 1, 127); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, i, i - 1, 127); |
| + do_test (i, i, i, 127); |
| + do_test (i, i, i + 1, 127); |
| + } |
| + |
| + for (i = 2; i <= 10; ++i) |
| + { |
| + do_test (0, 1 << i, 5000, 127); |
| + do_test (1, 1 << i, 5000, 127); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + do_test (0, i, 5000, 255); |
| + |
| + for (i = 1; i < 8; ++i) |
| + do_test (i, i, 5000, 255); |
| + |
| + for (i = 2; i <= 10; ++i) |
| + { |
| + do_test (0, 1 << i, 5000, 255); |
| + do_test (1, 1 << i, 5000, 255); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strnlen-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strnlen-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strnlen function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strnlen.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strpbrk.c glibc-2.17-c758a686.new/benchtests/bench-strpbrk.c |
| |
| |
| @@ -0,0 +1,182 @@ |
| +/* Measure strpbrk functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#ifndef STRPBRK_RESULT |
| +# define STRPBRK_RESULT(s, pos) ((s)[(pos)] ? (s) + (pos) : NULL) |
| +# define RES_TYPE char * |
| +# define TEST_MAIN |
| +# define TEST_NAME "strpbrk" |
| +# include "bench-string.h" |
| + |
| +typedef char *(*proto_t) (const char *, const char *); |
| +char *simple_strpbrk (const char *, const char *); |
| +char *stupid_strpbrk (const char *, const char *); |
| + |
| +IMPL (stupid_strpbrk, 0) |
| +IMPL (simple_strpbrk, 0) |
| +IMPL (strpbrk, 1) |
| + |
| +char * |
| +simple_strpbrk (const char *s, const char *rej) |
| +{ |
| + const char *r; |
| + char c; |
| + |
| + while ((c = *s++) != '\0') |
| + for (r = rej; *r != '\0'; ++r) |
| + if (*r == c) |
| + return (char *) s - 1; |
| + return NULL; |
| +} |
| + |
| +char * |
| +stupid_strpbrk (const char *s, const char *rej) |
| +{ |
| + size_t ns = strlen (s), nrej = strlen (rej); |
| + size_t i, j; |
| + |
| + for (i = 0; i < ns; ++i) |
| + for (j = 0; j < nrej; ++j) |
| + if (s[i] == rej[j]) |
| + return (char *) s + i; |
| + return NULL; |
| +} |
| +#endif |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s, const char *rej, RES_TYPE exp_res) |
| +{ |
| + RES_TYPE res = CALL (impl, s, rej); |
| + if (res != exp_res) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + (void *) res, (void *) exp_res); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s, rej); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align, size_t pos, size_t len) |
| +{ |
| + size_t i; |
| + int c; |
| + RES_TYPE result; |
| + char *rej, *s; |
| + |
| + align &= 7; |
| + if (align + pos + 10 >= page_size || len > 240) |
| + return; |
| + |
| + rej = (char *) (buf2 + (random () & 255)); |
| + s = (char *) (buf1 + align); |
| + |
| + for (i = 0; i < len; ++i) |
| + { |
| + rej[i] = random () & 255; |
| + if (!rej[i]) |
| + rej[i] = random () & 255; |
| + if (!rej[i]) |
| + rej[i] = 1 + (random () & 127); |
| + } |
| + rej[len] = '\0'; |
| + for (c = 1; c <= 255; ++c) |
| + if (strchr (rej, c) == NULL) |
| + break; |
| + |
| + for (i = 0; i < pos; ++i) |
| + { |
| + s[i] = random () & 255; |
| + if (strchr (rej, s[i])) |
| + { |
| + s[i] = random () & 255; |
| + if (strchr (rej, s[i])) |
| + s[i] = c; |
| + } |
| + } |
| + s[pos] = rej[random () % (len + 1)]; |
| + if (s[pos]) |
| + { |
| + for (i = pos + 1; i < pos + 10; ++i) |
| + s[i] = random () & 255; |
| + s[i] = '\0'; |
| + } |
| + result = STRPBRK_RESULT (s, pos); |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd, rej len %2zd:", pos, align, len); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s, rej, result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%32s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + do_test (0, 512, i); |
| + do_test (i, 512, i); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 16 << i, 4); |
| + do_test (i, 16 << i, 4); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + do_test (i, 64, 10); |
| + |
| + for (i = 0; i < 64; ++i) |
| + do_test (0, i, 6); |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strpbrk-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strpbrk-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strpbrk function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strpbrk.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strrchr.c glibc-2.17-c758a686.new/benchtests/bench-strrchr.c |
| |
| |
| @@ -0,0 +1,190 @@ |
| +/* Measure STRCHR functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#ifdef WIDE |
| +# define TEST_NAME "wcsrchr" |
| +#else |
| +# define TEST_NAME "strrchr" |
| +#endif |
| +#include "bench-string.h" |
| + |
| +#ifdef WIDE |
| +# include <wchar.h> |
| +# define SIMPLE_STRRCHR simple_wcsrchr |
| +# define STRRCHR wcsrchr |
| +# define CHAR wchar_t |
| +# define UCHAR wchar_t |
| +# define BIG_CHAR WCHAR_MAX |
| +# define SMALL_CHAR 1273 |
| +#else |
| +# define SIMPLE_STRRCHR simple_strrchr |
| +# define STRRCHR strrchr |
| +# define CHAR char |
| +# define UCHAR unsigned char |
| +# define BIG_CHAR CHAR_MAX |
| +# define SMALL_CHAR 127 |
| +#endif |
| + |
| +typedef CHAR *(*proto_t) (const CHAR *, int); |
| +CHAR *SIMPLE_STRRCHR (const CHAR *, int); |
| + |
| +IMPL (SIMPLE_STRRCHR, 0) |
| +IMPL (STRRCHR, 1) |
| + |
| +CHAR * |
| +SIMPLE_STRRCHR (const CHAR *s, int c) |
| +{ |
| + const CHAR *ret = NULL; |
| + |
| + for (; *s != '\0'; ++s) |
| + if (*s == (CHAR) c) |
| + ret = s; |
| + |
| + return (CHAR *) (c == '\0' ? s : ret); |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, const CHAR *s, int c, CHAR *exp_res) |
| +{ |
| + CHAR *res = CALL (impl, s, c); |
| + if (res != exp_res) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + res, exp_res); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s, c); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char) |
| +/* For wcsrchr: align here means align not in bytes, |
| + but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)) |
| + len for wcschr here isn't in bytes but it's number of wchar_t symbols. */ |
| +{ |
| + size_t i; |
| + CHAR *result; |
| + CHAR *buf = (CHAR *) buf1; |
| + |
| + align &= 7; |
| + if ( (align + len) * sizeof(CHAR) >= page_size) |
| + return; |
| + |
| + for (i = 0; i < len; ++i) |
| + { |
| + buf[align + i] = (random () * random ()) & max_char; |
| + if (!buf[align + i]) |
| + buf[align + i] = (random () * random ()) & max_char; |
| + if (!buf[align + i]) |
| + buf[align + i] = 1; |
| + if ((i > pos || pos >= len) && buf[align + i] == seek_char) |
| + buf[align + i] = seek_char + 10 + (random () & 15); |
| + } |
| + buf[align + len] = 0; |
| + |
| + if (pos < len) |
| + { |
| + buf[align + pos] = seek_char; |
| + result = (CHAR *) (buf + align + pos); |
| + } |
| + else if (seek_char == 0) |
| + result = (CHAR *) (buf + align + len); |
| + else |
| + result = NULL; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment in bytes %2zd:", pos, align * sizeof(CHAR)); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, (CHAR *) (buf + align), seek_char, result); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%20s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 16 << i, 2048, 23, SMALL_CHAR); |
| + do_test (i, 16 << i, 2048, 23, SMALL_CHAR); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 64, 256, 23, SMALL_CHAR); |
| + do_test (i, 64, 256, 23, BIG_CHAR); |
| + } |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + do_test (0, i, i + 1, 23, SMALL_CHAR); |
| + do_test (0, i, i + 1, 23, BIG_CHAR); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 16 << i, 2048, 0, SMALL_CHAR); |
| + do_test (i, 16 << i, 2048, 0, SMALL_CHAR); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (i, 64, 256, 0, SMALL_CHAR); |
| + do_test (i, 64, 256, 0, BIG_CHAR); |
| + } |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + do_test (0, i, i + 1, 0, SMALL_CHAR); |
| + do_test (0, i, i + 1, 0, BIG_CHAR); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strrchr-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strrchr-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strrchr function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strrchr.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strspn.c glibc-2.17-c758a686.new/benchtests/bench-strspn.c |
| |
| |
| @@ -0,0 +1,174 @@ |
| +/* Measure strspn functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "strspn" |
| +#include "bench-string.h" |
| + |
| +typedef size_t (*proto_t) (const char *, const char *); |
| +size_t simple_strspn (const char *, const char *); |
| +size_t stupid_strspn (const char *, const char *); |
| + |
| +IMPL (stupid_strspn, 0) |
| +IMPL (simple_strspn, 0) |
| +IMPL (strspn, 1) |
| + |
| +size_t |
| +simple_strspn (const char *s, const char *acc) |
| +{ |
| + const char *r, *str = s; |
| + char c; |
| + |
| + while ((c = *s++) != '\0') |
| + { |
| + for (r = acc; *r != '\0'; ++r) |
| + if (*r == c) |
| + break; |
| + if (*r == '\0') |
| + return s - str - 1; |
| + } |
| + return s - str - 1; |
| +} |
| + |
| +size_t |
| +stupid_strspn (const char *s, const char *acc) |
| +{ |
| + size_t ns = strlen (s), nacc = strlen (acc); |
| + size_t i, j; |
| + |
| + for (i = 0; i < ns; ++i) |
| + { |
| + for (j = 0; j < nacc; ++j) |
| + if (s[i] == acc[j]) |
| + break; |
| + if (j == nacc) |
| + return i; |
| + } |
| + return i; |
| +} |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s, const char *acc, size_t exp_res) |
| +{ |
| + size_t res = CALL (impl, s, acc); |
| + if (res != exp_res) |
| + { |
| + error (0, 0, "Wrong result in function %s %p %p", impl->name, |
| + (void *) res, (void *) exp_res); |
| + ret = 1; |
| + return; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~ (hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s, acc); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| +static void |
| +do_test (size_t align, size_t pos, size_t len) |
| +{ |
| + size_t i; |
| + char *acc, *s; |
| + |
| + align &= 7; |
| + if (align + pos + 10 >= page_size || len > 240 || ! len) |
| + return; |
| + |
| + acc = (char *) (buf2 + (random () & 255)); |
| + s = (char *) (buf1 + align); |
| + |
| + for (i = 0; i < len; ++i) |
| + { |
| + acc[i] = random () & 255; |
| + if (!acc[i]) |
| + acc[i] = random () & 255; |
| + if (!acc[i]) |
| + acc[i] = 1 + (random () & 127); |
| + } |
| + acc[len] = '\0'; |
| + |
| + for (i = 0; i < pos; ++i) |
| + s[i] = acc[random () % len]; |
| + s[pos] = random () & 255; |
| + if (strchr (acc, s[pos])) |
| + s[pos] = '\0'; |
| + else |
| + { |
| + for (i = pos + 1; i < pos + 10; ++i) |
| + s[i] = random () & 255; |
| + s[i] = '\0'; |
| + } |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd, alignment %2zd, acc len %2zd:", pos, align, len); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s, acc, pos); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +int |
| +test_main (void) |
| +{ |
| + size_t i; |
| + |
| + test_init (); |
| + |
| + printf ("%32s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + do_test (0, 512, i); |
| + do_test (i, 512, i); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + { |
| + do_test (0, 16 << i, 4); |
| + do_test (i, 16 << i, 4); |
| + } |
| + |
| + for (i = 1; i < 8; ++i) |
| + do_test (i, 64, 10); |
| + |
| + for (i = 0; i < 64; ++i) |
| + do_test (0, i, 6); |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strspn-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strspn-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strspn function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strspn.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strstr.c glibc-2.17-c758a686.new/benchtests/bench-strstr.c |
| |
| |
| @@ -0,0 +1,183 @@ |
| +/* Measure strstr functions. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_MAIN |
| +#define TEST_NAME "strstr" |
| +#include "bench-string.h" |
| + |
| + |
| +#define STRSTR simple_strstr |
| +#include "../string/strstr.c" |
| + |
| + |
| +static char * |
| +stupid_strstr (const char *s1, const char *s2) |
| +{ |
| + ssize_t s1len = strlen (s1); |
| + ssize_t s2len = strlen (s2); |
| + |
| + if (s2len > s1len) |
| + return NULL; |
| + |
| + for (ssize_t i = 0; i <= s1len - s2len; ++i) |
| + { |
| + size_t j; |
| + for (j = 0; j < s2len; ++j) |
| + if (s1[i + j] != s2[j]) |
| + break; |
| + if (j == s2len) |
| + return (char *) s1 + i; |
| + } |
| + |
| + return NULL; |
| +} |
| + |
| + |
| +typedef char *(*proto_t) (const char *, const char *); |
| + |
| +IMPL (stupid_strstr, 0) |
| +IMPL (simple_strstr, 0) |
| +IMPL (strstr, 1) |
| + |
| + |
| +static void |
| +do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) |
| +{ |
| + if (HP_TIMING_AVAIL) |
| + { |
| + hp_timing_t start __attribute ((unused)); |
| + hp_timing_t stop __attribute ((unused)); |
| + hp_timing_t best_time = ~(hp_timing_t) 0; |
| + size_t i; |
| + |
| + for (i = 0; i < 32; ++i) |
| + { |
| + HP_TIMING_NOW (start); |
| + CALL (impl, s1, s2); |
| + HP_TIMING_NOW (stop); |
| + HP_TIMING_BEST (best_time, start, stop); |
| + } |
| + |
| + printf ("\t%zd", (size_t) best_time); |
| + } |
| +} |
| + |
| + |
| +static void |
| +do_test (size_t align1, size_t align2, size_t len1, size_t len2, |
| + int fail) |
| +{ |
| + char *s1 = (char *) (buf1 + align1); |
| + char *s2 = (char *) (buf2 + align2); |
| + |
| + static const char d[] = "1234567890abcdef"; |
| +#define dl (sizeof (d) - 1) |
| + char *ss2 = s2; |
| + for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0) |
| + { |
| + size_t t = l > dl ? dl : l; |
| + ss2 = mempcpy (ss2, d, t); |
| + } |
| + s2[len2] = '\0'; |
| + |
| + if (fail) |
| + { |
| + char *ss1 = s1; |
| + for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0) |
| + { |
| + size_t t = l > dl ? dl : l; |
| + memcpy (ss1, d, t); |
| + ++ss1[len2 > 7 ? 7 : len2 - 1]; |
| + ss1 += t; |
| + } |
| + } |
| + else |
| + { |
| + memset (s1, '0', len1); |
| + memcpy (s1 + len1 - len2, s2, len2); |
| + } |
| + s1[len1] = '\0'; |
| + |
| + if (HP_TIMING_AVAIL) |
| + printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", |
| + len1, len2, align1, align2, fail ? "fail" : "found"); |
| + |
| + FOR_EACH_IMPL (impl, 0) |
| + do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2); |
| + |
| + if (HP_TIMING_AVAIL) |
| + putchar ('\n'); |
| +} |
| + |
| +static int |
| +test_main (void) |
| +{ |
| + test_init (); |
| + |
| + printf ("%23s", ""); |
| + FOR_EACH_IMPL (impl, 0) |
| + printf ("\t%s", impl->name); |
| + putchar ('\n'); |
| + |
| + for (size_t klen = 2; klen < 32; ++klen) |
| + for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen) |
| + { |
| + do_test (0, 0, hlen, klen, 0); |
| + do_test (0, 0, hlen, klen, 1); |
| + do_test (0, 3, hlen, klen, 0); |
| + do_test (0, 3, hlen, klen, 1); |
| + do_test (0, 9, hlen, klen, 0); |
| + do_test (0, 9, hlen, klen, 1); |
| + do_test (0, 15, hlen, klen, 0); |
| + do_test (0, 15, hlen, klen, 1); |
| + |
| + do_test (3, 0, hlen, klen, 0); |
| + do_test (3, 0, hlen, klen, 1); |
| + do_test (3, 3, hlen, klen, 0); |
| + do_test (3, 3, hlen, klen, 1); |
| + do_test (3, 9, hlen, klen, 0); |
| + do_test (3, 9, hlen, klen, 1); |
| + do_test (3, 15, hlen, klen, 0); |
| + do_test (3, 15, hlen, klen, 1); |
| + |
| + do_test (9, 0, hlen, klen, 0); |
| + do_test (9, 0, hlen, klen, 1); |
| + do_test (9, 3, hlen, klen, 0); |
| + do_test (9, 3, hlen, klen, 1); |
| + do_test (9, 9, hlen, klen, 0); |
| + do_test (9, 9, hlen, klen, 1); |
| + do_test (9, 15, hlen, klen, 0); |
| + do_test (9, 15, hlen, klen, 1); |
| + |
| + do_test (15, 0, hlen, klen, 0); |
| + do_test (15, 0, hlen, klen, 1); |
| + do_test (15, 3, hlen, klen, 0); |
| + do_test (15, 3, hlen, klen, 1); |
| + do_test (15, 9, hlen, klen, 0); |
| + do_test (15, 9, hlen, klen, 1); |
| + do_test (15, 15, hlen, klen, 0); |
| + do_test (15, 15, hlen, klen, 1); |
| + } |
| + |
| + do_test (0, 0, page_size - 1, 16, 0); |
| + do_test (0, 0, page_size - 1, 16, 1); |
| + |
| + return ret; |
| +} |
| + |
| +#include "../test-skeleton.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-strstr-ifunc.c glibc-2.17-c758a686.new/benchtests/bench-strstr-ifunc.c |
| |
| |
| @@ -0,0 +1,20 @@ |
| +/* Measure IFUNC implementations of strstr function. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#define TEST_IFUNC 1 |
| +#include "bench-strstr.c" |
| diff -pruN glibc-2.17-c758a686/benchtests/bench-timing.h glibc-2.17-c758a686.new/benchtests/bench-timing.h |
| |
| |
| @@ -0,0 +1,72 @@ |
| +/* Define timing macros. |
| + Copyright (C) 2013 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#include <hp-timing.h> |
| +#include <stdint.h> |
| + |
| +#if HP_TIMING_AVAIL && !defined USE_CLOCK_GETTIME |
| +# define GL(x) _##x |
| +# define GLRO(x) _##x |
| +hp_timing_t _dl_hp_timing_overhead; |
| +typedef hp_timing_t timing_t; |
| + |
| +# define TIMING_INIT(iters) \ |
| +({ \ |
| + HP_TIMING_DIFF_INIT(); \ |
| + (iters) = 1000; \ |
| +}) |
| + |
| +# define TIMING_NOW(var) HP_TIMING_NOW (var) |
| +# define TIMING_DIFF(diff, start, end) HP_TIMING_DIFF ((diff), (start), (end)) |
| +# define TIMING_ACCUM(sum, diff) HP_TIMING_ACCUM_NT ((sum), (diff)) |
| + |
| +# define TIMING_PRINT_STATS(func, d_total_s, d_iters, d_total_i, max, min) \ |
| + printf ("%s: ITERS:%g: TOTAL:%gMcy, MAX:%gcy, MIN:%gcy, %g calls/Mcy\n", \ |
| + (func), (d_total_i), (d_total_s) * 1e-6, (max) / (d_iters), \ |
| + (min) / (d_iters), 1e6 * (d_total_i) / (d_total_s)); |
| + |
| +#else |
| +typedef uint64_t timing_t; |
| + |
| +/* Measure 1000 times the resolution of the clock. So for a 1ns |
| + resolution clock, we measure 1000 iterations of the function call at a |
| + time. Measurements close to the minimum clock resolution won't make |
| + much sense, but it's better than having nothing at all. */ |
| +# define TIMING_INIT(iters) \ |
| +({ \ |
| + struct timespec start; \ |
| + clock_getres (CLOCK_PROCESS_CPUTIME_ID, &start); \ |
| + (iters) = 1000 * start.tv_nsec; \ |
| +}) |
| + |
| +# define TIMING_NOW(var) \ |
| +({ \ |
| + struct timespec tv; \ |
| + clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &tv); \ |
| + (var) = (uint64_t) (tv.tv_nsec + (uint64_t) 1000000000 * tv.tv_sec); \ |
| +}) |
| + |
| +# define TIMING_DIFF(diff, start, end) (diff) = (end) - (start) |
| +# define TIMING_ACCUM(sum, diff) (sum) += (diff) |
| + |
| +# define TIMING_PRINT_STATS(func, d_total_s, d_iters, d_total_i, max, min) \ |
| + printf ("%s: ITERS:%g: TOTAL:%gs, MAX:%gns, MIN:%gns, %g iter/s\n", \ |
| + (func), (d_total_i), (d_total_s) * 1e-9, (max) / (d_iters), \ |
| + (min) / (d_iters), 1e9 * (d_total_i) / (d_total_s)) |
| + |
| +#endif |
| diff -pruN glibc-2.17-c758a686/benchtests/cosh-inputs glibc-2.17-c758a686.new/benchtests/cosh-inputs |
| |
| |
| @@ -0,0 +1,5 @@ |
| +0.1 |
| +0.2 |
| +0.3 |
| +0.4 |
| +0.5 |
| diff -pruN glibc-2.17-c758a686/benchtests/cos-inputs glibc-2.17-c758a686.new/benchtests/cos-inputs |
| |
| |
| @@ -0,0 +1,13 @@ |
| +0x1.000000cf4a2a1p0 |
| +0x1.0000010b239a8p0 |
| +0x1.00000162a932ap0 |
| +0x1.000002d452a11p0 |
| +0x1.000005bc7d86cp0 |
| +# cos slow path at 768 bits |
| +# Implemented in sysdeps/ieee754/dbl-64/sincos32.c |
| +## name: 768bits |
| +0x1.000000cf4a2a2p0 |
| +0x1.0000010b239a9p0 |
| +0x1.00000162a932bp0 |
| +0x1.000002d452a10p0 |
| +0x1.000005bc7d86dp0 |
| diff -pruN glibc-2.17-c758a686/benchtests/exp-inputs glibc-2.17-c758a686.new/benchtests/exp-inputs |
| |
| |
| @@ -0,0 +1,5 @@ |
| +42 |
| +# Slowest path with computation in 768 bit precision. |
| +# Implemented in: sysdeps/ieee754/dbl-64/mpexp.c |
| +## name: 768bits |
| +708.00096423260981737257679924368858 |
| diff -pruN glibc-2.17-c758a686/benchtests/log-inputs glibc-2.17-c758a686.new/benchtests/log-inputs |
| |
| |
| @@ -0,0 +1 @@ |
| +42.0 |
| diff -pruN glibc-2.17-c758a686/benchtests/Makefile glibc-2.17-c758a686.new/benchtests/Makefile |
| |
| |
| @@ -0,0 +1,174 @@ |
| +# Copyright (C) 2013 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 |
| +# <http://www.gnu.org/licenses/>. |
| + |
| + |
| +# Makefile for benchmark tests. The only useful target here is `bench`. |
| +# Add benchmark functions in alphabetical order. |
| + |
| +subdir := benchtests |
| +bench := acos acosh asin asinh atan atanh cos cosh exp log modf pow rint sin \ |
| + sinh tan tanh |
| + |
| +# String function benchmarks. |
| +string-bench := bcopy bzero memccpy memchr memcmp memmem memmove mempcpy \ |
| + memset rawmemchr stpcpy stpncpy strcasecmp strcasestr strcat \ |
| + strchr strchrnul strcmp strcpy strcspn strlen strncasecmp \ |
| + strncat strncmp strncpy strnlen strpbrk strrchr strspn strstr \ |
| + strcpy_chk stpcpy_chk |
| +string-bench-ifunc := $(addsuffix -ifunc, $(string-bench)) |
| +string-bench-all := $(string-bench) $(string-bench-ifunc) |
| + |
| +benchset := $(string-bench-all) |
| + |
| +acos-ARGLIST = double |
| +acos-RET = double |
| +LDFLAGS-bench-acos = -lm |
| + |
| +acosh-ARGLIST = double |
| +acosh-RET = double |
| +LDFLAGS-bench-acosh = -lm |
| + |
| +asin-ARGLIST = double |
| +asin-RET = double |
| +LDFLAGS-bench-asin = -lm |
| + |
| +asinh-ARGLIST = double |
| +asinh-RET = double |
| +LDFLAGS-bench-asinh = -lm |
| + |
| +atan-ARGLIST = double |
| +atan-RET = double |
| +LDFLAGS-bench-atan = -lm |
| + |
| +atanh-ARGLIST = double |
| +atanh-RET = double |
| +LDFLAGS-bench-atanh = -lm |
| + |
| +cos-ARGLIST = double |
| +cos-RET = double |
| +LDFLAGS-bench-cos = -lm |
| + |
| +cosh-ARGLIST = double |
| +cosh-RET = double |
| +LDFLAGS-bench-cosh = -lm |
| + |
| +exp-ARGLIST = double |
| +exp-RET = double |
| +LDFLAGS-bench-exp = -lm |
| + |
| +log-ARGLIST = double |
| +log-RET = double |
| +LDFLAGS-bench-log = -lm |
| + |
| +pow-ARGLIST = double:double |
| +pow-RET = double |
| +LDFLAGS-bench-pow = -lm |
| + |
| +rint-ARGLIST = double |
| +rint-RET = double |
| +LDFLAGS-bench-rint = -lm |
| + |
| +sin-ARGLIST = double |
| +sin-RET = double |
| +LDFLAGS-bench-sin = -lm |
| + |
| +sinh-ARGLIST = double |
| +sinh-RET = double |
| +LDFLAGS-bench-sinh = -lm |
| + |
| +tan-ARGLIST = double |
| +tan-RET = double |
| +LDFLAGS-bench-tan = -lm |
| + |
| +tanh-ARGLIST = double |
| +tanh-RET = double |
| +LDFLAGS-bench-tanh = -lm |
| + |
| + |
| + |
| +# Rules to build and execute the benchmarks. Do not put any benchmark |
| +# parameters beyond this point. |
| + |
| +# We don't want the benchmark programs to run in parallel since that could |
| +# affect their performance. |
| +.NOTPARALLEL: |
| + |
| +include ../Makeconfig |
| +include ../Rules |
| + |
| +binaries-bench := $(addprefix $(objpfx)bench-,$(bench)) |
| +binaries-benchset := $(addprefix $(objpfx)bench-,$(benchset)) |
| + |
| +# The default duration: 10 seconds. |
| +ifndef BENCH_DURATION |
| +BENCH_DURATION := 10 |
| +endif |
| + |
| +CPPFLAGS-nonlib += -DDURATION=$(BENCH_DURATION) |
| + |
| +# Use clock_gettime to measure performance of functions. The default is to use |
| +# HP_TIMING if it is available. |
| +ifdef USE_CLOCK_GETTIME |
| +CPPFLAGS-nonlib += -DUSE_CLOCK_GETTIME |
| +endif |
| + |
| +# This makes sure CPPFLAGS-nonlib and CFLAGS-nonlib are passed |
| +# for all these modules. |
| +cpp-srcs-left := $(binaries-benchset:=.c) $(binaries-bench:=.c) |
| +lib := nonlib |
| +include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) |
| + |
| +bench-deps := bench-skeleton.c bench-timing.h Makefile |
| + |
| +run-bench = $(test-wrapper-env) \ |
| + GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \ |
| + $($*-ENV) $(rtld-prefix) $${run} |
| + |
| +bench-clean: |
| + rm -f $(binaries-bench) $(addsuffix .o,$(binaries-bench)) |
| + rm -f $(binaries-benchset) $(addsuffix .o,$(binaries-benchset)) |
| + |
| +bench: bench-set bench-func |
| + |
| +bench-set: $(binaries-benchset) |
| + for run in $^; do \ |
| + echo "Running $${run}"; \ |
| + $(run-bench) > $${run}.out; \ |
| + done |
| + |
| +bench-func: $(binaries-bench) |
| + { for run in $^; do \ |
| + echo "Running $${run}" >&2; \ |
| + $(run-bench); \ |
| + done; } > $(objpfx)bench.out-tmp; \ |
| + if [ -f $(objpfx)bench.out ]; then \ |
| + mv -f $(objpfx)bench.out $(objpfx)bench.out.old; \ |
| + fi; \ |
| + mv -f $(objpfx)bench.out-tmp $(objpfx)bench.out |
| + |
| +$(binaries-bench) $(binaries-benchset): %: %.o \ |
| + $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \ |
| + $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit) |
| + $(+link) |
| + |
| +$(objpfx)bench-%.c: %-inputs $(bench-deps) |
| + { if [ -n "$($*-INCLUDE)" ]; then \ |
| + cat $($*-INCLUDE); \ |
| + fi; \ |
| + $(..)scripts/bench.pl $(patsubst %-inputs,%,$<) \ |
| + $($*-ARGLIST) $($*-RET); } > $@-tmp |
| + mv -f $@-tmp $@ |
| diff -pruN glibc-2.17-c758a686/benchtests/pow-inputs glibc-2.17-c758a686.new/benchtests/pow-inputs |
| |
| |
| @@ -0,0 +1,5 @@ |
| +42.0, 42.0 |
| +# pow slowest path at 768 bits |
| +# Implemented in sysdeps/ieee754/dbl-64/slowpow.c |
| +## name: 768bits |
| +1.0000000000000020, 1.5 |
| diff -pruN glibc-2.17-c758a686/benchtests/README glibc-2.17-c758a686.new/benchtests/README |
| |
| |
| @@ -0,0 +1,89 @@ |
| +Using the glibc microbenchmark suite |
| +==================================== |
| + |
| +The glibc microbenchmark suite automatically generates code for specified |
| +functions, builds and calls them repeatedly for given inputs to give some |
| +basic performance properties of the function. |
| + |
| +Running the benchmark: |
| +===================== |
| + |
| +The benchmark can be executed by invoking make as follows: |
| + |
| + $ make bench |
| + |
| +This runs each function for 10 seconds and appends its output to |
| +benchtests/bench.out. To ensure that the tests are rebuilt, one could run: |
| + |
| + $ make bench-clean |
| + |
| +The duration of each test can be configured setting the BENCH_DURATION variable |
| +in the call to make. One should run `make bench-clean' before changing |
| +BENCH_DURATION. |
| + |
| + $ make BENCH_DURATION=1 bench |
| + |
| +The benchmark suite does function call measurements using architecture-specific |
| +high precision timing instructions whenever available. When such support is |
| +not available, it uses clock_gettime (CLOCK_PROCESS_CPUTIME_ID). One can force |
| +the benchmark to use clock_gettime by invoking make as follows: |
| + |
| + $ make USE_CLOCK_GETTIME=1 bench |
| + |
| +Again, one must run `make bench-clean' before changing the measurement method. |
| + |
| +Adding a function to benchtests: |
| +=============================== |
| + |
| +If the name of the function is `foo', then the following procedure should allow |
| +one to add `foo' to the bench tests: |
| + |
| +- Append the function name to the bench variable in the Makefile. |
| + |
| +- Define foo-ARGLIST as a colon separated list of types of the input |
| + arguments. Use `void' if function does not take any inputs. Put in quotes |
| + if the input argument is a pointer, e.g.: |
| + |
| + malloc-ARGLIST: "void *" |
| + |
| +- Define foo-RET as the type the function returns. Skip if the function |
| + returns void. One could even skip foo-ARGLIST if the function does not |
| + take any inputs AND the function returns void. |
| + |
| +- Make a file called `foo-inputs` with one input value per line, an input |
| + being a comma separated list of arguments to be passed into the function. |
| + See pow-inputs for an example. |
| + |
| + The script that parses the -inputs file treats lines beginning with a single |
| + `#' as comments. Lines beginning with two hashes `##' are treated specially |
| + as `directives'. |
| + |
| +Multiple execution units per function: |
| +===================================== |
| + |
| +Some functions have distinct performance characteristics for different input |
| +domains and it may be necessary to measure those separately. For example, some |
| +math functions perform computations at different levels of precision (64-bit vs |
| +240-bit vs 768-bit) and mixing them does not give a very useful picture of the |
| +performance of these functions. One could separate inputs for these domains in |
| +the same file by using the `name' directive that looks something like this: |
| + |
| + ##name: 240bit |
| + |
| +See the pow-inputs file for an example of what such a partitioned input file |
| +would look like. |
| + |
| +Benchmark Sets: |
| +============== |
| + |
| +In addition to standard benchmarking of functions, one may also generate |
| +custom outputs for a set of functions. This is currently used by string |
| +function benchmarks where the aim is to compare performance between |
| +implementations at various alignments and for various sizes. |
| + |
| +To add a benchset for `foo': |
| + |
| +- Add `foo' to the benchset variable. |
| +- Write your bench-foo.c that prints out the measurements to stdout. |
| +- On execution, a bench-foo.out is created in $(objpfx) with the contents of |
| + stdout. |
| diff -pruN glibc-2.17-c758a686/benchtests/rint-inputs glibc-2.17-c758a686.new/benchtests/rint-inputs |
| |
| |
| @@ -0,0 +1,4 @@ |
| +78.5 |
| +-78.5 |
| +4503599627370497.0 |
| +-4503599627370497.0 |
| diff -pruN glibc-2.17-c758a686/benchtests/sinh-inputs glibc-2.17-c758a686.new/benchtests/sinh-inputs |
| |
| |
| @@ -0,0 +1,5 @@ |
| +0.1 |
| +0.2 |
| +0.3 |
| +0.4 |
| +0.5 |
| diff -pruN glibc-2.17-c758a686/benchtests/sin-inputs glibc-2.17-c758a686.new/benchtests/sin-inputs |
| |
| |
| @@ -0,0 +1,17 @@ |
| +0.9 |
| +2.3 |
| +3.7 |
| +3.9 |
| +4.0 |
| +4.7 |
| +5.9 |
| +# sin slowest path at 768 bits |
| +# Implemented in sysdeps/ieee754/dbl-64/sincos32.c |
| +## name: 768bits |
| +0.93340582292648832662962377071381 |
| +2.3328432680770916363144351635128 |
| +3.7439477503636453548097051680088 |
| +3.9225160069792437411706487182528 |
| +4.0711651639931289992091478779912 |
| +4.7858438478542097982426639646292 |
| +5.9840767662578002727968851104379 |
| diff -pruN glibc-2.17-c758a686/benchtests/tanh-inputs glibc-2.17-c758a686.new/benchtests/tanh-inputs |
| |
| |
| @@ -0,0 +1,5 @@ |
| +0.1 |
| +0.2 |
| +0.3 |
| +0.4 |
| +0.5 |
| diff -pruN glibc-2.17-c758a686/benchtests/tan-inputs glibc-2.17-c758a686.new/benchtests/tan-inputs |
| |
| |
| @@ -0,0 +1,5 @@ |
| +0x1.dffffffffff1ep-22 |
| +# tan slowest path at 768 bits |
| +# Implemented in sysdeps/ieee754/dbl-64/mptan.c |
| +## name: 768bits |
| +0x1.dffffffffff1fp-22 |
| diff -pruN glibc-2.17-c758a686/debug/test-strcpy_chk.c glibc-2.17-c758a686.new/debug/test-strcpy_chk.c |
| |
| |
| @@ -110,24 +110,6 @@ do_one_test (impl_t *impl, char *dst, co |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused));; |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, dst, src, dlen); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -151,14 +133,8 @@ do_test (size_t align1, size_t align2, s |
| s1[i] = 32 + 23 * i % (max_char - 32); |
| s1[len] = 0; |
| |
| - if (HP_TIMING_AVAIL && dlen > len) |
| - printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s2, s1, len, dlen); |
| - |
| - if (HP_TIMING_AVAIL && dlen > len) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/Makefile.in glibc-2.17-c758a686.new/Makefile.in |
| |
| |
| @@ -3,7 +3,7 @@ srcdir = @srcdir@ |
| # Uncomment the line below if you want to do parallel build. |
| # PARALLELMFLAGS = -j 4 |
| |
| -.PHONY: all install |
| +.PHONY: all install bench |
| |
| all .DEFAULT: |
| $(MAKE) -r PARALLELMFLAGS="$(PARALLELMFLAGS)" -C $(srcdir) objdir=`pwd` $@ |
| @@ -11,3 +11,6 @@ all .DEFAULT: |
| install: |
| LANGUAGE=C LC_ALL=C; export LANGUAGE LC_ALL; \ |
| $(MAKE) -r PARALLELMFLAGS="$(PARALLELMFLAGS)" -C $(srcdir) objdir=`pwd` $@ |
| + |
| +bench bench-clean: |
| + $(MAKE) -C $(srcdir)/benchtests $(PARALLELMFLAGS) objdir=`pwd` $@ |
| diff -pruN glibc-2.17-c758a686/Rules glibc-2.17-c758a686.new/Rules |
| |
| |
| @@ -83,7 +83,7 @@ common-generated += dummy.o dummy.c |
| |
| # This makes all the auxiliary and test programs. |
| |
| -.PHONY: others tests |
| +.PHONY: others tests bench |
| ifeq ($(multi-arch),no) |
| tests := $(filter-out $(tests-ifunc), $(tests)) |
| xtests := $(filter-out $(xtests-ifunc), $(xtests)) |
| @@ -191,6 +191,7 @@ $(objpfx)%.out: /dev/null $(objpfx)% # M |
| $(make-test-out) > $@ |
| |
| endif # tests |
| + |
| |
| .PHONY: distclean realclean subdir_distclean subdir_realclean \ |
| subdir_clean subdir_mostlyclean subdir_testclean |
| diff -pruN glibc-2.17-c758a686/scripts/bench.pl glibc-2.17-c758a686.new/scripts/bench.pl |
| |
| |
| @@ -0,0 +1,168 @@ |
| +#! /usr/bin/perl -w |
| +# Copyright (C) 2013 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 |
| +# <http://www.gnu.org/licenses/>. |
| + |
| + |
| +use strict; |
| +use warnings; |
| +# Generate a benchmark source file for a given input. |
| + |
| +if (@ARGV < 2) { |
| + die "Usage: bench.pl <function> [parameter types] [return type]" |
| +} |
| + |
| +my $arg; |
| +my $func = $ARGV[0]; |
| +my @args; |
| +my $ret = "void"; |
| +my $getret = ""; |
| +my $retval = ""; |
| + |
| +if (@ARGV >= 2) { |
| + @args = split(':', $ARGV[1]); |
| +} |
| + |
| +if (@ARGV == 3) { |
| + $ret = $ARGV[2]; |
| +} |
| + |
| +my $decl = "extern $ret $func ("; |
| + |
| +# Function has no arguments. |
| +if (@args == 0 || $args[0] eq "void") { |
| + print "$decl void);\n"; |
| + print "#define CALL_BENCH_FUNC(i,j) $func();\n"; |
| + print "#define NUM_VARIANTS (1)\n"; |
| + print "#define NUM_SAMPLES(v) (1)\n"; |
| + print "#define VARIANT(v) FUNCNAME \"()\"\n" |
| +} |
| +# The function has arguments, so parse them and populate the inputs. |
| +else { |
| + my $num = 0; |
| + my $bench_func = "#define CALL_BENCH_FUNC(v, i) $func ("; |
| + |
| + my $struct = |
| + "struct _variants |
| + { |
| + const char *name; |
| + int count; |
| + struct args *in; |
| + };\n"; |
| + |
| + my $arg_struct = "struct args {"; |
| + |
| + foreach $arg (@args) { |
| + if ($num > 0) { |
| + $bench_func = "$bench_func,"; |
| + $decl = "$decl,"; |
| + } |
| + |
| + $arg_struct = "$arg_struct volatile $arg arg$num;"; |
| + $bench_func = "$bench_func variants[v].in[i].arg$num"; |
| + $decl = "$decl $arg"; |
| + $num = $num + 1; |
| + } |
| + |
| + $arg_struct = $arg_struct . "};\n"; |
| + $decl = $decl . ");\n"; |
| + $bench_func = $bench_func . ");\n"; |
| + |
| + # We create a hash of inputs for each variant of the test. |
| + my $variant = ""; |
| + my @curvals; |
| + my %vals; |
| + |
| + open INPUTS, "<$func-inputs" or die $!; |
| + |
| + LINE:while (<INPUTS>) { |
| + chomp; |
| + |
| + # New variant. |
| + if (/^## (\w+): (\w+)/) { |
| + #We only identify Name for now. |
| + if ($1 ne "name") { |
| + next LINE; |
| + } |
| + |
| + # Save values in the last variant. |
| + my @copy = @curvals; |
| + $vals{$variant} = \@copy; |
| + |
| + # Prepare for the next. |
| + $variant=$2; |
| + undef @curvals; |
| + next LINE; |
| + } |
| + |
| + # Skip over comments. |
| + if (/^#/) { |
| + next LINE; |
| + } |
| + push (@curvals, $_); |
| + } |
| + |
| + $vals{$variant} = \@curvals; |
| + |
| + # Print the definitions and macros. |
| + print $decl; |
| + print $bench_func; |
| + print $arg_struct; |
| + print $struct; |
| + |
| + my $c = 0; |
| + my $key; |
| + |
| + # Print the input arrays. |
| + foreach $key (keys %vals) { |
| + my @arr = @{$vals{$key}}; |
| + |
| + print "struct args in" . $c . "[" . @arr . "] = {\n"; |
| + foreach (@arr) { |
| + print "{$_},\n"; |
| + } |
| + print "};\n\n"; |
| + $c += 1; |
| + } |
| + |
| + # The variants. Each variant then points to the appropriate input array we |
| + # defined above. |
| + print "struct _variants variants[" . (keys %vals) . "] = {\n"; |
| + $c = 0; |
| + foreach $key (keys %vals) { |
| + print "{\"$func($key)\", " . @{$vals{$key}} . ", in$c},\n"; |
| + $c += 1; |
| + } |
| + print "};\n\n"; |
| + |
| + # Finally, print the last set of macros. |
| + print "#define NUM_VARIANTS $c\n"; |
| + print "#define NUM_SAMPLES(i) (variants[i].count)\n"; |
| + print "#define VARIANT(i) (variants[i].name)\n"; |
| +} |
| + |
| +# In some cases not storing a return value seems to result in the function call |
| +# being optimized out. |
| +if ($ret ne "void") { |
| + print "static volatile $ret ret = 0.0;\n"; |
| + $getret = "ret = "; |
| +} |
| + |
| +# And we're done. |
| +print "#define BENCH_FUNC(i, j) ({$getret CALL_BENCH_FUNC (i, j);})\n"; |
| + |
| +print "#define FUNCNAME \"$func\"\n"; |
| +print "#include \"bench-skeleton.c\"\n"; |
| diff -pruN glibc-2.17-c758a686/string/test-memccpy.c glibc-2.17-c758a686.new/string/test-memccpy.c |
| |
| |
| @@ -74,24 +74,6 @@ do_one_test (impl_t *impl, void *dst, co |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute__ ((unused)); |
| - hp_timing_t stop __attribute__ ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, dst, src, c, n); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -122,14 +104,8 @@ do_test (size_t align1, size_t align2, i |
| for (i = len; i + align1 < page_size && i < len + 64; ++i) |
| s1[i] = 32 + 32 * i % (max_char - 32); |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, n %4zd, char %d, alignment %2zd/%2zd:", len, n, c, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s2, s1, c, len, n); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-memchr.c glibc-2.17-c758a686.new/string/test-memchr.c |
| |
| |
| @@ -47,24 +47,6 @@ do_one_test (impl_t *impl, const char *s |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s, c, n); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -97,14 +79,8 @@ do_test (size_t align, size_t pos, size_ |
| buf1[align + len] = seek_char; |
| } |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd:", pos, align); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, (char *) (buf1 + align), seek_char, len, result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-memcmp.c glibc-2.17-c758a686.new/string/test-memcmp.c |
| |
| |
| @@ -100,24 +100,6 @@ do_one_test (impl_t *impl, const CHAR *s |
| { |
| if (check_result (impl, s1, s2, len, exp_result) < 0) |
| return; |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s1, s2, len); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -147,14 +129,8 @@ do_test (size_t align1, size_t align2, s |
| s2[len] = align2; |
| s2[len - 1] -= exp_result; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s1, s2, len, exp_result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-memcpy.c glibc-2.17-c758a686.new/string/test-memcpy.c |
| |
| |
| @@ -68,24 +68,6 @@ do_one_test (impl_t *impl, char *dst, co |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, dst, src, len); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -108,14 +90,8 @@ do_test (size_t align1, size_t align2, s |
| for (i = 0, j = 1; i < len; i++, j += 23) |
| s1[i] = j; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s2, s1, len); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-memmem.c glibc-2.17-c758a686.new/string/test-memmem.c |
| |
| |
| @@ -82,24 +82,6 @@ do_one_test (impl_t *impl, const void *h |
| if (check_result (impl, haystack, haystack_len, needle, needle_len, |
| expected) < 0) |
| return; |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, haystack, haystack_len, needle, needle_len); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -110,16 +92,10 @@ do_test (const char *str, size_t len, si |
| memcpy (tmpbuf, buf1 + idx, len); |
| memcpy (buf1 + idx, str, len); |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("String %s, offset %zd:", str, idx); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx); |
| |
| memcpy (buf1 + idx, tmpbuf, len); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| @@ -143,16 +119,10 @@ do_random_tests (void) |
| buf1[idx + off] = ch; |
| } |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("String %.*s, offset %zd:", (int) len, buf1 + idx, idx); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len, |
| buf1 + idx); |
| |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| - |
| memcpy (buf1 + idx, tmpbuf, len); |
| } |
| } |
| diff -pruN glibc-2.17-c758a686/string/test-memmove.c glibc-2.17-c758a686.new/string/test-memmove.c |
| |
| |
| @@ -91,28 +91,6 @@ do_one_test (impl_t *impl, char *dst, ch |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| -#ifdef TEST_BCOPY |
| - CALL (impl, src, dst, len); |
| -#else |
| - CALL (impl, dst, src, len); |
| -#endif |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -135,14 +113,8 @@ do_test (size_t align1, size_t align2, s |
| for (i = 0, j = 1; i < len; i++, j += 23) |
| s1[i] = j; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s2, (char *) (buf2 + align1), s1, len); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-memset.c glibc-2.17-c758a686.new/string/test-memset.c |
| |
| |
| @@ -92,29 +92,6 @@ do_one_test (impl_t *impl, char *s, int |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| -#ifdef TEST_BZERO |
| - CALL (impl, s, n); |
| -#else |
| - CALL (impl, s, c, n); |
| -#endif |
| - |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -124,14 +101,8 @@ do_test (size_t align, int c, size_t len |
| if (align + len > page_size) |
| return; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, (char *) buf1 + align, c, len); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| #ifndef TEST_BZERO |
| diff -pruN glibc-2.17-c758a686/string/test-rawmemchr.c glibc-2.17-c758a686.new/string/test-rawmemchr.c |
| |
| |
| @@ -49,24 +49,6 @@ do_one_test (impl_t *impl, const char *s |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s, c); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -93,14 +75,8 @@ do_test (size_t align, size_t pos, size_ |
| buf1[align + len] = -seek_char; |
| result = (char *) (buf1 + align + pos); |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd:", pos, align); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, (char *) (buf1 + align), seek_char, result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strcasecmp.c glibc-2.17-c758a686.new/string/test-strcasecmp.c |
| |
| |
| @@ -73,24 +73,6 @@ do_one_test (impl_t *impl, const char *s |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s1, s2); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -129,14 +111,8 @@ do_test (size_t align1, size_t align2, s |
| else |
| s2[len - 1] -= exp_result; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s1, s2, exp_result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strcasestr.c glibc-2.17-c758a686.new/string/test-strcasestr.c |
| |
| |
| @@ -78,24 +78,6 @@ do_one_test (impl_t *impl, const char *s |
| { |
| if (check_result (impl, s1, s2, exp_result) < 0) |
| return; |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~(hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s1, s2); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| |
| @@ -135,15 +117,8 @@ do_test (size_t align1, size_t align2, s |
| } |
| s1[len1] = '\0'; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", |
| - len1, len2, align1, align2, fail ? "fail" : "found"); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strcat.c glibc-2.17-c758a686.new/string/test-strcat.c |
| |
| |
| @@ -56,25 +56,6 @@ do_one_test (impl_t *impl, char *dst, co |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - dst[k] = '\0'; |
| - HP_TIMING_NOW (start); |
| - CALL (impl, dst, src); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -101,17 +82,11 @@ do_test (size_t align1, size_t align2, s |
| for (i = 0; i < len2; i++) |
| s2[i] = 32 + 23 * i % (max_char - 32); |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len1, len2, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| { |
| s2[len2] = '\0'; |
| do_one_test (impl, s2, s1); |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strchr.c glibc-2.17-c758a686.new/string/test-strchr.c |
| |
| |
| @@ -107,24 +107,6 @@ do_one_test (impl_t *impl, const CHAR *s |
| { |
| if (check_result (impl, s, c, exp_res) < 0) |
| return; |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s, c); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -160,15 +142,8 @@ do_test (size_t align, size_t pos, size_ |
| else |
| result = NULLRET (buf + align + len); |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment in bytes %2zd:", |
| - pos, align * sizeof (CHAR)); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, buf + align, seek_char, result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strcmp.c glibc-2.17-c758a686.new/string/test-strcmp.c |
| |
| |
| @@ -161,24 +161,6 @@ do_one_test (impl_t *impl, |
| { |
| if (check_result (impl, s1, s2, exp_result) < 0) |
| return; |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s1, s2); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -214,14 +196,8 @@ do_test (size_t align1, size_t align2, s |
| s2[len + 1] = 24 + exp_result; |
| s2[len - 1] -= exp_result; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s1, s2, exp_result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strcpy.c glibc-2.17-c758a686.new/string/test-strcpy.c |
| |
| |
| @@ -92,24 +92,6 @@ do_one_test (impl_t *impl, CHAR *dst, co |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused));; |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, dst, src); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -135,14 +117,8 @@ do_test (size_t align1, size_t align2, s |
| s1[i] = 32 + 23 * i % (max_char - 32); |
| s1[len] = 0; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignments in bytes %2zd/%2zd:", len, align1 * sizeof(CHAR), align2 * sizeof(CHAR)); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s2, s1, len); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-string.h glibc-2.17-c758a686.new/string/test-string.h |
| |
| |
| @@ -53,7 +53,6 @@ extern impl_t __start_impls[], __stop_im |
| #include <ifunc-impl-list.h> |
| #define GL(x) _##x |
| #define GLRO(x) _##x |
| -#include <hp-timing.h> |
| |
| |
| # define TEST_FUNCTION test_main () |
| @@ -67,8 +66,6 @@ int ret, do_srandom; |
| unsigned int seed; |
| size_t page_size; |
| |
| -hp_timing_t _dl_hp_timing_overhead; |
| - |
| # ifndef ITERATIONS |
| size_t iterations = 100000; |
| # define ITERATIONS_OPTIONS \ |
| @@ -159,16 +156,6 @@ static impl_t *impl_array; |
| if (!notall || impl->test) |
| #endif |
| |
| -#define HP_TIMING_BEST(best_time, start, end) \ |
| - do \ |
| - { \ |
| - hp_timing_t tmptime; \ |
| - HP_TIMING_DIFF (tmptime, start + _dl_hp_timing_overhead, end); \ |
| - if (best_time > tmptime) \ |
| - best_time = tmptime; \ |
| - } \ |
| - while (0) |
| - |
| #ifndef BUF1PAGES |
| # define BUF1PAGES 1 |
| #endif |
| @@ -199,7 +186,6 @@ test_init (void) |
| error (EXIT_FAILURE, errno, "mmap failed"); |
| if (mprotect (buf2 + page_size, page_size, PROT_NONE)) |
| error (EXIT_FAILURE, errno, "mprotect failed"); |
| - HP_TIMING_DIFF_INIT (); |
| if (do_srandom) |
| { |
| printf ("Setting seed to 0x%x\n", seed); |
| diff -pruN glibc-2.17-c758a686/string/test-strlen.c glibc-2.17-c758a686.new/string/test-strlen.c |
| |
| |
| @@ -72,24 +72,6 @@ do_one_test (impl_t *impl, const CHAR *s |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -107,14 +89,8 @@ do_test (size_t align, size_t len) |
| buf[align + i] = 1 + 11111 * i % MAX_CHAR; |
| buf[align + len] = 0; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd:", len, align); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, (CHAR *) (buf + align), len); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strncasecmp.c glibc-2.17-c758a686.new/string/test-strncasecmp.c |
| |
| |
| @@ -94,24 +94,6 @@ do_one_test (impl_t *impl, const char *s |
| { |
| if (check_result (impl, s1, s2, n, exp_result) < 0) |
| return; |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s1, s2, n); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -150,14 +132,8 @@ do_test (size_t align1, size_t align2, s |
| else |
| s2[len - 1] -= exp_result; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s1, s2, n, exp_result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strncat.c glibc-2.17-c758a686.new/string/test-strncat.c |
| |
| |
| @@ -67,24 +67,6 @@ do_one_test (impl_t *impl, char *dst, co |
| ret = 1; |
| return; |
| } |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - dst[k] = '\0'; |
| - HP_TIMING_NOW (start); |
| - CALL (impl, dst, src, n); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -114,18 +96,11 @@ do_test (size_t align1, size_t align2, s |
| for (i = 0; i < len2; i++) |
| s2[i] = 32 + 23 * i % (max_char - 32); |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd/%4zd, alignment %2zd/%2zd, N %4zd:", |
| - len1, len2, align1, align2, n); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| { |
| s2[len2] = '\0'; |
| do_one_test (impl, s2, s1, n); |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strncmp.c glibc-2.17-c758a686.new/string/test-strncmp.c |
| |
| |
| @@ -75,24 +75,6 @@ do_one_test (impl_t *impl, const char *s |
| { |
| if (check_result (impl, s1, s2, n, exp_result) < 0) |
| return; |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s1, s2, n); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -106,15 +88,10 @@ do_test_limit (size_t align1, size_t ali |
| { |
| s1 = (char*)(buf1 + page_size); |
| s2 = (char*)(buf2 + page_size); |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd/%4zd:", len, n); |
| |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s1, s2, n, 0); |
| |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| - |
| return; |
| } |
| |
| @@ -144,14 +121,8 @@ do_test_limit (size_t align1, size_t ali |
| s1[len] = 64; |
| } |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s1, s2, n, exp_result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| @@ -189,14 +160,8 @@ do_test (size_t align1, size_t align2, s |
| if (len >= n) |
| s2[n - 1] -= exp_result; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, (char*)s1, (char*)s2, n, exp_result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strncpy.c glibc-2.17-c758a686.new/string/test-strncpy.c |
| |
| |
| @@ -90,24 +90,6 @@ do_one_test (impl_t *impl, char *dst, co |
| return; |
| } |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute__ ((unused)); |
| - hp_timing_t stop __attribute__ ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, dst, src, n); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -133,14 +115,8 @@ do_test (size_t align1, size_t align2, s |
| for (i = len + 1; i + align1 < page_size && i < len + 64; ++i) |
| s1[i] = 32 + 32 * i % (max_char - 32); |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, n %4zd, alignment %2zd/%2zd:", len, n, align1, align2); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s2, s1, len, n); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strnlen.c glibc-2.17-c758a686.new/string/test-strnlen.c |
| |
| |
| @@ -47,24 +47,6 @@ do_one_test (impl_t *impl, const char *s |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s, maxlen); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -80,14 +62,8 @@ do_test (size_t align, size_t len, size_ |
| buf1[align + i] = 1 + 7 * i % max_char; |
| buf1[align + len] = 0; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd:", len, align); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, (char *) (buf1 + align), maxlen, MIN (len, maxlen)); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strpbrk.c glibc-2.17-c758a686.new/string/test-strpbrk.c |
| |
| |
| @@ -70,24 +70,6 @@ do_one_test (impl_t *impl, const char *s |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s, rej); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -137,14 +119,8 @@ do_test (size_t align, size_t pos, size_ |
| } |
| result = STRPBRK_RESULT (s, pos); |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd, rej len %2zd:", pos, align, len); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s, rej, result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strrchr.c glibc-2.17-c758a686.new/string/test-strrchr.c |
| |
| |
| @@ -73,24 +73,6 @@ do_one_test (impl_t *impl, const CHAR *s |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s, c); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -129,14 +111,8 @@ do_test (size_t align, size_t pos, size_ |
| else |
| result = NULL; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment in bytes %2zd:", pos, align * sizeof(CHAR)); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, (CHAR *) (buf + align), seek_char, result); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strspn.c glibc-2.17-c758a686.new/string/test-strspn.c |
| |
| |
| @@ -74,24 +74,6 @@ do_one_test (impl_t *impl, const char *s |
| ret = 1; |
| return; |
| } |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~ (hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s, acc); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| static void |
| @@ -129,14 +111,8 @@ do_test (size_t align, size_t pos, size_ |
| s[i] = '\0'; |
| } |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd, alignment %2zd, acc len %2zd:", pos, align, len); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s, acc, pos); |
| - |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |
| diff -pruN glibc-2.17-c758a686/string/test-strstr.c glibc-2.17-c758a686.new/string/test-strstr.c |
| |
| |
| @@ -77,24 +77,6 @@ do_one_test (impl_t *impl, const char *s |
| { |
| if (check_result (impl, s1, s2, exp_result) < 0) |
| return; |
| - |
| - if (HP_TIMING_AVAIL) |
| - { |
| - hp_timing_t start __attribute ((unused)); |
| - hp_timing_t stop __attribute ((unused)); |
| - hp_timing_t best_time = ~(hp_timing_t) 0; |
| - size_t i; |
| - |
| - for (i = 0; i < 32; ++i) |
| - { |
| - HP_TIMING_NOW (start); |
| - CALL (impl, s1, s2); |
| - HP_TIMING_NOW (stop); |
| - HP_TIMING_BEST (best_time, start, stop); |
| - } |
| - |
| - printf ("\t%zd", (size_t) best_time); |
| - } |
| } |
| |
| |
| @@ -133,15 +115,9 @@ do_test (size_t align1, size_t align2, s |
| } |
| s1[len1] = '\0'; |
| |
| - if (HP_TIMING_AVAIL) |
| - printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", |
| - len1, len2, align1, align2, fail ? "fail" : "found"); |
| - |
| FOR_EACH_IMPL (impl, 0) |
| do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2); |
| |
| - if (HP_TIMING_AVAIL) |
| - putchar ('\n'); |
| } |
| |
| static void |