Home | History | Annotate | Download | only in gold
      1 // timer.cc -- helper class for time accounting
      2 
      3 // Copyright (C) 2009-2016 Free Software Foundation, Inc.
      4 // Written by Rafael Avila de Espindola <espindola (at) google.com>.
      5 
      6 // This file is part of gold.
      7 
      8 // This program is free software; you can redistribute it and/or modify
      9 // it under the terms of the GNU General Public License as published by
     10 // the Free Software Foundation; either version 3 of the License, or
     11 // (at your option) any later version.
     12 
     13 // This program is distributed in the hope that it will be useful,
     14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 // GNU General Public License for more details.
     17 
     18 // You should have received a copy of the GNU General Public License
     19 // along with this program; if not, write to the Free Software
     20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21 // MA 02110-1301, USA.
     22 
     23 #include "gold.h"
     24 
     25 #include <unistd.h>
     26 
     27 #ifdef HAVE_TIMES
     28 #include <sys/times.h>
     29 #endif
     30 
     31 #include "libiberty.h"
     32 
     33 #include "timer.h"
     34 
     35 namespace gold
     36 {
     37 
     38 // Class Timer
     39 
     40 Timer::Timer()
     41 {
     42   this->start_time_.wall = 0;
     43   this->start_time_.user = 0;
     44   this->start_time_.sys = 0;
     45 }
     46 
     47 // Start counting the time.
     48 void
     49 Timer::start()
     50 {
     51   this->get_time(&this->start_time_);
     52 }
     53 
     54 // Record the time used by pass N (0 <= N <= 2).
     55 void
     56 Timer::stamp(int n)
     57 {
     58   gold_assert(n >= 0 && n <= 2);
     59   TimeStats& thispass = this->pass_times_[n];
     60   this->get_time(&thispass);
     61 }
     62 
     63 #if HAVE_SYSCONF && defined _SC_CLK_TCK
     64 # define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
     65 #else
     66 # ifdef CLK_TCK
     67 #  define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
     68 # else
     69 #  ifdef HZ
     70 #   define TICKS_PER_SECOND HZ  /* traditional UNIX */
     71 #  else
     72 #   define TICKS_PER_SECOND 100 /* often the correct value */
     73 #  endif
     74 # endif
     75 #endif
     76 
     77 // times returns statistics in clock_t units.  This variable will hold the
     78 // conversion factor to seconds.  We use a variable that is initialized once
     79 // because sysconf can be slow.
     80 static long ticks_per_sec;
     81 class Timer_init
     82 {
     83  public:
     84   Timer_init()
     85   {
     86     ticks_per_sec = TICKS_PER_SECOND;
     87   }
     88 };
     89 Timer_init timer_init;
     90 
     91 // Write the current time information.
     92 void
     93 Timer::get_time(TimeStats *now)
     94 {
     95 #ifdef HAVE_TIMES
     96   tms t;
     97   now->wall = (times(&t) * 1000) / ticks_per_sec;
     98   now->user = (t.tms_utime * 1000) / ticks_per_sec;
     99   now->sys  = (t.tms_stime * 1000) / ticks_per_sec;
    100 #else
    101   now->wall = get_run_time() / 1000;
    102   now->user = 0;
    103   now->sys = 0;
    104 #endif
    105 }
    106 
    107 // Return the stats since start was called.
    108 Timer::TimeStats
    109 Timer::get_elapsed_time()
    110 {
    111   TimeStats now;
    112   this->get_time(&now);
    113   TimeStats delta;
    114   delta.wall = now.wall - this->start_time_.wall;
    115   delta.user = now.user - this->start_time_.user;
    116   delta.sys = now.sys - this->start_time_.sys;
    117   return delta;
    118 }
    119 
    120 // Return the stats for pass N (0 <= N <= 2).
    121 Timer::TimeStats
    122 Timer::get_pass_time(int n)
    123 {
    124   gold_assert(n >= 0 && n <= 2);
    125   TimeStats thispass = this->pass_times_[n];
    126   TimeStats& lastpass = n > 0 ? this->pass_times_[n-1] : this->start_time_;
    127   thispass.wall -= lastpass.wall;
    128   thispass.user -= lastpass.user;
    129   thispass.sys -= lastpass.sys;
    130   return thispass;
    131 }
    132 
    133 }
    134