]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Sun, 27 Dec 1998 17:29:47 +0000 (17:29 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 27 Dec 1998 17:29:47 +0000 (17:29 +0000)
1998-12-27  Ulrich Drepper  <drepper@cygnus.com>

* elf/dl-lookup.c (_dl_num_relocations): New variable.
(do_lookup): Increment _dl_num_relocations for every call.
* elf/rtld.c (print_statistics): New function.
(_dl_debug_statistics): New variable.  Set when statistics are asked
for.
(rtld_total_time, relocate_time, load_time): New variables.  Used
in print_statistics.
(_dl_start): Record start and end time of startup.  Call
print_statistics if needed.
(dk_main): Record times for relocations and loading.
(process_dl_debug): Recognize statistics.

Low-level, low-overhead, high-precision timing funcationality.
* sysdeps/generic/hp-timing.h: New file.
* sysdeps/i386/i686/Makefile: New file.
* sysdeps/i386/i686/hp-timing.h: New file.
* sysdeps/i386/i686/hp-timing.c: New file.

* sysdeps/i386/dl-machine.h (elf_machine_rel): Reverse order of OR
clauses to avoid accessing global variables during rtld relocation.

* sunrpc/rpc_main.c: Unify messages.

* sysdeps/unix/sysv/linux/arm/Dist: Add ioperm.c and sys/io.h.

ChangeLog
elf/rtld.c
sunrpc/rpc_main.c
sysdeps/generic/hp-timing.h [new file with mode: 0644]
sysdeps/i386/dl-machine.h
sysdeps/i386/i686/Makefile [new file with mode: 0644]
sysdeps/i386/i686/hp-timing.c [new file with mode: 0644]
sysdeps/i386/i686/hp-timing.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/arm/Dist

index f7b3c0de9683bc89b6634a5f556c59a9c1651342..51109f1d583dea357a9243c842b1c0735bd65afa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+1998-12-27  Ulrich Drepper  <drepper@cygnus.com>
+
+       * elf/dl-lookup.c (_dl_num_relocations): New variable.
+       (do_lookup): Increment _dl_num_relocations for every call.
+       * elf/rtld.c (print_statistics): New function.
+       (_dl_debug_statistics): New variable.  Set when statistics are asked
+       for.
+       (rtld_total_time, relocate_time, load_time): New variables.  Used
+       in print_statistics.
+       (_dl_start): Record start and end time of startup.  Call
+       print_statistics if needed.
+       (dk_main): Record times for relocations and loading.
+       (process_dl_debug): Recognize statistics.
+
+       Low-level, low-overhead, high-precision timing funcationality.
+       * sysdeps/generic/hp-timing.h: New file.
+       * sysdeps/i386/i686/Makefile: New file.
+       * sysdeps/i386/i686/hp-timing.h: New file.
+       * sysdeps/i386/i686/hp-timing.c: New file.
+
+       * sysdeps/i386/dl-machine.h (elf_machine_rel): Reverse order of OR
+       clauses to avoid accessing global variables during rtld relocation.
+
+       * sunrpc/rpc_main.c: Unify messages.
+
+       * sysdeps/unix/sysv/linux/arm/Dist: Add ioperm.c and sys/io.h.
+
 1998-12-27  Roland McGrath  <roland@baalperazim.frob.com>
 
        * sysdeps/mach/hurd/bits/statfs.h (struct statfs, struct statfs64):
index 38c7b051b183a4eaa5f7705a16c597e364fece26..df6a945105893bbaee674e98e8dd799275db26df 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdio-common/_itoa.h>
 #include <entry.h>
 #include <fpu_control.h>
+#include <hp-timing.h>
 #include "dynamic-link.h"
 #include "dl-librecon.h"
 
@@ -58,6 +59,8 @@ static void print_unresolved (int errcode, const char *objname,
 static void print_missing_version (int errcode, const char *objname,
                                   const char *errsting);
 
+/* Print the various times we collected.  */
+static void print_statistics (void);
 
 /* This is a list of all the modes the dynamic loader can be in.  */
 enum mode { normal, list, verify, trace };
@@ -86,6 +89,7 @@ int _dl_debug_symbols;
 int _dl_debug_versions;
 int _dl_debug_reloc;
 int _dl_debug_files;
+int _dl_debug_statistics;
 const char *_dl_inhibit_rpath;         /* RPATH values which should be
                                           ignored.  */
 const char *_dl_origin_path;
@@ -118,6 +122,12 @@ struct link_map _dl_rtld_map;
 struct libname_list _dl_rtld_libname;
 struct libname_list _dl_rtld_libname2;
 
+/* Variable for statistics.  */
+static hp_timing_t rtld_total_time;
+static hp_timing_t relocate_time;
+static hp_timing_t load_time;
+extern unsigned long int _dl_num_relocations;  /* in dl-lookup.c */
+
 #ifdef RTLD_START
 RTLD_START
 #else
@@ -128,6 +138,8 @@ static ElfW(Addr)
 _dl_start (void *arg)
 {
   struct link_map bootstrap_map;
+  hp_timing_t start_time;
+  ElfW(Addr) start_addr;
 
   /* This #define produces dynamic linking inline functions for
      bootstrap relocation instead of general-purpose relocation.  */
@@ -136,6 +148,9 @@ _dl_start (void *arg)
   ((*(sym))->st_shndx == SHN_UNDEF ? 0 : bootstrap_map.l_addr)
 #include "dynamic-link.h"
 
+  if (HP_TIMING_INLINE && HP_TIMING_AVAIL)
+    HP_TIMING_NOW (start_time);
+
   /* Figure out the run-time load address of the dynamic linker itself.  */
   bootstrap_map.l_addr = elf_machine_load_address ();
 
@@ -160,6 +175,16 @@ _dl_start (void *arg)
      the operating system's program loader where to find the program
      header table in core.  */
 
+  if (HP_TIMING_AVAIL)
+    {
+      /* If it hasn't happen yet record the startup time.  */
+      if (! HP_TIMING_INLINE)
+       HP_TIMING_NOW (start_time);
+
+      /* Initialize the timing functions.  */
+      HP_TIMING_DIFF_INIT ();
+    }
+
   /* Transfer data about ourselves to the permanent link_map structure.  */
   _dl_rtld_map.l_addr = bootstrap_map.l_addr;
   _dl_rtld_map.l_ld = bootstrap_map.l_ld;
@@ -176,7 +201,23 @@ _dl_start (void *arg)
      file access.  It will call `dl_main' (below) to do all the real work
      of the dynamic linker, and then unwind our frame and run the user
      entry point on the same stack we entered on.  */
-  return _dl_sysdep_start (arg, &dl_main);
+  start_addr =  _dl_sysdep_start (arg, &dl_main);
+
+  if (HP_TIMING_AVAIL)
+    {
+      hp_timing_t end_time;
+
+      /* Get the current time.  */
+      HP_TIMING_NOW (end_time);
+
+      /* Compute the difference.  */
+      HP_TIMING_DIFF (rtld_total_time, start_time, end_time);
+    }
+
+  if (_dl_debug_statistics)
+    print_statistics ();
+
+  return start_addr;
 }
 
 /* Now life is peachy; we can do all normal operations.
@@ -300,6 +341,9 @@ dl_main (const ElfW(Phdr) *phdr,
   int has_interp = 0;
   unsigned int i;
   int paths_initialized = 0;
+  hp_timing_t start;
+  hp_timing_t stop;
+  hp_timing_t diff;
 
   /* Process the environment variable which control the behaviour.  */
   process_envvars (&mode, &lazy);
@@ -413,7 +457,13 @@ of this helper program; chances are you did not intend to run this program.\n\
            }
        }
       else
-       _dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0);
+       {
+         HP_TIMING_NOW (start);
+         _dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0);
+         HP_TIMING_NOW (stop);
+         
+         HP_TIMING_DIFF (load_time, start, stop);
+       }
 
       phdr = _dl_loaded->l_phdr;
       phent = _dl_loaded->l_phnum;
@@ -562,6 +612,9 @@ of this helper program; chances are you did not intend to run this program.\n\
         containing a '/' are ignored since it is insecure.  */
       char *list = strdupa (preloadlist);
       char *p;
+
+      HP_TIMING_NOW (start);
+
       while ((p = strsep (&list, " :")) != NULL)
        if (p[0] != '\0'
            && (! __libc_enable_secure || strchr (p, '/') == NULL))
@@ -572,6 +625,10 @@ of this helper program; chances are you did not intend to run this program.\n\
              /* It is no duplicate.  */
              ++npreloads;
          }
+
+      HP_TIMING_NOW (stop);
+      HP_TIMING_DIFF (diff, start, stop);
+      HP_TIMING_ACCUM_NT (load_time, diff);
     }
 
   /* Read the contents of the file.  */
@@ -621,6 +678,8 @@ of this helper program; chances are you did not intend to run this program.\n\
          file[file_size - 1] = '\0';
        }
 
+      HP_TIMING_NOW (start);
+
       if (file != problem)
        {
          char *p;
@@ -646,6 +705,10 @@ of this helper program; chances are you did not intend to run this program.\n\
            ++npreloads;
        }
 
+      HP_TIMING_NOW (stop);
+      HP_TIMING_DIFF (diff, start, stop);
+      HP_TIMING_ACCUM_NT (load_time, diff);
+
       /* We don't need the file anymore.  */
       __munmap (file, file_size);
     }
@@ -668,7 +731,11 @@ of this helper program; chances are you did not intend to run this program.\n\
   /* Load all the libraries specified by DT_NEEDED entries.  If LD_PRELOAD
      specified some libraries to load, these are inserted before the actual
      dependencies in the executable's searchlist for symbol resolution.  */
+  HP_TIMING_NOW (start);
   _dl_map_object_deps (_dl_loaded, preloads, npreloads, mode == trace, 0);
+  HP_TIMING_NOW (stop);
+  HP_TIMING_DIFF (diff, start, stop);
+  HP_TIMING_ACCUM_NT (load_time, diff);
 
   /* Mark all objects as being in the global scope.  */
   for (i = _dl_loaded->l_searchlist.r_nlist; i > 0; )
@@ -884,6 +951,9 @@ of this helper program; chances are you did not intend to run this program.\n\
 
     struct link_map *l;
     int consider_profiling = _dl_profile != NULL;
+    hp_timing_t start;
+    hp_timing_t stop;
+    hp_timing_t add;
 
     /* If we are profiling we also must do lazy reloaction.  */
     lazy |= consider_profiling;
@@ -891,13 +961,19 @@ of this helper program; chances are you did not intend to run this program.\n\
     l = _dl_loaded;
     while (l->l_next)
       l = l->l_next;
+
+    HP_TIMING_NOW (start);
     do
       {
        if (l != &_dl_rtld_map)
          _dl_relocate_object (l, l->l_scope, lazy, consider_profiling);
 
        l = l->l_prev;
-      } while (l);
+      }
+    while (l);
+    HP_TIMING_NOW (stop);
+
+    HP_TIMING_DIFF (relocate_time, start, stop);
 
     /* Do any necessary cleanups for the startup OS interface code.
        We do these now so that no calls are made after rtld re-relocation
@@ -907,9 +983,15 @@ of this helper program; chances are you did not intend to run this program.\n\
     _dl_sysdep_start_cleanup ();
 
     if (_dl_rtld_map.l_opencount > 0)
-      /* There was an explicit ref to the dynamic linker as a shared lib.
-        Re-relocate ourselves with user-controlled symbol definitions.  */
-      _dl_relocate_object (&_dl_rtld_map, _dl_loaded->l_scope, 0, 0);
+      {
+       /* There was an explicit ref to the dynamic linker as a shared lib.
+          Re-relocate ourselves with user-controlled symbol definitions.  */
+       HP_TIMING_NOW (start);
+       _dl_relocate_object (&_dl_rtld_map, _dl_loaded->l_scope, 0, 0);
+       HP_TIMING_NOW (stop);
+       HP_TIMING_DIFF (add, start, stop);
+       HP_TIMING_ACCUM_NT (relocate_time, add);
+      }
   }
 
   /* Now set up the variable which helps the assembler startup code.  */
@@ -1101,6 +1183,14 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n",
                }
              break;
 
+           case 10:
+             if (memcmp (dl_debug, "statistics", 10) == 0)
+               {
+                 _dl_debug_statistics = 1;
+                 continue;
+               }
+             break;
+
            default:
              break;
            }
@@ -1110,6 +1200,7 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n",
            char *startp = strndupa (dl_debug, len);
            _dl_sysdep_error ("warning: debug option `", startp,
                              "' unknown; try LD_DEBUG=help\n", NULL);
+           break;
          }
        }
     }
@@ -1291,3 +1382,74 @@ process_envvars (enum mode *modep, int *lazyp)
 
   *modep = mode;
 }
+
+
+/* Print the various times we collected.  */
+static void
+print_statistics (void)
+{
+  char buf[200];
+  char *cp;
+  char *wp;
+
+  /* Total time rtld used.  */
+  if (HP_TIMING_AVAIL)
+    {
+      HP_TIMING_PRINT (buf, sizeof (buf), rtld_total_time);
+      _dl_debug_message (1, "\nruntime linker statistics:\n"
+                        "  total startup time in dynamic loader: ",
+                        buf, "\n", NULL);
+    }
+
+  /* Print relocation statistics.  */
+  if (HP_TIMING_AVAIL)
+    {
+      HP_TIMING_PRINT (buf, sizeof (buf), relocate_time);
+      _dl_debug_message (1, "            time needed for relocation: ", buf,
+                        NULL);
+      cp = _itoa_word ((1000 * relocate_time) / rtld_total_time,
+                      buf + sizeof (buf), 10, 0);
+      wp = buf;
+      switch (buf + sizeof (buf) - cp)
+       {
+       case 3:
+         *wp++ = *cp++;
+       case 2:
+         *wp++ = *cp++;
+       case 1:
+         *wp++ = '.';
+         *wp++ = *cp++;
+       }
+      *wp = '\0';
+      _dl_debug_message (0, " (", buf, "%)\n", NULL);
+    }
+
+  buf[sizeof (buf) - 1] = '\0';
+  _dl_debug_message (1, "                 number of relocations: ",
+                    _itoa_word (_dl_num_relocations,
+                                buf + sizeof (buf) - 1, 10, 0),
+                    "\n", NULL);
+
+  /* Time spend while loading the object and the dependencies.  */
+  if (HP_TIMING_AVAIL)
+    {
+      HP_TIMING_PRINT (buf, sizeof (buf), load_time);
+      _dl_debug_message (1, "           time needed to load objects: ", buf,
+                        NULL);
+      cp = _itoa_word ((1000 * load_time) / rtld_total_time,
+                      buf + sizeof (buf), 10, 0);
+      wp = buf;
+      switch (buf + sizeof (buf) - cp)
+       {
+       case 3:
+         *wp++ = *cp++;
+       case 2:
+         *wp++ = *cp++;
+       case 1:
+         *wp++ = '.';
+         *wp++ = *cp++;
+       }
+      *wp = '\0';
+      _dl_debug_message (0, " (", buf, "%)\n", NULL);
+    }
+}
index 8302f810c4f5a40214a6c41cad89de781f4fb041..2229c564fecc7d4b0ed165d933b87f0afad0a3d7 100644 (file)
@@ -459,7 +459,7 @@ check_nettype (const char *name, const char *list_to_check[])
          return 1;
        }
     }
-  fprintf (stderr, _ ("illegal nettype :\'%s\'\n"), name);
+  fprintf (stderr, _ ("illegal nettype :`%s'\n"), name);
   return 0;
 }
 
@@ -1144,7 +1144,7 @@ checkfiles (const char *infile, const char *outfile)
       else
        {
          fprintf (stderr,
-                  _("file '%s' already exists and may be overwritten\n"),
+                  _("file `%s' already exists and may be overwritten\n"),
                   outfile);
          crash ();
        }
@@ -1411,7 +1411,7 @@ parseargs (int argc, const char *argv[], struct commandline *cmd)
 static void
 usage (void)
 {
-  fprintf (stderr, _("usage:  %s infile\n"), cmdname);
+  fprintf (stderr, _("usage: %s infile\n"), cmdname);
   fprintf (stderr, _("\t%s [-abkCLNTM][-Dname[=value]] [-i size] \
 [-I [-K seconds]] [-Y path] infile\n"), cmdname);
   fprintf (stderr, _("\t%s [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] \
diff --git a/sysdeps/generic/hp-timing.h b/sysdeps/generic/hp-timing.h
new file mode 100644 (file)
index 0000000..7795f51
--- /dev/null
@@ -0,0 +1,80 @@
+/* High precision, low overhead timing functions.  i686 version.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H   1
+
+
+/* There are no generic definitions for the times.  We could write something
+   using the `gettimeofday' system call where available but the overhead of
+   the system call might be too high.
+
+   In case a platform supports timers in the hardware the following macros
+   and types must be defined:
+
+   - HP_TIMING_AVAIL: test for availability.
+
+   - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+     implemented using function calls but instead uses some inlined code
+     which might simply consist of a few assembler instructions.  We have to
+     know this since we might want to use the macros here in places where we
+     cannot make function calls.
+
+   - hp_timing_t: This is the type for variables used to store the time
+     values.
+
+   - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+   - HP_TIMING_NOW: place timestamp for current time in variable given as
+     parameter.
+
+   - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+     HP_TIMING_DIFF macro.
+
+   - HP_TIMING_DIFF: compute difference between two times and store it
+     in a third.  Source and destination might overlap.
+
+   - HP_TIMING_ACCUM: add time difference to another variable.  This might
+     be a bit more complicated to implement for some platforms as the
+     operation should be thread-safe and 64bit arithmetic on 32bit platforms
+     is not.
+
+   - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+     there are no threads involved.
+
+   - HP_TIMING_PRINT: write decimal representation of the timing value into
+     the given string.  This operation need not be inline even though
+     HP_TIMING_INLINE is specified.
+
+*/
+
+/* Provide dummy definitions.  */
+#define HP_TIMING_AVAIL                (0)
+#define HP_TIMING_INLINE       (0)
+typedef int hp_timing_t;
+#define HP_TIMING_ZERO(Var)
+#define HP_TIMING_NOW(var)
+#define HP_TIMING_DIFF_INIT()
+#define HP_TIMING_DIFF(Diff, Start, End)
+#define HP_TIMING_ACCUM(Sum, Diff)
+#define HP_TIMING_ACCUM_NT(Sum, Diff)
+#define HP_TIMING_PRINT(Buf, Len, Val)
+
+#endif /* hp-timing.h */
index 87d924821a567781023ef6d6cf2fb0f4d70d74c8..8338a93617358d8d21fe7052765947b67aafa6e5 100644 (file)
@@ -335,7 +335,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
               found.  */
            break;
          if (sym->st_size > refsym->st_size
-             || (_dl_verbose && sym->st_size < refsym->st_size))
+             || (sym->st_size < refsym->st_size && _dl_verbose))
            {
              const char *strtab;
 
diff --git a/sysdeps/i386/i686/Makefile b/sysdeps/i386/i686/Makefile
new file mode 100644 (file)
index 0000000..b4b60d0
--- /dev/null
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+sysdep_routines += hp-timing
+endif
diff --git a/sysdeps/i386/i686/hp-timing.c b/sysdeps/i386/i686/hp-timing.c
new file mode 100644 (file)
index 0000000..3f5fcfe
--- /dev/null
@@ -0,0 +1,24 @@
+/* Support for high precision, low overhead timing functions.  i686 version.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <hp-timing.h>
+
+/* We have to define the variable for the overhead.  */
+hp_timing_t __libc_hp_timing_overhead;
diff --git a/sysdeps/i386/i686/hp-timing.h b/sysdeps/i386/i686/hp-timing.h
new file mode 100644 (file)
index 0000000..ffbeb27
--- /dev/null
@@ -0,0 +1,160 @@
+/* High precision, low overhead timing functions.  i686 version.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H   1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+
+/* The macros defined here use the timestamp counter in i586 and up versions
+   of the x86 processors.  They provide a very accurate way to measure the
+   time with very little overhead.  The time values themself have no real
+   meaning, only differences are interesting.
+
+   This version is for the i686 processors.  The difference to the i586
+   version is that the timerstamp register is unconditionally used.  This is
+   not the case for the i586 version where we have to perform runtime test
+   whether the processor really has this capability.  We have to make this
+   distinction since the sysdeps/i386/i586 code is supposed to work on all
+   platforms while the i686 already contains i686-specific code.
+
+   The list of macros we need includes the following:
+
+   - HP_TIMING_AVAIL: test for availability.
+
+   - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+     implemented using function calls but instead uses some inlined code
+     which might simply consist of a few assembler instructions.  We have to
+     know this since we might want to use the macros here in places where we
+     cannot make function calls.
+
+   - hp_timing_t: This is the type for variables used to store the time
+     values.
+
+   - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+   - HP_TIMING_NOW: place timestamp for current time in variable given as
+     parameter.
+
+   - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+     HP_TIMING_DIFF macro.
+
+   - HP_TIMING_DIFF: compute difference between two times and store it
+     in a third.  Source and destination might overlap.
+
+   - HP_TIMING_ACCUM: add time difference to another variable.  This might
+     be a bit more complicated to implement for some platforms as the
+     operation should be thread-safe and 64bit arithmetic on 32bit platforms
+     is not.
+
+   - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+     there are no threads involved.
+
+   - HP_TIMING_PRINT: write decimal representation of the timing value into
+     the given string.  This operation need not be inline even though
+     HP_TIMING_INLINE is specified.
+
+*/
+
+/* We always assume having the timestamp register.  */
+#define HP_TIMING_AVAIL                (1)
+
+/* We indeed have inlined functions.  */
+#define HP_TIMING_INLINE       (1)
+
+/* We use 64bit values for the times.  */
+typedef unsigned long long int hp_timing_t;
+
+/* Internal variabled used to store the overhead of the measurement
+   opcodes.  */
+extern hp_timing_t __libc_hp_timing_overhead;
+
+/* Set timestamp value to zero.  */
+#define HP_TIMING_ZERO(Var)    (Var) = (0)
+
+/* That's quite simple.  Use the `rdtsc' instruction.  Note that the value
+   might not be 100% accurate since there might be some more instructions
+   running in this moment.  This could be changed by using a barrier like
+   'cpuid' right before the `rdtsc' instruciton.  But we are not interested
+   in accurate clock cycles here so we don't do this.  */
+#define HP_TIMING_NOW(Var)     __asm__ __volatile__ ("rdtsc" : "=A" (Var))
+
+/* Use two 'rdtsc' instructions in a row to find out how long it takes.  */
+#define HP_TIMING_DIFF_INIT() \
+  do {                                                                       \
+    int __cnt = 5;                                                           \
+    __libc_hp_timing_overhead = ~0ull;                                       \
+    do                                                                       \
+      {                                                                              \
+       hp_timing_t __t1, __t2;                                               \
+       HP_TIMING_NOW (__t1);                                                 \
+       HP_TIMING_NOW (__t2);                                                 \
+       if (__t2 - __t1 < __libc_hp_timing_overhead)                          \
+         __libc_hp_timing_overhead = __t2 - __t1;                            \
+      }                                                                              \
+    while (--__cnt > 0);                                                     \
+  } while (0)
+
+/* It's simple arithmetic for us.  */
+#define HP_TIMING_DIFF(Diff, Start, End)       (Diff) = ((End) - (Start))
+
+/* We have to jump through hoops to get this correctly implemented.  */
+#define HP_TIMING_ACCUM(Sum, Diff) \
+  do {                                                                       \
+    char __not_done;                                                         \
+    hp_timing_t __oldval = (Sum);                                            \
+    hp_timing_t __diff = (Diff) - __libc_hp_timing_overhead;                 \
+    do                                                                       \
+      {                                                                              \
+       hp_timing_t __newval = __oldval + __diff;                             \
+       int __temp0, __temp1;                                                 \
+       __asm__ __volatile__ ("xchgl %4, %%ebx\n\t"                           \
+                             "lock; cmpxchg8b %1\n\t"                        \
+                             "sete %0\n\t"                                   \
+                             "movl %4, %%ebx"                                \
+                             : "=q" (__not_done), "=m" (Sum),                \
+                               "=A" (__oldval), "=c" (__temp0),              \
+                               "=SD" (__temp1)                               \
+                             : "1" (Sum), "2" (__oldval),                    \
+                               "3" (__newval >> 32),                         \
+                               "4" (__newval & 0xffffffff)                   \
+                             : "memory");                                    \
+      }                                                                              \
+    while (__not_done);                                                              \
+  } while (0)
+
+/* No threads, no extra work.  */
+#define HP_TIMING_ACCUM_NT(Sum, Diff)  (Sum) += (Diff)
+
+/* Print the time value.  */
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+  do {                                                                       \
+    char __buf[20];                                                          \
+    char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0);                 \
+    int __len = (Len);                                                       \
+    char *__dest = (Buf);                                                    \
+    while (__len-- > 0 && __cp < __buf + sizeof (__buf))                     \
+      *__dest++ = *__cp++;                                                   \
+    memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles")));  \
+  } while (0)
+
+#endif /* hp-timing.h */
index 18aa31fa9d851c4b7f75522e562e9b5f41c27e3b..479a4abb08a94bcdb1beaefd5913c02bd1b3c396 100644 (file)
@@ -1,7 +1,9 @@
 clone.S
 init-first.h
+ioperm.c
 setresuid.c
 setresgid.c
 setfsuid.c
 setfsgid.c
 bits/armsigctx.h
+sys/io.h