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