diff options
author | Rafael Ávila de Espíndola <respindola@mozilla.com> | 2009-12-17 16:02:03 +0000 |
---|---|---|
committer | Rafael Ávila de Espíndola <respindola@mozilla.com> | 2009-12-17 16:02:03 +0000 |
commit | d675ff4684242402af02908e431ed5e9fe045320 (patch) | |
tree | 45bfbe1903cf6096bd6e80327625852653480829 | |
parent | ff4a8d2b939133ea12e8994ff1f83d3a8e17baa2 (diff) | |
download | binutils-gdb-d675ff4684242402af02908e431ed5e9fe045320.tar.gz |
2009-12-17 Rafael Avila de Espindola <espindola@google.com>
* Makefile.am (CCFILES): Add timer.cc.
(HFILES): Add timer.h.
* configure.ac: Check for sysconf and times.
* main.cc: include timer.h.
(main): Use Timer instead of get_run_time.
* timer.cc: New.
* timer.h: New.
* workqueue.cc: include timer.h.
(Workqueue::find_and_run_task):
Report user, sys and wall time.
* Makefile.in: Regenerate.
* config.in: Regenerate.
* configure: Regenerate.
-rw-r--r-- | gold/ChangeLog | 16 | ||||
-rw-r--r-- | gold/Makefile.am | 2 | ||||
-rw-r--r-- | gold/Makefile.in | 7 | ||||
-rw-r--r-- | gold/config.in | 6 | ||||
-rwxr-xr-x | gold/configure | 2 | ||||
-rw-r--r-- | gold/configure.ac | 2 | ||||
-rw-r--r-- | gold/main.cc | 17 | ||||
-rw-r--r-- | gold/timer.cc | 107 | ||||
-rw-r--r-- | gold/timer.h | 69 | ||||
-rw-r--r-- | gold/workqueue.cc | 19 |
10 files changed, 236 insertions, 11 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index b6cd629ab51..14cce02167f 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,19 @@ +2009-12-17 Rafael Avila de Espindola <espindola@google.com> + + * Makefile.am (CCFILES): Add timer.cc. + (HFILES): Add timer.h. + * configure.ac: Check for sysconf and times. + * main.cc: include timer.h. + (main): Use Timer instead of get_run_time. + * timer.cc: New. + * timer.h: New. + * workqueue.cc: include timer.h. + (Workqueue::find_and_run_task): + Report user, sys and wall time. + * Makefile.in: Regenerate. + * config.in: Regenerate. + * configure: Regenerate. + 2009-12-16 Doug Kwan <dougkwan@google.com> * arm.cc (Arm_relobj::scan_sections_for_stubs): Exclude ICF-eliminated diff --git a/gold/Makefile.am b/gold/Makefile.am index 6afca178b44..9c9ed1a7370 100644 --- a/gold/Makefile.am +++ b/gold/Makefile.am @@ -78,6 +78,7 @@ CCFILES = \ symtab.cc \ target.cc \ target-select.cc \ + timer.cc \ version.cc \ workqueue.cc \ workqueue-threads.cc @@ -124,6 +125,7 @@ HFILES = \ target.h \ target-reloc.h \ target-select.h \ + timer.h \ tls.h \ token.h \ workqueue.h \ diff --git a/gold/Makefile.in b/gold/Makefile.in index 38bd887fbe3..b6e743a91f0 100644 --- a/gold/Makefile.in +++ b/gold/Makefile.in @@ -87,8 +87,8 @@ am__objects_1 = archive.$(OBJEXT) attributes.$(OBJEXT) \ reduced_debug_output.$(OBJEXT) reloc.$(OBJEXT) \ resolve.$(OBJEXT) script-sections.$(OBJEXT) script.$(OBJEXT) \ stringpool.$(OBJEXT) symtab.$(OBJEXT) target.$(OBJEXT) \ - target-select.$(OBJEXT) version.$(OBJEXT) workqueue.$(OBJEXT) \ - workqueue-threads.$(OBJEXT) + target-select.$(OBJEXT) timer.$(OBJEXT) version.$(OBJEXT) \ + workqueue.$(OBJEXT) workqueue-threads.$(OBJEXT) am__objects_2 = am__objects_3 = yyscript.$(OBJEXT) am_libgold_a_OBJECTS = $(am__objects_1) $(am__objects_2) \ @@ -392,6 +392,7 @@ CCFILES = \ symtab.cc \ target.cc \ target-select.cc \ + timer.cc \ version.cc \ workqueue.cc \ workqueue-threads.cc @@ -438,6 +439,7 @@ HFILES = \ target.h \ target-reloc.h \ target-select.h \ + timer.h \ tls.h \ token.h \ workqueue.h \ @@ -641,6 +643,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symtab.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target-select.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/workqueue-threads.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/workqueue.Po@am__quote@ diff --git a/gold/config.in b/gold/config.in index 745510b081c..7a824b045a0 100644 --- a/gold/config.in +++ b/gold/config.in @@ -117,6 +117,9 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H +/* Define to 1 if you have the `sysconf' function. */ +#undef HAVE_SYSCONF + /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H @@ -138,6 +141,9 @@ /* Define if attributes work on C++ templates */ #undef HAVE_TEMPLATE_ATTRIBUTES +/* Define to 1 if you have the `times' function. */ +#undef HAVE_TIMES + /* Define to 1 if you have the <tr1/unordered_map> header file. */ #undef HAVE_TR1_UNORDERED_MAP diff --git a/gold/configure b/gold/configure index 30bd132d749..1bb2d3dee21 100755 --- a/gold/configure +++ b/gold/configure @@ -6701,7 +6701,7 @@ fi done -for ac_func in mallinfo posix_fallocate readv +for ac_func in mallinfo posix_fallocate readv sysconf times do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/gold/configure.ac b/gold/configure.ac index 2f9cc43a99e..f279b450a20 100644 --- a/gold/configure.ac +++ b/gold/configure.ac @@ -338,7 +338,7 @@ AC_LANG_PUSH(C++) AC_CHECK_HEADERS(tr1/unordered_set tr1/unordered_map) AC_CHECK_HEADERS(ext/hash_map ext/hash_set) AC_CHECK_HEADERS(byteswap.h) -AC_CHECK_FUNCS(mallinfo posix_fallocate readv) +AC_CHECK_FUNCS(mallinfo posix_fallocate readv sysconf times) AC_CHECK_DECLS([basename, ffs, asprintf, vasprintf, snprintf, vsnprintf, strverscmp, strndup, memmem]) # Use of ::std::tr1::unordered_map::rehash causes undefined symbols diff --git a/gold/main.cc b/gold/main.cc index 66e8b244318..c9d0d7966c4 100644 --- a/gold/main.cc +++ b/gold/main.cc @@ -46,6 +46,7 @@ #include "gc.h" #include "icf.h" #include "incremental.h" +#include "timer.h" using namespace gold; @@ -161,9 +162,9 @@ main(int argc, char** argv) Command_line command_line; command_line.process(argc - 1, const_cast<const char**>(argv + 1)); - long start_time = 0; + Timer timer; if (command_line.options().stats()) - start_time = get_run_time(); + timer.start(); // Store some options in the globally accessible parameters. set_parameters_options(&command_line.options()); @@ -247,9 +248,15 @@ main(int argc, char** argv) if (command_line.options().stats()) { - long run_time = get_run_time() - start_time; - fprintf(stderr, _("%s: total run time: %ld.%06ld seconds\n"), - program_name, run_time / 1000000, run_time % 1000000); + Timer::TimeStats elapsed = timer.get_elapsed_time(); + fprintf(stderr, + _("%s: total run time: " \ + "(user: %ld.%06ld sys: %ld.%06ld wall: %ld.%06ld)\n"), + program_name, + elapsed.user / 1000, (elapsed.user % 1000) * 1000, + elapsed.sys / 1000, (elapsed.user % 1000) * 1000, + elapsed.wall / 1000, (elapsed.wall % 1000) * 1000); + #ifdef HAVE_MALLINFO struct mallinfo m = mallinfo(); fprintf(stderr, _("%s: total space allocated by malloc: %d bytes\n"), diff --git a/gold/timer.cc b/gold/timer.cc new file mode 100644 index 00000000000..ec51bc9151e --- /dev/null +++ b/gold/timer.cc @@ -0,0 +1,107 @@ +// timer.cc -- helper class for time accounting + +// Copyright 2009 Free Software Foundation, Inc. +// Written by Rafael Avila de Espindola <espindola@google.com>. + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +#include "gold.h" + +#include <sys/times.h> + +#include "libiberty.h" + +#include "timer.h" + +namespace gold +{ + +// Class Timer + +Timer::Timer() +{ + this->start_time_.wall = 0; + this->start_time_.user = 0; + this->start_time_.sys = 0; +} + +// Start couting the time. +void +Timer::start () +{ + this->get_time(&this->start_time_); +} + +#if HAVE_SYSCONF && defined _SC_CLK_TCK +# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */ +#else +# ifdef CLK_TCK +# define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */ +# else +# ifdef HZ +# define TICKS_PER_SECOND HZ /* traditional UNIX */ +# else +# define TICKS_PER_SECOND 100 /* often the correct value */ +# endif +# endif +#endif + +// times returns statistics in clock_t units. This variable will hold the +// conversion factor to seconds. We use a variable that is initialize once +// because sysconf can be slow. +static long ticks_per_sec; +class Timer_init +{ + public: + Timer_init() + { + ticks_per_sec = TICKS_PER_SECOND; + } +}; +Timer_init timer_init; + +// Write the current time infortamion. +void +Timer::get_time (TimeStats *now) +{ +#ifdef HAVE_TIMES + tms t; + now->wall = (times(&t) * 1000) / ticks_per_sec; + now->user = (t.tms_utime * 1000) / ticks_per_sec; + now->sys = (t.tms_stime * 1000) / ticks_per_sec; +#else + now->wall = get_run_time() / 1000; + now->user = 0; + now->sys = 0; +#endif +} + +// Return the stats since start was called. +Timer::TimeStats +Timer::get_elapsed_time () +{ + TimeStats now; + this->get_time(&now); + TimeStats delta; + delta.wall = now.wall - this->start_time_.wall; + delta.user = now.user - this->start_time_.user; + delta.sys = now.sys - this->start_time_.sys; + return delta; +} + +} diff --git a/gold/timer.h b/gold/timer.h new file mode 100644 index 00000000000..ea360c2f21d --- /dev/null +++ b/gold/timer.h @@ -0,0 +1,69 @@ +// timer.h -- helper class for time accounting -*- C++ -*- + +// Copyright 2009 Free Software Foundation, Inc. +// Written by Rafael Avila de Espindola <espindola@google.com>. + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +#ifndef GOLD_TIMER_H +#define GOLD_TIMER_H + +namespace gold +{ + +class Timer +{ + public: + // Used to report time statistics. All fields are in milliseconds. + struct TimeStats + { + /* User time in this process. */ + long user; + + /* System time in this process. */ + long sys; + + /* Wall clock time. */ + long wall; + }; + + Timer(); + + // Return the stats since start was called. + TimeStats + get_elapsed_time(); + + // Start couting the time. + void + start(); + + private: + // This class cannot be copied. + Timer(const Timer&); + Timer& operator=(const Timer&); + + // Write the current time infortamion. + static void + get_time(TimeStats *now); + + // The time of the last call to start. + TimeStats start_time_; +}; + +} +#endif diff --git a/gold/workqueue.cc b/gold/workqueue.cc index 18c39003abd..c713dca1dc2 100644 --- a/gold/workqueue.cc +++ b/gold/workqueue.cc @@ -24,6 +24,7 @@ #include "debug.h" #include "options.h" +#include "timer.h" #include "workqueue.h" #include "workqueue-internal.h" @@ -311,10 +312,24 @@ Workqueue::find_and_run_task(int thread_number) gold_debug(DEBUG_TASK, "%3d running task %s", thread_number, t->name().c_str()); + Timer timer; + if (is_debugging_enabled(DEBUG_TASK)) + timer.start(); + t->run(this); - gold_debug(DEBUG_TASK, "%3d completed task %s", thread_number, - t->name().c_str()); + if (is_debugging_enabled(DEBUG_TASK)) + { + Timer::TimeStats elapsed = timer.get_elapsed_time(); + + gold_debug(DEBUG_TASK, + "%3d completed task %s " + "(user: %ld.%06ld sys: %ld.%06ld wall: %ld.%06ld)", + thread_number, t->name().c_str(), + elapsed.user / 1000, (elapsed.user % 1000) * 1000, + elapsed.sys / 1000, (elapsed.user % 1000) * 1000, + elapsed.wall / 1000, (elapsed.wall % 1000) * 1000); + } Task* next; { |