2 static char sfs_c_clkSid[] = "@(#)sfs_c_clk.c 2.1 97/10/23";
6 * Copyright (c) 1992-1997,2001 by Standard Performance Evaluation Corporation
8 * Standard Performance Evaluation Corporation (SPEC)
9 * 6585 Merchant Place, Suite 100
12 * This product contains benchmarks acquired from several sources who
13 * understand and agree with SPEC's goal of creating fair and objective
14 * benchmarks to measure computer performance.
16 * This copyright notice is placed here only to protect SPEC in the
17 * event the source is misused in any manner that is contrary to the
18 * spirit, the goals and the intent of SPEC.
20 * The source code is provided to the user or company under the license
21 * agreement for the SPEC Benchmark Suite for this product.
24 /*****************************************************************
26 * Copyright 1991,1992 Legato Systems, Inc. *
27 * Copyright 1991,1992 Auspex Systems, Inc. *
28 * Copyright 1991,1992 Data General Corporation *
29 * Copyright 1991,1992 Digital Equipment Corporation *
30 * Copyright 1991,1992 Interphase Corporation *
31 * Copyright 1991,1992 Sun Microsystems, Inc. *
33 *****************************************************************/
36 * ---------------------- sfs_c_clk.c ---------------------
38 * Clock handling. Routines to read the clock, measure elapsed
39 * time and sleep for a timed interval.
42 * void sfs_gettime(struct ladtime *)
43 * void sfs_elapsedtime(sfs_op_type *, struct ladtime *,
51 * 05-Jan-92 Pawlowski Added raw data dump hooks.
52 * 16-Dec-91 Wittle Created.
57 * ------------------------- Include Files -------------------------
70 #include <sys/types.h>
73 #include <sys/times.h>
75 #include <sys/signal.h>
80 #include "sfs_c_def.h"
82 #if !(defined(USE_GETTIMEOFDAY) || defined(USE_TIMES))
83 #define USE_GETTIMEOFDAY
86 #define CLK_RESOLUTION 10 /* clock resolution in msec */
89 * ------------------------- Clock Handling -------------------------
92 #if defined(USE_GETTIMEOFDAY)
94 * The time that the test first starts, all times are relative to this
95 * value to prevent integer overflows.
97 extern struct ladtime test_start = {0, 0, 0};
100 * Get the time of day, offset by 'tz_ptr', and return it in 'time_ptr'.
101 * This is a local time of day interface to allow support for system
102 * dependent clock resolution.
106 struct ladtime *time_ptr)
111 (void) gettimeofday(&tv, NULL);
113 * Use standard time function to get epoch time since 1970 for
116 t = time((time_t *)NULL);
118 if (test_start.sec == 0 && test_start.usec == 0) {
119 test_start.sec = tv.tv_sec;
122 time_ptr->sec = tv.tv_sec - test_start.sec;
123 time_ptr->usec = tv.tv_usec;
125 time_ptr->esec = (int32_t)t;
127 #endif /* USE_GETTIMEOFDAY */
129 #if defined(USE_TIMES)
130 static uint32_t test_start = 0;
134 struct ladtime *time_ptr)
137 uint32_t clock_ticks;
139 int32_t ticks_per_sec = 100;
142 * Try use possible conversions from least accurate to most accurate
148 ticks_per_sec = CLK_TCK;
150 #if defined(_SC_CLK_TCK)
151 ticks_per_sec = sysconf(_SC_CLK_TCK);
152 #endif /* _SC_CLK_TCK */
154 if ((clock_ticks = (uint32_t)times(&tms)) == -1) {
155 (void) fprintf(stderr, "%s: can't get time of day from system: %s\n",
156 sfs_Myname, strerror(errno));
157 (void) generic_kill(0, SIGINT);
162 * Use standard time function to get epoch time since 1970 for
165 t = time((time_t *)NULL);
167 if (test_start == 0) {
168 test_start = clock_ticks;
171 time_ptr->sec = (clock_ticks - test_start) / ticks_per_sec;
172 time_ptr->usec = ((clock_ticks - test_start) -
173 (time_ptr->sec * ticks_per_sec)) *
174 (1000000/ticks_per_sec);
175 time_ptr->esec = (int32_t)t;
177 #endif /* USE_TIMES */
180 * Compute the elapsed time between 'stop_ptr' and 'start_ptr', and
181 * add the result to the time acculated for operation 'op_ptr'.
185 sfs_op_type * op_ptr,
186 struct ladtime * start_ptr,
187 struct ladtime * stop_ptr)
190 struct ladtime time_ptr1, time_ptr2;
192 /* get the elapsed time */
193 if (stop_ptr->usec >= 1000000) {
194 stop_ptr->sec += (stop_ptr->usec / 1000000);
195 stop_ptr->usec %= 1000000;
198 if (stop_ptr->usec < start_ptr->usec) {
199 stop_ptr->usec += 1000000;
203 if (stop_ptr->sec < start_ptr->sec) {
207 stop_ptr->usec -= start_ptr->usec;
208 stop_ptr->sec -= start_ptr->sec;
211 /* count ops that take zero time */
212 if ((stop_ptr->sec == 0) && (stop_ptr->usec == 0))
213 op_ptr->results.fast_calls++;
215 /* add the elapsed time to the total time for this operation */
217 time_ptr1 = op_ptr->results.time;
218 time_ptr2 = *stop_ptr;
220 ADDTIME(time_ptr1, time_ptr2);
222 op_ptr->results.time = time_ptr1;
223 stop_ptr = &time_ptr2;
225 /* square the elapsed time */
226 msec2 = (stop_ptr->sec * 1000.0) + (stop_ptr->usec / 1000.0);
229 /* add the squared elapsed time to the total of squared elapsed time */
230 op_ptr->results.msec2 += msec2;
233 * Log this point if logging is on. The (op_ptr - Ops)
234 * calculation is a baroque way of deriving the "NFS Operation
235 * code" we just executed--given available information.
237 * stop_ptr at this time contains the *elapsed* time, or
238 * response time of the operation.
240 log_dump(start_ptr, stop_ptr, op_ptr - Ops);
242 } /* sfs_elapsedtime */
244 long cumulative_resets;
245 long cumulative_adjusts;
248 * Use select to sleep for 'msec' milliseconds.
249 * Granularity is CLK_RESOLUTION msec.
250 * Return the amount we actually slept.
257 static long cumulative_error_msecs = 0;
259 struct timeval sleeptime;
261 struct ladtime start;
266 select_msecs = msecs + cumulative_error_msecs;
267 if (select_msecs < 0) {
268 sleeptime.tv_sec = 0;
269 sleeptime.tv_usec = 0;
271 sleeptime.tv_sec = select_msecs / 1000;
272 sleeptime.tv_usec = (select_msecs % 1000) * 1000;
276 if (select(0, NULL, NULL, NULL, &sleeptime) == -1) {
277 if (errno != EINTR) {
279 (void) fprintf(stderr, "%s: select failed ",
283 (void) generic_kill(0, SIGINT);
290 actual_msecs = ((end.sec * 1000) + (end.usec / 1000));
292 cumulative_error_msecs += (msecs - actual_msecs);
293 if(cumulative_error_msecs > 100 ||
294 cumulative_error_msecs < -100) /* Clip tops */
296 cumulative_error_msecs = 0;
301 if(cumulative_error_msecs != 0)
302 cumulative_adjusts++;