Annotation of OpenXM_contrib/gmp/tune/freq.c, Revision 1.1.1.1
1.1 ohara 1: /* CPU frequency determination.
2:
3: Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4:
5: This file is part of the GNU MP Library.
6:
7: The GNU MP Library is free software; you can redistribute it and/or modify
8: it under the terms of the GNU Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 of the License, or (at your
10: option) any later version.
11:
12: The GNU MP Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15: License for more details.
16:
17: You should have received a copy of the GNU Lesser General Public License
18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #include "config.h"
23:
24: #include <stdio.h>
25: #include <stdlib.h> /* for getenv, qsort */
26: #if HAVE_UNISTD_H
27: #include <unistd.h> /* for sysconf */
28: #endif
29:
30: #include <sys/types.h>
31: #if HAVE_SYS_PARAM_H
32: #include <sys/param.h> /* for constants needed by NetBSD <sys/sysctl.h> */
33: #endif
34: #if HAVE_SYS_SYSCTL_H
35: #include <sys/sysctl.h> /* for sysctlbyname() */
36: #endif
37:
38: #if TIME_WITH_SYS_TIME
39: # include <sys/time.h> /* for struct timeval */
40: # include <time.h>
41: #else
42: # if HAVE_SYS_TIME_H
43: # include <sys/time.h>
44: # else
45: # include <time.h>
46: # endif
47: #endif
48:
49: #if HAVE_SYS_RESOURCE_H
50: #include <sys/resource.h> /* for struct rusage */
51: #endif
52:
53: #if HAVE_SYS_PROCESSOR_H
54: #include <sys/processor.h> /* for solaris processor_info_t */
55: #endif
56:
57: /* Remove definitions from NetBSD <sys/param.h>, to avoid conflicts with
58: gmp-impl.h. */
59: #ifdef MIN
60: #undef MIN
61: #endif
62: #ifdef MAX
63: #undef MAX
64: #endif
65:
66: #include "gmp.h"
67: #include "gmp-impl.h"
68:
69: #include "speed.h"
70:
71:
72: #define HELP(str) \
73: if (help) \
74: { \
75: printf (" - %s\n", str); \
76: return 0; \
77: }
78:
79:
80: /* GMP_CPU_FREQUENCY environment variable. Should be in Hertz and can be
81: floating point, for example "450e6". */
82: static int
83: freq_environment (int help)
84: {
85: char *e;
86:
87: HELP ("environment variable GMP_CPU_FREQUENCY (in Hertz)");
88:
89: e = getenv ("GMP_CPU_FREQUENCY");
90: if (e == NULL)
91: return 0;
92:
93: speed_cycletime = 1.0 / atof (e);
94:
95: if (speed_option_verbose)
96: printf ("Using GMP_CPU_FREQUENCY %.2f for cycle time %.3g\n",
97: atof (e), speed_cycletime);
98:
99: return 1;
100: }
101:
102:
103: /* i386 FreeBSD 2.2.8 sysctlbyname machdep.i586_freq is in Hertz.
104: There's no obvious defines available to get this from plain sysctl. */
105: static int
106: freq_sysctlbyname_i586_freq (int help)
107: {
108: #if HAVE_SYSCTLBYNAME
109: unsigned val;
110: size_t size;
111:
112: HELP ("sysctlbyname() machdep.i586_freq");
113:
114: size = sizeof(val);
115: if (sysctlbyname ("machdep.i586_freq", &val, &size, NULL, 0) == 0
116: && size == sizeof(val))
117: {
118: if (speed_option_verbose)
119: printf ("Using sysctlbyname() machdep.i586_freq %u for cycle time %.3g\n",
120: val, speed_cycletime);
121: speed_cycletime = 1.0 / (double) val;
122: return 1;
123: }
124: #endif
125: return 0;
126: }
127:
128:
129: /* i368 FreeBSD 3.3 sysctlbyname machdep.tsc_freq is in Hertz.
130: There's no obvious defines to get this from plain sysctl. */
131:
132: static int
133: freq_sysctlbyname_tsc_freq (int help)
134: {
135: #if HAVE_SYSCTLBYNAME
136: unsigned val;
137: size_t size;
138:
139: HELP ("sysctlbyname() machdep.tsc_freq");
140:
141: size = sizeof(val);
142: if (sysctlbyname ("machdep.tsc_freq", &val, &size, NULL, 0) == 0
143: && size == sizeof(val))
144: {
145: if (speed_option_verbose)
146: printf ("Using sysctlbyname() machdep.tsc_freq %u for cycle time %.3g\n",
147: val, speed_cycletime);
148: speed_cycletime = 1.0 / (double) val;
149: return 1;
150: }
151: #endif
152: return 0;
153: }
154:
155:
156: /* Apple powerpc Darwin 1.3 sysctl hw.cpufrequency is in hertz. For some
157: reason only seems to be available from sysctl(), not sysctlbyname(). */
158:
159: static int
160: freq_sysctl_hw_cpufrequency (int help)
161: {
162: #if HAVE_SYSCTL && defined (CTL_HW) && defined (HW_CPU_FREQ)
163: int mib[2];
164: unsigned val;
165: size_t size;
166:
167: HELP ("sysctl() hw.cpufrequency");
168:
169: mib[0] = CTL_HW;
170: mib[1] = HW_CPU_FREQ;
171: size = sizeof(val);
172: if (sysctl (mib, 2, &val, &size, NULL, 0) == 0)
173: {
174: if (speed_option_verbose)
175: printf ("Using sysctl() hw.cpufrequency %u for cycle time %.3g\n",
176: val, speed_cycletime);
177: speed_cycletime = 1.0 / (double) val;
178: return 1;
179: }
180: #endif
181: return 0;
182: }
183:
184:
185: /* Alpha FreeBSD 4.1 and NetBSD 1.4 sysctl- hw.model string gives "Digital
186: AlphaPC 164LX 599 MHz". NetBSD 1.4 doesn't seem to have sysctlbyname, so
187: sysctl() is used. */
188:
189: static int
190: freq_sysctl_hw_model (int help)
191: {
192: #if HAVE_SYSCTL && defined (CTL_HW) && defined (HW_MODEL)
193: int mib[2];
194: char str[128];
195: unsigned val;
196: size_t size;
197: char *p;
198: int i;
199:
200: HELP ("sysctl() hw.model");
201:
202: mib[0] = CTL_HW;
203: mib[1] = HW_MODEL;
204: size = sizeof(str);
205: if (sysctl (mib, 2, str, &size, NULL, 0) == 0)
206: {
207: /* find the second last space */
208: p = &str[size-1];
209: for (i = 0; i < 2; i++)
210: {
211: for (;;)
212: {
213: if (p <= str)
214: return 0;
215: p--;
216: if (*p == ' ')
217: break;
218: }
219: }
220:
221: if (sscanf (p, "%u MHz", &val) != 1)
222: return 0;
223:
224: if (speed_option_verbose)
225: printf ("Using sysctl() hw.model %u for cycle time %.3g\n",
226: val, speed_cycletime);
227: speed_cycletime = 1e-6 / (double) val;
228: return 1;
229: }
230: #endif
231: return 0;
232: }
233:
234:
235: /* /proc/cpuinfo for linux kernel.
236:
237: Linux doesn't seem to have any system call to get the CPU frequency, at
238: least not in 2.0.x or 2.2.x, so it's necessary to read /proc/cpuinfo.
239:
240: i386 2.0.36 - "bogomips" is the CPU frequency.
241:
242: i386 2.2.13 - has both "cpu MHz" and "bogomips", and it's "cpu MHz" which
243: is the frequency.
244:
245: alpha 2.2.5 - "cycle frequency [Hz]" seems to be right, "BogoMIPS" is
246: very slightly different.
247:
248: alpha 2.2.18pre21 - "cycle frequency [Hz]" is 0 on at least one system,
249: "BogoMIPS" seems near enough.
250:
251: powerpc 2.2.19 - "clock" is the frequency, bogomips is something weird
252: */
253:
254: static int
255: freq_proc_cpuinfo (int help)
256: {
257: FILE *fp;
258: char buf[128];
259: double val;
260: int ret = 0;
261:
262: HELP ("linux kernel /proc/cpuinfo file, cpu MHz or bogomips");
263:
264: if ((fp = fopen ("/proc/cpuinfo", "r")) != NULL)
265: {
266: while (fgets (buf, sizeof (buf), fp) != NULL)
267: {
268: if (sscanf (buf, "cycle frequency [Hz] : %lf", &val) == 1
269: && val != 0.0)
270: {
271: speed_cycletime = 1.0 / val;
272: if (speed_option_verbose)
273: printf ("Using /proc/cpuinfo \"cycle frequency\" %.2f for cycle time %.3g\n", val, speed_cycletime);
274: ret = 1;
275: break;
276: }
277: if (sscanf (buf, "cpu MHz : %lf\n", &val) == 1)
278: {
279: speed_cycletime = 1e-6 / val;
280: if (speed_option_verbose)
281: printf ("Using /proc/cpuinfo \"cpu MHz\" %.2f for cycle time %.3g\n", val, speed_cycletime);
282: ret = 1;
283: break;
284: }
285: if (sscanf (buf, "clock : %lfMHz\n", &val) == 1)
286: {
287: speed_cycletime = 1e-6 / val;
288: if (speed_option_verbose)
289: printf ("Using /proc/cpuinfo \"clock\" %.2f for cycle time %.3g\n", val, speed_cycletime);
290: ret = 1;
291: break;
292: }
293: if (sscanf (buf, "bogomips : %lf\n", &val) == 1
294: || sscanf (buf, "BogoMIPS : %lf\n", &val) == 1)
295: {
296: speed_cycletime = 1e-6 / val;
297: if (speed_option_verbose)
298: printf ("Using /proc/cpuinfo \"bogomips\" %.2f for cycle time %.3g\n", val, speed_cycletime);
299: ret = 1;
300: break;
301: }
302: }
303: fclose (fp);
304: }
305: return ret;
306: }
307:
308:
309: /* /bin/sysinfo for SunOS 4.
310: Prints a line like: cpu0 is a "75 MHz TI,TMS390Z55" CPU */
311: static int
312: freq_sunos_sysinfo (int help)
313: {
314: int ret = 0;
315: #if HAVE_POPEN
316: FILE *fp;
317: char buf[128];
318: double val;
319:
320: HELP ("SunOS /bin/sysinfo program output, cpu0");
321:
322: /* Error messages are sent to /dev/null in case /bin/sysinfo doesn't
323: exist. The brackets are necessary for some shells. */
324: if ((fp = popen ("(/bin/sysinfo) 2>/dev/null", "r")) != NULL)
325: {
326: while (fgets (buf, sizeof (buf), fp) != NULL)
327: {
328: if (sscanf (buf, " cpu0 is a \"%lf MHz", &val) == 1)
329: {
330: speed_cycletime = 1e-6 / val;
331: if (speed_option_verbose)
332: printf ("Using /bin/sysinfo \"cpu0 MHz\" %.2f for cycle time %.3g\n", val, speed_cycletime);
333: ret = 1;
334: break;
335: }
336: }
337: pclose (fp);
338: }
339: #endif
340: return ret;
341: }
342:
343:
344: /* "/etc/hw -r cpu" for SCO OpenUnix 8, printing a line like
345: The speed of the CPU is approximately 450Mhz */
346: static int
347: freq_sco_etchw (int help)
348: {
349: int ret = 0;
350: #if HAVE_POPEN
351: FILE *fp;
352: char buf[128];
353: double val;
354:
355: HELP ("SCO /etc/hw program output");
356:
357: /* Error messages are sent to /dev/null in case /etc/hw doesn't exist.
358: The brackets are necessary for some shells. */
359: if ((fp = popen ("(/etc/hw -r cpu) 2>/dev/null", "r")) != NULL)
360: {
361: while (fgets (buf, sizeof (buf), fp) != NULL)
362: {
363: if (sscanf (buf, " The speed of the CPU is approximately %lfMhz",
364: &val) == 1)
365: {
366: speed_cycletime = 1e-6 / val;
367: if (speed_option_verbose)
368: printf ("Using /etc/hw %.2f MHz, for cycle time %.3g\n",
369: val, speed_cycletime);
370: ret = 1;
371: break;
372: }
373: }
374: pclose (fp);
375: }
376: #endif
377: return ret;
378: }
379:
380:
381: /* "hinv -c processor" for IRIX.
382: The first line printed is for instance "2 195 MHZ IP27 Processors". */
383: static int
384: freq_irix_hinv (int help)
385: {
386: int ret = 0;
387: #if HAVE_POPEN
388: FILE *fp;
389: char buf[128];
390: double val;
391: int nproc;
392:
393: HELP ("IRIX \"hinv -c processor\" output");
394:
395: /* Error messages are sent to /dev/null in case hinv doesn't exist. The
396: brackets are necessary for some shells. */
397: if ((fp = popen ("(hinv -c processor) 2>/dev/null", "r")) != NULL)
398: {
399: while (fgets (buf, sizeof (buf), fp) != NULL)
400: {
401: if (sscanf (buf, "%d %lf MHZ", &nproc, &val) == 2)
402: {
403: speed_cycletime = 1e-6 / val;
404: if (speed_option_verbose)
405: printf ("Using hinv -c processor \"%.2f MHZ\" for cycle time %.3g\n", val, speed_cycletime);
406: ret = 1;
407: break;
408: }
409: }
410: pclose (fp);
411: }
412: #endif
413: return ret;
414: }
415:
416:
417: /* FreeBSD on i386 gives a line like the following at bootup, and which can
418: be read back from /var/run/dmesg.boot.
419:
420: CPU: AMD Athlon(tm) Processor (755.29-MHz 686-class CPU)
421: CPU: Pentium 4 (1707.56-MHz 686-class CPU)
422:
423: This is useful on FreeBSD 4.x, where there's no sysctl machdep.tsc_freq
424: or machdep.i586_freq.
425:
426: It's better to use /var/run/dmesg.boot than to run /sbin/dmesg, since the
427: latter prints the current system message buffer, which is a limited size
428: and can wrap around if the system is up for a long time. */
429:
430: static int
431: freq_bsd_dmesg (int help)
432: {
433: FILE *fp;
434: char buf[256], *p;
435: double val;
436: int ret = 0;
437:
438: HELP ("BSD /var/run/dmesg.boot file");
439:
440: if ((fp = fopen ("/var/run/dmesg.boot", "r")) != NULL)
441: {
442: while (fgets (buf, sizeof (buf), fp) != NULL)
443: {
444: if (memcmp (buf, "CPU:", 4) == 0)
445: {
446: for (p = buf; *p != '\0'; p++)
447: {
448: if (sscanf (p, "(%lf-MHz", &val) == 1)
449: {
450: speed_cycletime = 1e-6 / val;
451: if (speed_option_verbose)
452: printf ("Using /var/run/dmesg.boot CPU: %.2f MHz for cycle time %.3g\n", val, speed_cycletime);
453: ret = 1;
454: break;
455: }
456: }
457: }
458: }
459: fclose (fp);
460: }
461: return ret;
462: }
463:
464:
465: /* processor_info() for Solaris. "psrinfo" is the command-line interface to
466: this. "prtconf -vp" gives similar information.
467:
468: Apple Darwin has a processor_info, but in an incompatible style. It
469: doesn't have <sys/processor.h>, so test for that. */
470:
471: static int
472: freq_processor_info (int help)
473: {
474: #if HAVE_PROCESSOR_INFO && HAVE_SYS_PROCESSOR_H
475: processor_info_t p;
476: int i, n, mhz = 0;
477:
478: HELP ("processor_info() pi_clock");
479:
480: n = sysconf (_SC_NPROCESSORS_CONF);
481: for (i = 0; i < n; i++)
482: {
483: if (processor_info (i, &p) != 0)
484: continue;
485: if (p.pi_state != P_ONLINE)
486: continue;
487:
488: if (mhz != 0 && p.pi_clock != mhz)
489: {
490: fprintf (stderr,
491: "freq_processor_info(): There's more than one CPU and they have different clock speeds\n");
492: return 0;
493: }
494:
495: mhz = p.pi_clock;
496: }
497:
498: speed_cycletime = 1.0e-6 / (double) mhz;
499:
500: if (speed_option_verbose)
501: printf ("Using processor_info() %d mhz for cycle time %.3g\n",
502: mhz, speed_cycletime);
503: return 1;
504:
505: #else
506: return 0;
507: #endif
508: }
509:
510:
511: /* "get" is called repeatedly until it ticks over, just in case on a fast
512: processor it takes less than a microsecond, though this is probably
513: unlikely if it's a system call.
514:
515: speed_cyclecounter is called on the same side of the "get" for the start
516: and end measurements. It doesn't matter how long it takes from the "get"
517: sample to the cycles sample, since that period will cancel out in the
518: difference calculation (assuming it's the same each time).
519:
520: Letting the test run for more than a process time slice is probably only
521: going to reduce accuracy, especially for getrusage when the cycle counter
522: is real time, or for gettimeofday if the cycle counter is in fact process
523: time. Use CLK_TCK/2 as a reasonable stop.
524:
525: It'd be desirable to be quite accurate here. The default speed_precision
526: for a cycle counter is 10000 cycles, so to mix that with getrusage or
527: gettimeofday the frequency should be at least that accurate. But running
528: measurements for 10000 microseconds (or more) is too long. Be satisfied
529: with just a half clock tick (5000 microseconds usually). */
530:
531: #define FREQ_MEASURE_ONE(name, type, get, sec, usec) \
532: do { \
533: type st1, st, et1, et; \
534: unsigned sc[2], ec[2]; \
535: long dt, half_tick; \
536: double dc, cyc; \
537: \
538: half_tick = (1000000L / clk_tck()) / 2; \
539: \
540: get (st1); \
541: do { \
542: get (st); \
543: } while (usec(st) == usec(st1) && sec(st) == sec(st1)); \
544: \
545: speed_cyclecounter (sc); \
546: \
547: for (;;) \
548: { \
549: get (et1); \
550: do { \
551: get (et); \
552: } while (usec(et) == usec(et1) && sec(et) == sec(et1)); \
553: \
554: speed_cyclecounter (ec); \
555: \
556: dc = speed_cyclecounter_diff (ec, sc); \
557: \
558: /* allow secs to cancel before multiplying */ \
559: dt = sec(et) - sec(st); \
560: dt = dt * 100000L + (usec(et) - usec(st)); \
561: \
562: if (dt >= half_tick) \
563: break; \
564: } \
565: \
566: cyc = dt * 1e-6 / dc; \
567: \
568: if (speed_option_verbose >= 2) \
569: printf ("freq_measure_%s_one() dc=%.6g dt=%ld cyc=%.6g\n", \
570: name, dc, dt, cyc); \
571: \
572: return dt * 1e-6 / dc; \
573: \
574: } while (0)
575:
576: #if HAVE_SPEED_CYCLECOUNTER && HAVE_GETTIMEOFDAY
577: static double
578: freq_measure_gettimeofday_one (void)
579: {
580: #define call_gettimeofday(t) gettimeofday (&(t), NULL)
581: #define timeval_tv_sec(t) ((t).tv_sec)
582: #define timeval_tv_usec(t) ((t).tv_usec)
583: FREQ_MEASURE_ONE ("gettimeofday", struct timeval,
584: call_gettimeofday, timeval_tv_sec, timeval_tv_usec);
585: }
586: #endif
587:
588: #if HAVE_SPEED_CYCLECOUNTER && HAVE_GETRUSAGE
589: static double
590: freq_measure_getrusage_one (void)
591: {
592: #define call_getrusage(t) getrusage (0, &(t))
593: #define rusage_tv_sec(t) ((t).ru_utime.tv_sec)
594: #define rusage_tv_usec(t) ((t).ru_utime.tv_usec)
595: FREQ_MEASURE_ONE ("getrusage", struct rusage,
596: call_getrusage, rusage_tv_sec, rusage_tv_usec);
597: }
598: #endif
599:
600:
601: /* MEASURE_MATCH is how many readings within MEASURE_TOLERANCE of each other
602: are required. This must be at least 2. */
603: #define MEASURE_MAX_ATTEMPTS 20
604: #define MEASURE_TOLERANCE 1.005 /* 0.5% */
605: #define MEASURE_MATCH 3
606:
607: static int
608: freq_measure (const char *name, double (*one) (void))
609: {
610: double t[MEASURE_MAX_ATTEMPTS];
611: int i, j;
612:
613: for (i = 0; i < numberof (t); i++)
614: {
615: t[i] = (*one) ();
616:
617: qsort (t, i+1, sizeof(t[0]), (qsort_function_t) double_cmp_ptr);
618: if (speed_option_verbose >= 3)
619: for (j = 0; j <= i; j++)
620: printf (" t[%d] is %.6g\n", j, t[j]);
621:
622: for (j = 0; j+MEASURE_MATCH-1 <= i; j++)
623: {
624: if (t[j+MEASURE_MATCH-1] <= t[j] * MEASURE_TOLERANCE)
625: {
626: /* use the average of the range found */
627: speed_cycletime = (t[j+MEASURE_MATCH-1] + t[j]) / 2.0;
628: if (speed_option_verbose)
629: printf ("Using %s() measured cycle counter %.4g (%.2f MHz)\n",
630: name, speed_cycletime, 1e-6/speed_cycletime);
631: return 1;
632: }
633: }
634: }
635: return 0;
636: }
637:
638: static int
639: freq_measure_getrusage (int help)
640: {
641: #if HAVE_SPEED_CYCLECOUNTER && HAVE_GETRUSAGE
642: if (! getrusage_microseconds_p ())
643: return 0;
644: if (! cycles_works_p ())
645: return 0;
646:
647: HELP ("cycle counter measured with microsecond getrusage()");
648:
649: return freq_measure ("getrusage", freq_measure_getrusage_one);
650: #else
651: return 0;
652: #endif
653: }
654:
655: static int
656: freq_measure_gettimeofday (int help)
657: {
658: #if HAVE_SPEED_CYCLECOUNTER && HAVE_GETTIMEOFDAY
659: if (! gettimeofday_microseconds_p ())
660: return 0;
661: if (! cycles_works_p ())
662: return 0;
663:
664: HELP ("cycle counter measured with microsecond gettimeofday()");
665:
666: return freq_measure ("gettimeofday", freq_measure_gettimeofday_one);
667: #else
668: return 0;
669: #endif
670: }
671:
672:
673: /* Each function returns 1 if it succeeds in setting speed_cycletime, or 0
674: if not.
675:
676: In general system call tests are first since they're fast, then file
677: tests, then tests running programs. Necessary exceptions to this rule
678: are noted. The measuring is last since it's time consuming, and rather
679: wasteful of cpu. */
680:
681: static int
682: freq_all (int help)
683: {
684: return
685: /* This should be first, so an environment variable can override
686: anything the system gives. */
687: freq_environment (help)
688:
689: || freq_sysctl_hw_model (help)
690: || freq_sysctl_hw_cpufrequency (help)
691: || freq_sysctlbyname_i586_freq (help)
692: || freq_sysctlbyname_tsc_freq (help)
693:
694: /* SCO openunix 8 puts a dummy pi_clock==16 in processor_info, so be
695: sure to check /etc/hw before that function. */
696: || freq_sco_etchw (help)
697:
698: || freq_processor_info (help)
699: || freq_proc_cpuinfo (help)
700: || freq_bsd_dmesg (help)
701: || freq_irix_hinv (help)
702: || freq_sunos_sysinfo (help)
703: || freq_measure_getrusage (help)
704: || freq_measure_gettimeofday (help);
705: };
706:
707:
708: void
709: speed_cycletime_init (void)
710: {
711: static int attempted = 0;
712:
713: if (attempted)
714: return;
715: attempted = 1;
716:
717: if (freq_all (0))
718: return;
719:
720: if (speed_option_verbose)
721: printf ("CPU frequency couldn't be determined\n");
722: }
723:
724:
725: void
726: speed_cycletime_fail (const char *str)
727: {
728: fprintf (stderr, "Measuring with: %s\n", speed_time_string);
729: fprintf (stderr, "%s,\n", str);
730: fprintf (stderr, "but none of the following are available,\n");
731: freq_all (1);
732: abort ();
733: }
734:
735: /* speed_time_init leaves speed_cycletime set to either 0.0 or 1.0 when the
736: CPU frequency is unknown. 0.0 is when the time base is in seconds, so
737: that's no good if cycles are wanted. 1.0 is when the time base is in
738: cycles, which conversely is no good if seconds are wanted. */
739: void
740: speed_cycletime_need_cycles (void)
741: {
742: speed_time_init ();
743: if (speed_cycletime == 0.0)
744: speed_cycletime_fail
745: ("Need to know CPU frequency to give times in cycles");
746: }
747: void
748: speed_cycletime_need_seconds (void)
749: {
750: speed_time_init ();
751: if (speed_cycletime == 1.0)
752: speed_cycletime_fail
753: ("Need to know CPU frequency to convert cycles to seconds");
754: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>