Back to index

glibc  2.9
test-string.h
Go to the documentation of this file.
00001 /* Test and measure string and memory functions.
00002    Copyright (C) 1999, 2002, 2004, 2008 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 typedef struct
00022 {
00023   const char *name;
00024   void (*fn) (void);
00025   long test;
00026 } impl_t;
00027 extern impl_t __start_impls[], __stop_impls[];
00028 
00029 #define IMPL(name, test) \
00030   impl_t tst_ ## name                                                 \
00031   __attribute__ ((section ("impls"), aligned (sizeof (void *))))      \
00032     = { #name, (void (*) (void))name, test };
00033 
00034 #ifdef TEST_MAIN
00035 
00036 #ifndef _GNU_SOURCE
00037 #define _GNU_SOURCE
00038 #endif
00039 
00040 #undef __USE_STRING_INLINES
00041 
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <sys/mman.h>
00046 #include <unistd.h>
00047 #include <fcntl.h>
00048 #include <error.h>
00049 #include <errno.h>
00050 #include <time.h>
00051 #define GL(x) _##x
00052 #define GLRO(x) _##x
00053 #include <hp-timing.h>
00054 
00055 
00056 # define TEST_FUNCTION test_main ()
00057 # define TIMEOUT (4 * 60)
00058 # define OPT_ITERATIONS 10000
00059 # define OPT_RANDOM 10001
00060 # define OPT_SEED 10002
00061 
00062 unsigned char *buf1, *buf2;
00063 int ret, do_srandom;
00064 unsigned int seed;
00065 size_t page_size;
00066 
00067 hp_timing_t _dl_hp_timing_overhead;
00068 
00069 # ifndef ITERATIONS
00070 size_t iterations = 100000;
00071 #  define ITERATIONS_OPTIONS \
00072   { "iterations", required_argument, NULL, OPT_ITERATIONS },
00073 #  define ITERATIONS_PROCESS \
00074   case OPT_ITERATIONS:                           \
00075     iterations = strtoul (optarg, NULL, 0);      \
00076     break;
00077 #  define ITERATIONS iterations
00078 # else
00079 #  define ITERATIONS_OPTIONS
00080 #  define ITERATIONS_PROCESS
00081 # endif
00082 
00083 # define CMDLINE_OPTIONS ITERATIONS_OPTIONS \
00084   { "random", no_argument, NULL, OPT_RANDOM },   \
00085   { "seed", required_argument, NULL, OPT_SEED },
00086 # define CMDLINE_PROCESS ITERATIONS_PROCESS \
00087   case OPT_RANDOM:                                             \
00088     {                                                          \
00089       int fdr = open ("/dev/urandom", O_RDONLY);               \
00090                                                                \
00091       if (fdr < 0 || read (fdr, &seed, sizeof(seed)) != sizeof (seed))       \
00092        seed = time (NULL);                                     \
00093       if (fdr >= 0)                                            \
00094        close (fdr);                                            \
00095       do_srandom = 1;                                                 \
00096       break;                                                   \
00097     }                                                          \
00098                                                                \
00099   case OPT_SEED:                                               \
00100     seed = strtoul (optarg, NULL, 0);                                 \
00101     do_srandom = 1;                                            \
00102     break;
00103 
00104 #define CALL(impl, ...)     \
00105   (* (proto_t) (impl)->fn) (__VA_ARGS__)
00106 
00107 #define FOR_EACH_IMPL(impl, notall) \
00108   for (impl_t *impl = __start_impls; impl < __stop_impls; ++impl)     \
00109     if (!notall || impl->test)
00110 
00111 #define HP_TIMING_BEST(best_time, start, end)    \
00112   do                                                           \
00113     {                                                          \
00114       hp_timing_t tmptime;                                     \
00115       HP_TIMING_DIFF (tmptime, start + _dl_hp_timing_overhead, end);  \
00116       if (best_time > tmptime)                                        \
00117        best_time = tmptime;                                    \
00118     }                                                          \
00119   while (0)
00120 
00121 #ifndef BUF1PAGES
00122 # define BUF1PAGES 1
00123 #endif
00124 
00125 static void
00126 test_init (void)
00127 {
00128   page_size = 2 * getpagesize ();
00129 #ifdef MIN_PAGE_SIZE
00130   if (page_size < MIN_PAGE_SIZE)
00131     page_size = MIN_PAGE_SIZE;
00132 #endif
00133   buf1 = mmap (0, (BUF1PAGES + 1) * page_size, PROT_READ | PROT_WRITE,
00134               MAP_PRIVATE | MAP_ANON, -1, 0);
00135   if (buf1 == MAP_FAILED)
00136     error (EXIT_FAILURE, errno, "mmap failed");
00137   if (mprotect (buf1 + BUF1PAGES * page_size, page_size, PROT_NONE))
00138     error (EXIT_FAILURE, errno, "mprotect failed");
00139   buf2 = mmap (0, 2 * page_size, PROT_READ | PROT_WRITE,
00140               MAP_PRIVATE | MAP_ANON, -1, 0);
00141   if (buf2 == MAP_FAILED)
00142     error (EXIT_FAILURE, errno, "mmap failed");
00143   if (mprotect (buf2 + page_size, page_size, PROT_NONE))
00144     error (EXIT_FAILURE, errno, "mprotect failed");
00145   HP_TIMING_DIFF_INIT ();
00146   if (do_srandom)
00147     {
00148       printf ("Setting seed to 0x%x\n", seed);
00149       srandom (seed);
00150     }
00151 
00152   memset (buf1, 0xa5, BUF1PAGES * page_size);
00153   memset (buf2, 0x5a, page_size);
00154 }
00155 
00156 #endif