1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
26 #include <sys/resource.h>
28 #include <sys/times.h>
31 #if defined(sparc) || defined(__sparcv9)
33 #elif defined(__aarch64__)
39 /* typedef and function prototypes for hi-resolution timers */
40 typedef long long hrtime_t
;
41 #if defined(__cplusplus)
45 hrtime_t
gethrtime ();
46 hrtime_t
gethrvtime ();
47 hrtime_t
gethrustime ();
48 hrtime_t
gethrpxtime ();
49 int get_clock_rate ();
52 /* prototype underscore-appended wrappers for Fortran usage */
53 hrtime_t
gethrtime_ ();
54 hrtime_t
gethrustime_ ();
55 hrtime_t
gethrpxtime_ ();
56 hrtime_t
gethrvtime_ ();
57 int get_clock_rate_ ();
58 #if defined(__cplusplus)
62 /* =============================================================== */
64 * Below this are the get_clock_rate() and get_ncpus() for all OSs and architectures
69 static int clock_rate
= 0;
71 static char msgbuf
[1024];
76 /* Linux version -- read /proc/cpuinfo
77 * Note the parsing is different on intel-Linux and sparc-Linux
79 FILE *fp
= fopen ("/proc/cpuinfo", "r");
83 while (fgets (temp
, sizeof (temp
), fp
) != NULL
)
86 /* cpu count for SPARC linux -- read from /proc/cpuinfo */
87 if (strncmp (temp
, "ncpus active", 12) == 0)
89 char *val
= strchr (temp
, ':');
90 ncpus
= val
? atol (val
+ 1) : 0;
96 /* pick the first line that gives a CPU clock rate */
99 if (strncmp (temp
, "Cpu0ClkTck", 10) == 0)
101 char *val
= strchr (temp
, ':');
102 clk
= val
? strtoll (val
+ 1, NULL
, 16) : 0;
103 clock_rate
= (int) (clk
/ 1000000);
106 if (strncmp (temp
, "cpu MHz", 7) == 0)
108 char *val
= strchr (temp
, ':');
109 clock_rate
= val
? atoi (val
+ 1) : 0;
114 /* did we get a clock rate? */
118 /* since we got a cpu count, we can break from the look */
123 /* On intel-Linux, count cpus based on "cpu MHz" lines */
124 if (strncmp (temp
, "cpu MHz", 7) == 0)
132 sprintf (msgbuf
, "Clock rate = %d MHz (from reading /proc/cpuinfo) %d CPUs\n", clock_rate
, ncpus
);
134 /* did we get a clock rate? */
138 sprintf (msgbuf
, "Clock rate = %d MHz (set by default) %d CPUs\n",
148 (void) get_clock_rate ();
153 /* gethrpxtime -- per-process user+system CPU time from POSIX times() */
154 /* does not include the child user and system CPU time */
159 static int initted
= 0;
160 static hrtime_t ns_per_tick
;
163 static long ticks_per_sec
;
164 ticks_per_sec
= sysconf (_SC_CLK_TCK
);
165 ns_per_tick
= 1000000000 / ticks_per_sec
;
168 struct tms mytms
= {0};
170 clock_t curtick
= times (&mytms
);
171 if (curtick
== 0) return rc
;
172 rc
= (mytms
.tms_utime
+ mytms
.tms_stime
) * ns_per_tick
;
176 /* gethrustime -- per-process user+system CPU time from getrusage() */
181 if (0 == getrusage (RUSAGE_SELF
, &usage
))
183 hrtime_t rc
= usage
.ru_utime
.tv_sec
/* seconds */
184 + usage
.ru_stime
.tv_sec
;
185 rc
= usage
.ru_utime
.tv_usec
/* microseconds */
186 + usage
.ru_stime
.tv_usec
+ 1000000 * rc
;
187 rc
*= 1000; /* nanoseconds */
195 * Below this are the Linux versions of gethrvtime and gethrtime
202 int r
= clock_gettime (CLOCK_THREAD_CPUTIME_ID
, &tp
);
204 rc
= ((hrtime_t
) tp
.tv_sec
) * 1000000000 + (hrtime_t
) tp
.tv_nsec
;
208 /* generic gethrvtime -- uses gethrtcputime */
212 return gethrtcputime ();
217 * Clock that cannot be set and represents monotonic time since some
218 * unspecified starting point.
225 #ifdef CLOCK_MONOTONIC_RAW
226 int r
= clock_gettime (CLOCK_MONOTONIC_RAW
, &tp
);
228 int r
= clock_gettime (CLOCK_MONOTONIC
, &tp
);
232 rc
= ((hrtime_t
) tp
.tv_sec
) * 1000000000 + (hrtime_t
) tp
.tv_nsec
;
237 * define underscore-appended wrappers for Fortran usage
248 return gethrustime ();
254 return gethrpxtime ();
260 return gethrvtime ();
266 return get_clock_rate ();
270 init_micro_acct () { }