1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*-------------------------------------------------------------------------
15 *
16 * Created: H5timer.c
17 * Aug 21 2006
18 * Quincey Koziol <koziol@hdfgroup.org>
19 *
20 * Purpose: Internal 'timer' routines & support routines.
21 *
22 *-------------------------------------------------------------------------
23 */
24
25 /****************/
26 /* Module Setup */
27 /****************/
28
29
30 /***********/
31 /* Headers */
32 /***********/
33 #include "H5private.h" /* Generic Functions */
34
35 /* We need this for the struct rusage declaration */
36 #if defined(H5_HAVE_GETRUSAGE) && defined(H5_HAVE_SYS_RESOURCE_H)
37 # include <sys/resource.h>
38 #endif
39
40 #if defined(H5_HAVE_GETTIMEOFDAY) && defined(H5_HAVE_SYS_TIME_H)
41 #include <sys/time.h>
42 #endif
43
44
45 /****************/
46 /* Local Macros */
47 /****************/
48
49
50 /******************/
51 /* Local Typedefs */
52 /******************/
53
54
55 /********************/
56 /* Package Typedefs */
57 /********************/
58
59
60 /********************/
61 /* Local Prototypes */
62 /********************/
63
64
65 /*********************/
66 /* Package Variables */
67 /*********************/
68
69
70 /*****************************/
71 /* Library Private Variables */
72 /*****************************/
73
74
75 /*******************/
76 /* Local Variables */
77 /*******************/
78
79
80 /*-------------------------------------------------------------------------
81 * Function: H5_timer_reset
82 *
83 * Purpose: Resets the timer struct to zero. Use this to reset a timer
84 * that's being used as an accumulator for summing times.
85 *
86 * Return: void
87 *
88 * Programmer: Robb Matzke
89 * Thursday, April 16, 1998
90 *
91 *-------------------------------------------------------------------------
92 */
93 void
H5_timer_reset(H5_timer_t * timer)94 H5_timer_reset (H5_timer_t *timer)
95 {
96 HDassert(timer);
97 HDmemset(timer, 0, sizeof *timer);
98 } /* end H5_timer_reset() */
99
100
101 /*-------------------------------------------------------------------------
102 * Function: H5_timer_begin
103 *
104 * Purpose: Initialize a timer to time something.
105 *
106 * Return: void
107 *
108 * Programmer: Robb Matzke
109 * Thursday, April 16, 1998
110 *
111 *-------------------------------------------------------------------------
112 */
113 void
H5_timer_begin(H5_timer_t * timer)114 H5_timer_begin (H5_timer_t *timer)
115 {
116 #ifdef H5_HAVE_GETRUSAGE
117 struct rusage rusage;
118 #endif
119 #ifdef H5_HAVE_GETTIMEOFDAY
120 struct timeval etime;
121 #endif
122
123 HDassert(timer);
124
125 #ifdef H5_HAVE_GETRUSAGE
126 HDgetrusage (RUSAGE_SELF, &rusage);
127 timer->utime = (double)rusage.ru_utime.tv_sec +
128 ((double)rusage.ru_utime.tv_usec / (double)1e6F);
129 timer->stime = (double)rusage.ru_stime.tv_sec +
130 ((double)rusage.ru_stime.tv_usec / (double)1e6F);
131 #else
132 timer->utime = 0.0F;
133 timer->stime = 0.0F;
134 #endif
135 #ifdef H5_HAVE_GETTIMEOFDAY
136 HDgettimeofday (&etime, NULL);
137 timer->etime = (double)etime.tv_sec + ((double)etime.tv_usec / (double)1e6F);
138 #else
139 timer->etime = 0.0F;
140 #endif
141 } /* end H5_timer_begin() */
142
143
144 /*-------------------------------------------------------------------------
145 * Function: H5_timer_end
146 *
147 * Purpose: This function should be called at the end of a timed region.
148 * The SUM is an optional pointer which will accumulate times.
149 * TMS is the same struct that was passed to H5_timer_start().
150 * On return, TMS will contain total times for the timed region.
151 *
152 * Return: void
153 *
154 * Programmer: Robb Matzke
155 * Thursday, April 16, 1998
156 *
157 *-------------------------------------------------------------------------
158 */
159 void
H5_timer_end(H5_timer_t * sum,H5_timer_t * timer)160 H5_timer_end (H5_timer_t *sum/*in,out*/, H5_timer_t *timer/*in,out*/)
161 {
162 H5_timer_t now;
163
164 HDassert(timer);
165 H5_timer_begin(&now);
166
167 timer->utime = MAX((double)0.0F, now.utime - timer->utime);
168 timer->stime = MAX((double)0.0F, now.stime - timer->stime);
169 timer->etime = MAX((double)0.0F, now.etime - timer->etime);
170
171 if (sum) {
172 sum->utime += timer->utime;
173 sum->stime += timer->stime;
174 sum->etime += timer->etime;
175 }
176 } /* end H5_timer_end() */
177
178
179 /*-------------------------------------------------------------------------
180 * Function: H5_bandwidth
181 *
182 * Purpose: Prints the bandwidth (bytes per second) in a field 10
183 * characters wide widh four digits of precision like this:
184 *
185 * NaN If <=0 seconds
186 * 1234. TB/s
187 * 123.4 TB/s
188 * 12.34 GB/s
189 * 1.234 MB/s
190 * 4.000 kB/s
191 * 1.000 B/s
192 * 0.000 B/s If NBYTES==0
193 * 1.2345e-10 For bandwidth less than 1
194 * 6.7893e+94 For exceptionally large values
195 * 6.678e+106 For really big values
196 *
197 * Return: void
198 *
199 * Programmer: Robb Matzke
200 * Wednesday, August 5, 1998
201 *
202 *-------------------------------------------------------------------------
203 */
204 void
H5_bandwidth(char * buf,double nbytes,double nseconds)205 H5_bandwidth(char *buf/*out*/, double nbytes, double nseconds)
206 {
207 double bw;
208
209 if(nseconds <= (double)0.0F)
210 HDstrcpy(buf, " NaN");
211 else {
212 bw = nbytes/nseconds;
213 if(H5_DBL_ABS_EQUAL(bw, (double)0.0F))
214 HDstrcpy(buf, "0.000 B/s");
215 else if(bw < (double)1.0F)
216 sprintf(buf, "%10.4e", bw);
217 else if(bw < (double)H5_KB) {
218 sprintf(buf, "%05.4f", bw);
219 HDstrcpy(buf+5, " B/s");
220 } else if(bw < (double)H5_MB) {
221 sprintf(buf, "%05.4f", bw / (double)H5_KB);
222 HDstrcpy(buf+5, " kB/s");
223 } else if(bw < (double)H5_GB) {
224 sprintf(buf, "%05.4f", bw / (double)H5_MB);
225 HDstrcpy(buf+5, " MB/s");
226 } else if(bw < (double)H5_TB) {
227 sprintf(buf, "%05.4f", bw / (double)H5_GB);
228 HDstrcpy(buf+5, " GB/s");
229 } else if(bw < (double)H5_PB) {
230 sprintf(buf, "%05.4f", bw / (double)H5_TB);
231 HDstrcpy(buf+5, " TB/s");
232 } else {
233 sprintf(buf, "%10.4e", bw);
234 if(HDstrlen(buf) > 10)
235 sprintf(buf, "%10.3e", bw);
236 }
237 }
238 } /* end H5_bandwidth() */
239
240
241 /*-------------------------------------------------------------------------
242 * Function: H5_now
243 *
244 * Purpose: Retrieves the current time, as seconds after the UNIX epoch.
245 *
246 * Return: # of seconds from the epoch (can't fail)
247 *
248 * Programmer: Quincey Koziol
249 * Tuesday, November 28, 2006
250 *
251 *-------------------------------------------------------------------------
252 */
253 time_t
H5_now(void)254 H5_now(void)
255 {
256 time_t now; /* Current time */
257
258 #ifdef H5_HAVE_GETTIMEOFDAY
259 {
260 struct timeval now_tv;
261
262 HDgettimeofday(&now_tv, NULL);
263 now = now_tv.tv_sec;
264 }
265 #else /* H5_HAVE_GETTIMEOFDAY */
266 now = HDtime(NULL);
267 #endif /* H5_HAVE_GETTIMEOFDAY */
268
269 return(now);
270 } /* end H5_now() */
271
272