Back to index

glibc  2.9
test-memset.c
Go to the documentation of this file.
00001 /* Test and measure memset 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 #define MIN_PAGE_SIZE 131072
00023 #include "test-string.h"
00024 
00025 typedef char *(*proto_t) (char *, int, size_t);
00026 char *simple_memset (char *, int, size_t);
00027 char *builtin_memset (char *, int, size_t);
00028 
00029 IMPL (simple_memset, 0)
00030 IMPL (builtin_memset, 0)
00031 IMPL (memset, 1)
00032 
00033 char *
00034 simple_memset (char *s, int c, size_t n)
00035 {
00036   char *r = s, *end = s + n;
00037   while (r < end)
00038     *r++ = c;
00039   return s;
00040 }
00041 
00042 char *
00043 builtin_memset (char *s, int c, size_t n)
00044 {
00045   return __builtin_memset (s, c, n);
00046 }
00047 
00048 static void
00049 do_one_test (impl_t *impl, char *s, int c, size_t n)
00050 {
00051   char *res = CALL (impl, s, c, n);
00052   char tstbuf[n];
00053   if (res != s
00054       || simple_memset (tstbuf, c, n) != tstbuf
00055       || memcmp (s, tstbuf, n) != 0)
00056     {
00057       error (0, 0, "Wrong result in function %s", impl->name);
00058       ret = 1;
00059       return;
00060     }
00061 
00062   if (HP_TIMING_AVAIL)
00063     {
00064       hp_timing_t start __attribute ((unused));
00065       hp_timing_t stop __attribute ((unused));
00066       hp_timing_t best_time = ~ (hp_timing_t) 0;
00067       size_t i;
00068 
00069       for (i = 0; i < 32; ++i)
00070        {
00071          HP_TIMING_NOW (start);
00072          CALL (impl, s, c, n);
00073          HP_TIMING_NOW (stop);
00074          HP_TIMING_BEST (best_time, start, stop);
00075        }
00076 
00077       printf ("\t%zd", (size_t) best_time);
00078     }
00079 }
00080 
00081 static void
00082 do_test (size_t align, int c, size_t len)
00083 {
00084   align &= 7;
00085   if (align + len > page_size)
00086     return;
00087 
00088   if (HP_TIMING_AVAIL)
00089     printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c);
00090 
00091   FOR_EACH_IMPL (impl, 0)
00092     do_one_test (impl, (char *) buf1 + align, c, len);
00093 
00094   if (HP_TIMING_AVAIL)
00095     putchar ('\n');
00096 }
00097 
00098 static void
00099 do_random_tests (void)
00100 {
00101   size_t i, j, k, n, align, len, size;
00102   int c, o;
00103   unsigned char *p, *res;
00104 
00105   for (i = 0; i < 65536; ++i)
00106     buf2[i] = random () & 255;
00107 
00108   for (n = 0; n < ITERATIONS; n++)
00109     {
00110       if ((random () & 31) == 0)
00111        size = 65536;
00112       else
00113        size = 512;
00114       p = buf1 + page_size - size;
00115       len = random () & (size - 1);
00116       align = size - len - (random () & 31);
00117       if (align > size)
00118        align = size - len;
00119       if ((random () & 7) == 0)
00120        align &= ~63;
00121       if ((random () & 7) == 0)
00122        c = 0;
00123       else
00124        c = random () & 255;
00125       o = random () & 255;
00126       if (o == c)
00127         o = (c + 1) & 255;
00128       j = len + align + 128;
00129       if (j > size)
00130        j = size;
00131       if (align >= 128)
00132        k = align - 128;
00133       else
00134        k = 0;
00135       for (i = k; i < align; ++i)
00136        p[i] = o;
00137       for (i = align + len; i < j; ++i)
00138        p[i] = o;
00139 
00140       FOR_EACH_IMPL (impl, 1)
00141        {
00142          for (i = 0; i < len; ++i)
00143            {
00144              p[i + align] = buf2[i];
00145              if (p[i + align] == c)
00146               p[i + align] = o;
00147            }
00148          res = (unsigned char *) CALL (impl, (char *) p + align, c, len);
00149          if (res != p + align)
00150            {
00151              error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd) %p != %p",
00152                    n, impl->name, align, c, len, res, p + align);
00153              ret = 1;
00154            }
00155          for (i = k; i < align; ++i)
00156            if (p[i] != o)
00157              {
00158               error (0, 0, "Iteration %zd - garbage before %s (%zd, %d, %zd)",
00159                      n, impl->name, align, c, len);
00160               ret = 1;
00161               break;
00162              }
00163          for (; i < align + len; ++i)
00164            if (p[i] != c)
00165              {
00166               error (0, 0, "Iteration %zd - not cleared correctly %s (%zd, %d, %zd)",
00167                      n, impl->name, align, c, len);
00168               ret = 1;
00169               break;
00170              }
00171          for (; i < j; ++i)
00172            if (p[i] != o)
00173              {
00174               error (0, 0, "Iteration %zd - garbage after %s (%zd, %d, %zd)",
00175                      n, impl->name, align, c, len);
00176               ret = 1;
00177               break;
00178              }
00179        }
00180     }
00181 }
00182 
00183 int
00184 test_main (void)
00185 {
00186   size_t i;
00187   int c;
00188 
00189   test_init ();
00190 
00191   printf ("%24s", "");
00192   FOR_EACH_IMPL (impl, 0)
00193     printf ("\t%s", impl->name);
00194   putchar ('\n');
00195 
00196   for (c = -65; c <= 130; c += 65)
00197     {
00198       for (i = 0; i < 18; ++i)
00199        do_test (0, c, 1 << i);
00200       for (i = 1; i < 32; ++i)
00201        {
00202          do_test (i, c, i);
00203          if (i & (i - 1))
00204            do_test (0, c, i);
00205        }
00206       do_test (1, c, 14);
00207       do_test (3, c, 1024);
00208       do_test (4, c, 64);
00209       do_test (2, c, 25);
00210     }
00211 
00212   do_random_tests ();
00213   return ret;
00214 }
00215 
00216 #include "../test-skeleton.c"