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