annotate libgfortran/intrinsics/time_1.h @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Wrappers for platform timing functions.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2003-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of the GNU Fortran runtime library (libgfortran).
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 Libgfortran is free software; you can redistribute it and/or
kono
parents:
diff changeset
7 modify it under the terms of the GNU General Public
kono
parents:
diff changeset
8 License as published by the Free Software Foundation; either
kono
parents:
diff changeset
9 version 3 of the License, or (at your option) any later version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 Libgfortran is distributed in the hope that it will be useful,
kono
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
14 GNU General Public License for more details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
17 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
18 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
21 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
23 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
24
kono
parents:
diff changeset
25 #ifndef LIBGFORTRAN_TIME_H
kono
parents:
diff changeset
26 #define LIBGFORTRAN_TIME_H
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 #ifdef HAVE_UNISTD_H
kono
parents:
diff changeset
29 #include <unistd.h>
kono
parents:
diff changeset
30 #endif
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 #include <errno.h>
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 /* The time related intrinsics (DTIME, ETIME, CPU_TIME) to "compare
kono
parents:
diff changeset
35 different algorithms on the same computer or discover which parts
kono
parents:
diff changeset
36 are the most expensive", need a way to get the CPU time with the
kono
parents:
diff changeset
37 finest resolution possible. We can only be accurate up to
kono
parents:
diff changeset
38 microseconds.
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 As usual with UNIX systems, unfortunately no single way is
kono
parents:
diff changeset
41 available for all systems. */
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 #ifdef HAVE_SYS_TIME_H
kono
parents:
diff changeset
44 #include <sys/time.h>
kono
parents:
diff changeset
45 #endif
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 #include <time.h>
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 #ifdef HAVE_SYS_TYPES_H
kono
parents:
diff changeset
50 #include <sys/types.h>
kono
parents:
diff changeset
51 #endif
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 /* The most accurate way to get the CPU time is getrusage (). */
kono
parents:
diff changeset
54 #if defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
kono
parents:
diff changeset
55 # include <sys/resource.h>
kono
parents:
diff changeset
56 #endif /* HAVE_GETRUSAGE && HAVE_SYS_RESOURCE_H */
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 /* The most accurate way to get the CPU time is getrusage ().
kono
parents:
diff changeset
59 If we have times(), that's good enough, too. */
kono
parents:
diff changeset
60 #if !defined (HAVE_GETRUSAGE) || !defined (HAVE_SYS_RESOURCE_H)
kono
parents:
diff changeset
61 /* For times(), we _must_ know the number of clock ticks per second. */
kono
parents:
diff changeset
62 # if defined (HAVE_TIMES) && (defined (HZ) || defined (_SC_CLK_TCK) || defined (CLK_TCK))
kono
parents:
diff changeset
63 # ifdef HAVE_SYS_PARAM_H
kono
parents:
diff changeset
64 # include <sys/param.h>
kono
parents:
diff changeset
65 # endif
kono
parents:
diff changeset
66 # if defined (HAVE_SYS_TIMES_H)
kono
parents:
diff changeset
67 # include <sys/times.h>
kono
parents:
diff changeset
68 # endif
kono
parents:
diff changeset
69 # ifndef HZ
kono
parents:
diff changeset
70 # if defined _SC_CLK_TCK
kono
parents:
diff changeset
71 # define HZ sysconf(_SC_CLK_TCK)
kono
parents:
diff changeset
72 # else
kono
parents:
diff changeset
73 # define HZ CLK_TCK
kono
parents:
diff changeset
74 # endif
kono
parents:
diff changeset
75 # endif
kono
parents:
diff changeset
76 # endif /* HAVE_TIMES etc. */
kono
parents:
diff changeset
77 #endif /* !HAVE_GETRUSAGE || !HAVE_SYS_RESOURCE_H */
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 /* If the re-entrant version of localtime is not available, provide a
kono
parents:
diff changeset
81 fallback implementation. On some targets where the _r version is
kono
parents:
diff changeset
82 not available, localtime uses thread-local storage so it's
kono
parents:
diff changeset
83 threadsafe. */
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 #ifndef HAVE_LOCALTIME_R
kono
parents:
diff changeset
86 /* If _POSIX is defined localtime_r gets defined by mingw-w64 headers. */
kono
parents:
diff changeset
87 #ifdef localtime_r
kono
parents:
diff changeset
88 #undef localtime_r
kono
parents:
diff changeset
89 #endif
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 static inline struct tm *
kono
parents:
diff changeset
92 localtime_r (const time_t * timep, struct tm * result)
kono
parents:
diff changeset
93 {
kono
parents:
diff changeset
94 *result = *localtime (timep);
kono
parents:
diff changeset
95 return result;
kono
parents:
diff changeset
96 }
kono
parents:
diff changeset
97 #endif
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 /* Helper function for the actual implementation of the DTIME, ETIME and
kono
parents:
diff changeset
101 CPU_TIME intrinsics. Returns 0 for success or -1 if no
kono
parents:
diff changeset
102 CPU time could be computed. */
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 #if defined(__MINGW32__)
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 #define WIN32_LEAN_AND_MEAN
kono
parents:
diff changeset
107 #include <windows.h>
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 static inline int
kono
parents:
diff changeset
110 gf_cputime (long *user_sec, long *user_usec, long *system_sec, long *system_usec)
kono
parents:
diff changeset
111 {
kono
parents:
diff changeset
112 union {
kono
parents:
diff changeset
113 FILETIME ft;
kono
parents:
diff changeset
114 unsigned long long ulltime;
kono
parents:
diff changeset
115 } kernel_time, user_time;
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 FILETIME unused1, unused2;
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 /* No support for Win9x. The high order bit of the DWORD
kono
parents:
diff changeset
120 returned by GetVersion is 0 for NT and higher. */
kono
parents:
diff changeset
121 if (GetVersion () >= 0x80000000)
kono
parents:
diff changeset
122 {
kono
parents:
diff changeset
123 *user_sec = *system_sec = 0;
kono
parents:
diff changeset
124 *user_usec = *system_usec = 0;
kono
parents:
diff changeset
125 return -1;
kono
parents:
diff changeset
126 }
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 /* The FILETIME structs filled in by GetProcessTimes represent
kono
parents:
diff changeset
129 time in 100 nanosecond units. */
kono
parents:
diff changeset
130 GetProcessTimes (GetCurrentProcess (), &unused1, &unused2,
kono
parents:
diff changeset
131 &kernel_time.ft, &user_time.ft);
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133 *user_sec = user_time.ulltime / 10000000;
kono
parents:
diff changeset
134 *user_usec = (user_time.ulltime % 10000000) / 10;
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 *system_sec = kernel_time.ulltime / 10000000;
kono
parents:
diff changeset
137 *system_usec = (kernel_time.ulltime % 10000000) / 10;
kono
parents:
diff changeset
138 return 0;
kono
parents:
diff changeset
139 }
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 #else
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 static inline int
kono
parents:
diff changeset
144 gf_cputime (long *user_sec, long *user_usec, long *system_sec, long *system_usec)
kono
parents:
diff changeset
145 {
kono
parents:
diff changeset
146 #if defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
kono
parents:
diff changeset
147 struct rusage usage;
kono
parents:
diff changeset
148 int err;
kono
parents:
diff changeset
149 err = getrusage (RUSAGE_SELF, &usage);
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 *user_sec = usage.ru_utime.tv_sec;
kono
parents:
diff changeset
152 *user_usec = usage.ru_utime.tv_usec;
kono
parents:
diff changeset
153 *system_sec = usage.ru_stime.tv_sec;
kono
parents:
diff changeset
154 *system_usec = usage.ru_stime.tv_usec;
kono
parents:
diff changeset
155 return err;
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 #elif defined HAVE_TIMES
kono
parents:
diff changeset
158 struct tms buf;
kono
parents:
diff changeset
159 clock_t err;
kono
parents:
diff changeset
160 err = times (&buf);
kono
parents:
diff changeset
161 long hz = HZ;
kono
parents:
diff changeset
162 *user_sec = buf.tms_utime / hz;
kono
parents:
diff changeset
163 *user_usec = (buf.tms_utime % hz) * (1000000. / hz);
kono
parents:
diff changeset
164 *system_sec = buf.tms_stime / hz;
kono
parents:
diff changeset
165 *system_usec = (buf.tms_stime % hz) * (1000000. / hz);
kono
parents:
diff changeset
166 if ((err == (clock_t) -1) && errno != 0)
kono
parents:
diff changeset
167 return -1;
kono
parents:
diff changeset
168 return 0;
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 #elif defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_PROCESS_CPUTIME_ID) \
kono
parents:
diff changeset
171 || defined(CLOCK_THREAD_CPUTIME_ID))
kono
parents:
diff changeset
172 /* Newer versions of VxWorks have CLOCK_THREAD_CPUTIME_ID giving
kono
parents:
diff changeset
173 per-thread CPU time. CLOCK_PROCESS_CPUTIME_ID would be better
kono
parents:
diff changeset
174 but is not available. */
kono
parents:
diff changeset
175 #ifndef CLOCK_PROCESS_CPUTIME_ID
kono
parents:
diff changeset
176 #define CLOCK_PROCESS_CPUTIME_ID CLOCK_THREAD_CPUTIME_ID
kono
parents:
diff changeset
177 #endif
kono
parents:
diff changeset
178 struct timespec ts;
kono
parents:
diff changeset
179 int err = clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts);
kono
parents:
diff changeset
180 *user_sec = ts.tv_sec;
kono
parents:
diff changeset
181 *user_usec = ts.tv_nsec / 1000;
kono
parents:
diff changeset
182 *system_sec = *system_usec = 0;
kono
parents:
diff changeset
183 return err;
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 #else
kono
parents:
diff changeset
186 clock_t c = clock ();
kono
parents:
diff changeset
187 *user_sec = c / CLOCKS_PER_SEC;
kono
parents:
diff changeset
188 *user_usec = (c % CLOCKS_PER_SEC) * (1000000. / CLOCKS_PER_SEC);
kono
parents:
diff changeset
189 *system_sec = *system_usec = 0;
kono
parents:
diff changeset
190 if (c == (clock_t) -1)
kono
parents:
diff changeset
191 return -1;
kono
parents:
diff changeset
192 return 0;
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 #endif
kono
parents:
diff changeset
195 }
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 #endif
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 /* Realtime clock with microsecond resolution, falling back to other
kono
parents:
diff changeset
201 functions if the target does not support gettimeofday().
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 Arguments:
kono
parents:
diff changeset
204 secs - OUTPUT, seconds
kono
parents:
diff changeset
205 usecs - OUTPUT, microseconds
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 The OUTPUT arguments shall represent the number of seconds and
kono
parents:
diff changeset
208 microseconds since the Epoch.
kono
parents:
diff changeset
209
kono
parents:
diff changeset
210 Return value: 0 for success, -1 for error. In case of error, errno
kono
parents:
diff changeset
211 is set.
kono
parents:
diff changeset
212 */
kono
parents:
diff changeset
213 static inline int
kono
parents:
diff changeset
214 gf_gettime (time_t * secs, long * usecs)
kono
parents:
diff changeset
215 {
kono
parents:
diff changeset
216 #ifdef HAVE_GETTIMEOFDAY
kono
parents:
diff changeset
217 struct timeval tv;
kono
parents:
diff changeset
218 int err;
kono
parents:
diff changeset
219 err = gettimeofday (&tv, NULL);
kono
parents:
diff changeset
220 *secs = tv.tv_sec;
kono
parents:
diff changeset
221 *usecs = tv.tv_usec;
kono
parents:
diff changeset
222 return err;
kono
parents:
diff changeset
223 #elif defined(HAVE_CLOCK_GETTIME)
kono
parents:
diff changeset
224 struct timespec ts;
kono
parents:
diff changeset
225 int err = clock_gettime (CLOCK_REALTIME, &ts);
kono
parents:
diff changeset
226 *secs = ts.tv_sec;
kono
parents:
diff changeset
227 *usecs = ts.tv_nsec / 1000;
kono
parents:
diff changeset
228 return err;
kono
parents:
diff changeset
229 #else
kono
parents:
diff changeset
230 time_t t = time (NULL);
kono
parents:
diff changeset
231 *secs = t;
kono
parents:
diff changeset
232 *usecs = 0;
kono
parents:
diff changeset
233 if (t == ((time_t)-1))
kono
parents:
diff changeset
234 return -1;
kono
parents:
diff changeset
235 return 0;
kono
parents:
diff changeset
236 #endif
kono
parents:
diff changeset
237 }
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239
kono
parents:
diff changeset
240 #endif /* LIBGFORTRAN_TIME_H */