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