diff options
author | Ulrich Drepper <drepper@redhat.com> | 1998-12-27 17:29:47 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1998-12-27 17:29:47 +0000 |
commit | db276fa11c8a8b574f3467680a3372504629c114 (patch) | |
tree | 435be6762f532b187ee91070b49c82667a4f79ea | |
parent | 8352b484cfe1c87f99d41e976da5427082fed58c (diff) | |
download | glibc-db276fa11c8a8b574f3467680a3372504629c114.tar.gz glibc-db276fa11c8a8b574f3467680a3372504629c114.tar.xz glibc-db276fa11c8a8b574f3467680a3372504629c114.zip |
Update.
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.
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | elf/rtld.c | 174 | ||||
-rw-r--r-- | sunrpc/rpc_main.c | 6 | ||||
-rw-r--r-- | sysdeps/generic/hp-timing.h | 80 | ||||
-rw-r--r-- | sysdeps/i386/dl-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/i386/i686/Makefile | 3 | ||||
-rw-r--r-- | sysdeps/i386/i686/hp-timing.c | 24 | ||||
-rw-r--r-- | sysdeps/i386/i686/hp-timing.h | 160 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/Dist | 2 |
9 files changed, 468 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog index f7b3c0de96..51109f1d58 100644 --- 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): diff --git a/elf/rtld.c b/elf/rtld.c index 38c7b051b1..df6a945105 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -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); + } +} diff --git a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c index 8302f810c4..2229c564fe 100644 --- a/sunrpc/rpc_main.c +++ b/sunrpc/rpc_main.c @@ -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 index 0000000000..7795f510d5 --- /dev/null +++ b/sysdeps/generic/hp-timing.h @@ -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 */ diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 87d924821a..8338a93617 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -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 index 0000000000..b4b60d0814 --- /dev/null +++ b/sysdeps/i386/i686/Makefile @@ -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 index 0000000000..3f5fcfe1e5 --- /dev/null +++ b/sysdeps/i386/i686/hp-timing.c @@ -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 index 0000000000..ffbeb277e5 --- /dev/null +++ b/sysdeps/i386/i686/hp-timing.h @@ -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 */ diff --git a/sysdeps/unix/sysv/linux/arm/Dist b/sysdeps/unix/sysv/linux/arm/Dist index 18aa31fa9d..479a4abb08 100644 --- a/sysdeps/unix/sysv/linux/arm/Dist +++ b/sysdeps/unix/sysv/linux/arm/Dist @@ -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 |