Back to index

glibc  2.9
test-memchr.c
Go to the documentation of this file.
00001 /* Test and measure memchr functions.
00002    Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Written by Jakub Jelinek <jakub@redhat.com>, 1999.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #define TEST_MAIN
00022 #include "test-string.h"
00023 
00024 typedef char *(*proto_t) (const char *, int, size_t);
00025 char *simple_memchr (const char *, int, size_t);
00026 
00027 IMPL (simple_memchr, 0)
00028 IMPL (memchr, 1)
00029 
00030 char *
00031 simple_memchr (const char *s, int c, size_t n)
00032 {
00033   while (n--)
00034     if (*s++ == (char) c)
00035       return (char *) s - 1;
00036   return NULL;
00037 }
00038 
00039 static void
00040 do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res)
00041 {
00042   char *res = CALL (impl, s, c, n);
00043   if (res != exp_res)
00044     {
00045       error (0, 0, "Wrong result in function %s %p %p", impl->name,
00046             res, exp_res);
00047       ret = 1;
00048       return;
00049     }
00050 
00051   if (HP_TIMING_AVAIL)
00052     {
00053       hp_timing_t start __attribute ((unused));
00054       hp_timing_t stop __attribute ((unused));
00055       hp_timing_t best_time = ~ (hp_timing_t) 0;
00056       size_t i;
00057 
00058       for (i = 0; i < 32; ++i)
00059        {
00060          HP_TIMING_NOW (start);
00061          CALL (impl, s, c, n);
00062          HP_TIMING_NOW (stop);
00063          HP_TIMING_BEST (best_time, start, stop);
00064        }
00065 
00066       printf ("\t%zd", (size_t) best_time);
00067     }
00068 }
00069 
00070 static void
00071 do_test (size_t align, size_t pos, size_t len, int seek_char)
00072 {
00073   size_t i;
00074   char *result;
00075 
00076   align &= 7;
00077   if (align + len >= page_size)
00078     return;
00079 
00080   for (i = 0; i < len; ++i)
00081     {
00082       buf1[align + i] = 1 + 23 * i % 127;
00083       if (buf1[align + i] == seek_char)
00084         buf1[align + i] = seek_char + 1;
00085     }
00086   buf1[align + len] = 0;
00087 
00088   if (pos < len)
00089     {
00090       buf1[align + pos] = seek_char;
00091       buf1[align + len] = -seek_char;
00092       result = (char *) (buf1 + align + pos);
00093     }
00094   else
00095     {
00096       result = NULL;
00097       buf1[align + len] = seek_char;
00098     }
00099 
00100   if (HP_TIMING_AVAIL)
00101     printf ("Length %4zd, alignment %2zd:", pos, align);
00102 
00103   FOR_EACH_IMPL (impl, 0)
00104     do_one_test (impl, (char *) (buf1 + align), seek_char, len, result);
00105 
00106   if (HP_TIMING_AVAIL)
00107     putchar ('\n');
00108 }
00109 
00110 static void
00111 do_random_tests (void)
00112 {
00113   size_t i, j, n, align, pos, len;
00114   int seek_char;
00115   char *result;
00116   unsigned char *p = buf1 + page_size - 512;
00117 
00118   for (n = 0; n < ITERATIONS; n++)
00119     {
00120       align = random () & 15;
00121       pos = random () & 511;
00122       if (pos + align >= 512)
00123        pos = 511 - align - (random () & 7);
00124       len = random () & 511;
00125       if (pos >= len)
00126        len = pos + (random () & 7);
00127       if (len + align >= 512)
00128         len = 512 - align - (random () & 7);
00129       seek_char = random () & 255;
00130       j = len + align + 64;
00131       if (j > 512)
00132         j = 512;
00133 
00134       for (i = 0; i < j; i++)
00135        {
00136          if (i == pos + align)
00137            p[i] = seek_char;
00138          else
00139            {
00140              p[i] = random () & 255;
00141              if (i < pos + align && p[i] == seek_char)
00142               p[i] = seek_char + 13;
00143            }
00144        }
00145 
00146       if (pos < len)
00147        result = (char *) (p + pos + align);
00148       else
00149        result = NULL;
00150 
00151       FOR_EACH_IMPL (impl, 1)
00152        if (CALL (impl, (char *) (p + align), seek_char, len) != result)
00153          {
00154            error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
00155                  n, impl->name, align, seek_char, len, pos,
00156                  CALL (impl, (char *) (p + align), seek_char, len),
00157                  result, p);
00158            ret = 1;
00159          }
00160     }
00161 }
00162 
00163 int
00164 test_main (void)
00165 {
00166   size_t i;
00167 
00168   test_init ();
00169 
00170   printf ("%20s", "");
00171   FOR_EACH_IMPL (impl, 0)
00172     printf ("\t%s", impl->name);
00173   putchar ('\n');
00174 
00175   for (i = 1; i < 8; ++i)
00176     {
00177       do_test (0, 16 << i, 2048, 23);
00178       do_test (i, 64, 256, 23);
00179       do_test (0, 16 << i, 2048, 0);
00180       do_test (i, 64, 256, 0);
00181     }
00182   for (i = 1; i < 32; ++i)
00183     {
00184       do_test (0, i, i + 1, 23);
00185       do_test (0, i, i + 1, 0);
00186     }
00187 
00188   do_random_tests ();
00189   return ret;
00190 }
00191 
00192 #include "../test-skeleton.c"