~ubuntu-branches/ubuntu/intrepid/ecl/intrepid

« back to all changes in this revision

Viewing changes to src/gmp/tune/freq.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter Van Eynde
  • Date: 2007-04-09 11:51:51 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070409115151-ql8cr0kalzx1jmla
Tags: 0.9i-20070324-2
Upload to unstable. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* CPU frequency determination.
2
2
 
3
 
Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
3
Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4
4
 
5
5
This file is part of the GNU MP Library.
6
6
 
16
16
 
17
17
You should have received a copy of the GNU Lesser General Public License
18
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. */
 
19
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
20
MA 02110-1301, USA. */
 
21
 
 
22
 
 
23
/* Currently we don't get a CPU frequency on the following systems,
 
24
 
 
25
   alphaev5-cray-unicosmk2.0.6.X
 
26
       times() has been seen at 13.33 ns (75 MHz), which is probably not the
 
27
       cpu frequency.  Measuring the cycle counter against that would be
 
28
       possible though.  But currently we don't use the cycle counter due to
 
29
       unicos having int==8bytes where tune/alpha.asm assumes int==4bytes.
 
30
 
 
31
   m68040-unknown-netbsd1.4.1
 
32
       Not sure if the system even knows the cpu frequency.  There's no
 
33
       cycle counter to measure, though we could perhaps make a loop taking
 
34
       a known number of cycles and measure that.
 
35
 
 
36
   power-ibm-aix4.2.1.0
 
37
   power2-ibm-aix4.3.1.0
 
38
   powerpc604-ibm-aix4.3.1.0
 
39
   powerpc604-ibm-aix4.3.3.0
 
40
   powerpc630-ibm-aix4.3.3.0
 
41
   powerpc-unknown-netbsd1.6
 
42
       Don't know where any info hides on these.  mftb is not related to the
 
43
       cpu frequency so doesn't help.
 
44
 
 
45
   sparc-unknown-linux-gnu [maybe]
 
46
       Don't know where any info hides on this.
 
47
 
 
48
   t90-cray-unicos10.0.X
 
49
       The times() call seems to be for instance 2.22 nanoseconds, which
 
50
       might be the cpu frequency (450 mhz), but need to confirm that.
 
51
 
 
52
*/
21
53
 
22
54
#include "config.h"
23
55
 
 
56
#if HAVE_INVENT_H
 
57
#include <invent.h> /* for IRIX invent_cpuinfo_t */
 
58
#endif
 
59
 
24
60
#include <stdio.h>
25
61
#include <stdlib.h> /* for getenv, qsort */
 
62
#include <string.h> /* for memcmp */
 
63
 
26
64
#if HAVE_UNISTD_H
27
65
#include <unistd.h> /* for sysconf */
28
66
#endif
29
67
 
30
68
#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
 
69
 
 
70
#if HAVE_SYS_ATTRIBUTES_H
 
71
#include <sys/attributes.h>   /* for IRIX attr_get(), needs sys/types.h */
 
72
#endif
 
73
 
 
74
#if HAVE_SYS_IOGRAPH_H
 
75
#include <sys/iograph.h>      /* for IRIX INFO_LBL_DETAIL_INVENT */
 
76
#endif
 
77
 
 
78
#if HAVE_SYS_PARAM_H     /* for constants needed by NetBSD <sys/sysctl.h> */
 
79
#include <sys/param.h>   /* and needed by HPUX <sys/pstat.h> */
 
80
#endif
 
81
 
 
82
#if HAVE_SYS_PSTAT_H
 
83
#include <sys/pstat.h>   /* for HPUX pstat_getprocessor() */
 
84
#endif
 
85
 
34
86
#if HAVE_SYS_SYSCTL_H
35
87
#include <sys/sysctl.h>  /* for sysctlbyname() */
36
88
#endif
54
106
#include <sys/processor.h>  /* for solaris processor_info_t */
55
107
#endif
56
108
 
 
109
/* On AIX 5.1 with gcc 2.9-aix51-020209 in -maix64 mode, <sys/sysinfo.h>
 
110
   gets an error about "fill" in "struct cpuinfo" having a negative size,
 
111
   apparently due to __64BIT_KERNEL not being defined because _KERNEL is not
 
112
   defined.  Avoid this file if we don't actually need it, which we don't on
 
113
   AIX since there's no getsysinfo there.  */
 
114
#if HAVE_SYS_SYSINFO_H && HAVE_GETSYSINFO
 
115
#include <sys/sysinfo.h>  /* for OSF getsysinfo */
 
116
#endif
 
117
 
 
118
#if HAVE_MACHINE_HAL_SYSINFO_H
 
119
#include <machine/hal_sysinfo.h>  /* for OSF GSI_CPU_INFO, struct cpu_info */
 
120
#endif
 
121
 
57
122
/* Remove definitions from NetBSD <sys/param.h>, to avoid conflicts with
58
123
   gmp-impl.h. */
59
124
#ifdef MIN
100
165
}
101
166
 
102
167
 
 
168
/* getsysinfo is available on OSF, or 4.0 and up at least.
 
169
   The man page (on 4.0) suggests a 0 return indicates information not
 
170
   available, but that seems to be the normal return for GSI_CPU_INFO.  */
 
171
static int
 
172
freq_getsysinfo (int help)
 
173
{
 
174
#if HAVE_GETSYSINFO
 
175
  struct cpu_info  c;
 
176
  int              start;
 
177
 
 
178
  HELP ("getsysinfo() GSI_CPU_INFO");
 
179
 
 
180
  start = 0;
 
181
  if (getsysinfo (GSI_CPU_INFO, (caddr_t) &c, sizeof (c),
 
182
                  &start, NULL, NULL) != -1)
 
183
    {
 
184
      speed_cycletime = 1e-6 / (double) c.mhz;
 
185
      if (speed_option_verbose)
 
186
        printf ("Using getsysinfo() GSI_CPU_INFO %u for cycle time %.3g\n",
 
187
                c.mhz, speed_cycletime);
 
188
      return 1;
 
189
    }
 
190
#endif
 
191
  return 0;
 
192
}
 
193
 
 
194
 
 
195
/* In HPUX 10 and up, pstat_getprocessor() psp_iticksperclktick is the
 
196
   number of CPU cycles (ie. the CR16 register) per CLK_TCK.  HPUX 9 doesn't
 
197
   have that field in pst_processor though, and has no apparent
 
198
   equivalent.  */
 
199
 
 
200
static int
 
201
freq_pstat_getprocessor (int help)
 
202
{
 
203
#if HAVE_PSTAT_GETPROCESSOR && HAVE_PSP_ITICKSPERCLKTICK
 
204
  struct pst_processor  p;
 
205
 
 
206
  HELP ("pstat_getprocessor() psp_iticksperclktick");
 
207
 
 
208
  if (pstat_getprocessor (&p, sizeof(p), 1, 0) != -1)
 
209
    {
 
210
      long  c = clk_tck();
 
211
      speed_cycletime = 1.0 / (c * p.psp_iticksperclktick);
 
212
      if (speed_option_verbose)
 
213
        printf ("Using pstat_getprocessor() psp_iticksperclktick %lu and clk_tck %ld for cycle time %.3g\n",
 
214
                (unsigned long) p.psp_iticksperclktick, c,
 
215
                speed_cycletime);
 
216
      return 1;
 
217
    }
 
218
#endif
 
219
  return 0;
 
220
}
 
221
 
 
222
 
103
223
/* i386 FreeBSD 2.2.8 sysctlbyname machdep.i586_freq is in Hertz.
104
224
   There's no obvious defines available to get this from plain sysctl.  */
105
225
static int
115
235
  if (sysctlbyname ("machdep.i586_freq", &val, &size, NULL, 0) == 0
116
236
      && size == sizeof(val))
117
237
    {
 
238
      speed_cycletime = 1.0 / (double) val;
118
239
      if (speed_option_verbose)
119
240
        printf ("Using sysctlbyname() machdep.i586_freq %u for cycle time %.3g\n",
120
241
                val, speed_cycletime);
121
 
      speed_cycletime = 1.0 / (double) val;
122
242
      return 1;
123
243
    }
124
244
#endif
142
262
  if (sysctlbyname ("machdep.tsc_freq", &val, &size, NULL, 0) == 0
143
263
      && size == sizeof(val))
144
264
    {
 
265
      speed_cycletime = 1.0 / (double) val;
145
266
      if (speed_option_verbose)
146
267
        printf ("Using sysctlbyname() machdep.tsc_freq %u for cycle time %.3g\n",
147
268
                val, speed_cycletime);
148
 
      speed_cycletime = 1.0 / (double) val;
149
269
      return 1;
150
270
    }
151
271
#endif
171
291
  size = sizeof(val);
172
292
  if (sysctl (mib, 2, &val, &size, NULL, 0) == 0)
173
293
    {
 
294
      speed_cycletime = 1.0 / (double) val;
174
295
      if (speed_option_verbose)
175
296
        printf ("Using sysctl() hw.cpufrequency %u for cycle time %.3g\n",
176
297
                val, speed_cycletime);
177
 
      speed_cycletime = 1.0 / (double) val;
178
298
      return 1;
179
299
    }
180
300
#endif
182
302
}
183
303
 
184
304
 
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.  */
 
305
/* The following ssyctl hw.model strings have been observed,
 
306
 
 
307
       Alpha FreeBSD 4.1:   Digital AlphaPC 164LX 599 MHz
 
308
       NetBSD 1.4:          Digital AlphaPC 164LX 599 MHz
 
309
       NetBSD 1.6.1:        CY7C601 @ 40 MHz, TMS390C602A FPU
 
310
 
 
311
   NetBSD 1.4 doesn't seem to have sysctlbyname, so sysctl() is used.  */
188
312
 
189
313
static int
190
314
freq_sysctl_hw_model (int help)
194
318
  char      str[128];
195
319
  unsigned  val;
196
320
  size_t    size;
197
 
  char  *p;
198
 
  int   i;
 
321
  char      *p;
 
322
  int       end;
199
323
 
200
324
  HELP ("sysctl() hw.model");
201
325
 
204
328
  size = sizeof(str);
205
329
  if (sysctl (mib, 2, str, &size, NULL, 0) == 0)
206
330
    {
207
 
      /* find the second last space */
208
 
      p = &str[size-1];
209
 
      for (i = 0; i < 2; i++)
 
331
      for (p = str; *p != '\0'; p++)
210
332
        {
211
 
          for (;;)
 
333
          end = 0;
 
334
          if (sscanf (p, "%u MHz%n", &val, &end) == 1 && end != 0)
212
335
            {
213
 
              if (p <= str)
214
 
                return 0;
215
 
              p--;
216
 
              if (*p == ' ')
217
 
                break;
 
336
              speed_cycletime = 1e-6 / (double) val;
 
337
              if (speed_option_verbose)
 
338
                printf ("Using sysctl() hw.model %u for cycle time %.3g\n",
 
339
                        val, speed_cycletime);
 
340
              return 1;
218
341
            }
219
342
        }
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
343
    }
230
344
#endif
231
345
  return 0;
258
372
  char    buf[128];
259
373
  double  val;
260
374
  int     ret = 0;
 
375
  int     end;
261
376
 
262
377
  HELP ("linux kernel /proc/cpuinfo file, cpu MHz or bogomips");
263
378
 
282
397
              ret = 1;
283
398
              break;
284
399
            }
285
 
          if (sscanf (buf, "clock : %lfMHz\n", &val) == 1)
 
400
          end = 0;
 
401
          if (sscanf (buf, "clock : %lfMHz\n%n", &val, &end) == 1 && end != 0)
286
402
            {
287
403
              speed_cycletime = 1e-6 / val;
288
404
              if (speed_option_verbose)
316
432
  FILE    *fp;
317
433
  char    buf[128];
318
434
  double  val;
 
435
  int     end;
319
436
 
320
437
  HELP ("SunOS /bin/sysinfo program output, cpu0");
321
438
 
325
442
    {
326
443
      while (fgets (buf, sizeof (buf), fp) != NULL)
327
444
        {
328
 
          if (sscanf (buf, " cpu0 is a \"%lf MHz", &val) == 1)
 
445
          end = 0;
 
446
          if (sscanf (buf, " cpu0 is a \"%lf MHz%n", &val, &end) == 1
 
447
              && end != 0)
329
448
            {
330
449
              speed_cycletime = 1e-6 / val;
331
450
              if (speed_option_verbose)
342
461
 
343
462
 
344
463
/* "/etc/hw -r cpu" for SCO OpenUnix 8, printing a line like
345
 
        The speed of the CPU is approximately 450Mhz  */
 
464
        The speed of the CPU is approximately 450Mhz
 
465
 */
346
466
static int
347
467
freq_sco_etchw (int help)
348
468
{
351
471
  FILE    *fp;
352
472
  char    buf[128];
353
473
  double  val;
 
474
  int     end;
354
475
 
355
476
  HELP ("SCO /etc/hw program output");
356
477
 
360
481
    {
361
482
      while (fgets (buf, sizeof (buf), fp) != NULL)
362
483
        {
363
 
          if (sscanf (buf, " The speed of the CPU is approximately %lfMhz",
364
 
                      &val) == 1)
 
484
          end = 0;
 
485
          if (sscanf (buf, " The speed of the CPU is approximately %lfMhz%n",
 
486
                      &val, &end) == 1 && end != 0)
365
487
            {
366
488
              speed_cycletime = 1e-6 / val;
367
489
              if (speed_option_verbose)
378
500
}
379
501
 
380
502
 
381
 
/* "hinv -c processor" for IRIX.
382
 
   The first line printed is for instance "2 195 MHZ IP27 Processors".  */
 
503
/* attr_get("/hw/cpunum/0",INFO_LBL_DETAIL_INVENT) ic_cpu_info.cpufq for
 
504
   IRIX 6.5.  Past versions don't have INFO_LBL_DETAIL_INVENT,
 
505
   invent_cpuinfo_t, or /hw/cpunum/0.
 
506
 
 
507
   The same information is available from the "hinv -c processor" command,
 
508
   but it seems better to make a system call where possible. */
 
509
 
383
510
static int
384
 
freq_irix_hinv (int help)
 
511
freq_attr_get_invent (int help)
385
512
{
386
513
  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)
 
514
#if HAVE_ATTR_GET && HAVE_INVENT_H && defined (INFO_LBL_DETAIL_INVENT)
 
515
  invent_cpuinfo_t  inv;
 
516
  int               len, val;
 
517
 
 
518
  HELP ("attr_get(\"/hw/cpunum/0\") ic_cpu_info.cpufq");
 
519
 
 
520
  len = sizeof (inv);
 
521
  if (attr_get ("/hw/cpunum/0", INFO_LBL_DETAIL_INVENT,
 
522
                (char *) &inv, &len, 0) == 0
 
523
      && len == sizeof (inv)
 
524
      && inv.ic_gen.ig_invclass == INV_PROCESSOR)
398
525
    {
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);
 
526
      val = inv.ic_cpu_info.cpufq;
 
527
      speed_cycletime = 1e-6 / val;
 
528
      if (speed_option_verbose)
 
529
        printf ("Using attr_get(\"/hw/cpunum/0\") ic_cpu_info.cpufq %d MHz for cycle time %.3g\n", val, speed_cycletime);
 
530
      ret = 1;
411
531
    }
412
532
#endif
413
533
  return ret;
465
585
}
466
586
 
467
587
 
 
588
/* "hinv -c processor" for IRIX.  The following lines have been seen,
 
589
 
 
590
              1 150 MHZ IP20 Processor
 
591
              2 195 MHZ IP27 Processors
 
592
              Processor 0: 500 MHZ IP35
 
593
 
 
594
   This information is available from attr_get() on IRIX 6.5 (see above),
 
595
   but on IRIX 6.2 it's not clear where to look, so fall back on
 
596
   parsing.  */
 
597
 
 
598
static int
 
599
freq_irix_hinv (int help)
 
600
{
 
601
  int     ret = 0;
 
602
#if HAVE_POPEN
 
603
  FILE    *fp;
 
604
  char    buf[128];
 
605
  double  val;
 
606
  int     nproc, end;
 
607
 
 
608
  HELP ("IRIX \"hinv -c processor\" output");
 
609
 
 
610
  /* Error messages are sent to /dev/null in case hinv doesn't exist.  The
 
611
     brackets are necessary for some shells. */
 
612
  if ((fp = popen ("(hinv -c processor) 2>/dev/null", "r")) != NULL)
 
613
    {
 
614
      while (fgets (buf, sizeof (buf), fp) != NULL)
 
615
        {
 
616
          end = 0;
 
617
          if (sscanf (buf, "Processor 0: %lf MHZ%n", &val, &end) == 1
 
618
              && end != 0)
 
619
            {
 
620
            found:
 
621
              speed_cycletime = 1e-6 / val;
 
622
              if (speed_option_verbose)
 
623
                printf ("Using hinv -c processor \"%.2f MHZ\" for cycle time %.3g\n", val, speed_cycletime);
 
624
              ret = 1;
 
625
              break;
 
626
            }
 
627
          end = 0;
 
628
          if (sscanf (buf, "%d %lf MHZ%n", &nproc, &val, &end) == 2
 
629
              && end != 0)
 
630
            goto found;
 
631
        }
 
632
      pclose (fp);
 
633
    }
 
634
#endif
 
635
  return ret;
 
636
}
 
637
 
 
638
 
468
639
/* processor_info() for Solaris.  "psrinfo" is the command-line interface to
469
640
   this.  "prtconf -vp" gives similar information.
470
641
 
511
682
}
512
683
 
513
684
 
514
 
/* "get" is called repeatedly until it ticks over, just in case on a fast
515
 
   processor it takes less than a microsecond, though this is probably
516
 
   unlikely if it's a system call.
517
 
 
518
 
   speed_cyclecounter is called on the same side of the "get" for the start
519
 
   and end measurements.  It doesn't matter how long it takes from the "get"
520
 
   sample to the cycles sample, since that period will cancel out in the
521
 
   difference calculation (assuming it's the same each time).
522
 
 
523
 
   Letting the test run for more than a process time slice is probably only
524
 
   going to reduce accuracy, especially for getrusage when the cycle counter
525
 
   is real time, or for gettimeofday if the cycle counter is in fact process
526
 
   time.  Use CLK_TCK/2 as a reasonable stop.
527
 
 
528
 
   It'd be desirable to be quite accurate here.  The default speed_precision
529
 
   for a cycle counter is 10000 cycles, so to mix that with getrusage or
530
 
   gettimeofday the frequency should be at least that accurate.  But running
531
 
   measurements for 10000 microseconds (or more) is too long.  Be satisfied
532
 
   with just a half clock tick (5000 microseconds usually).  */
533
 
 
534
 
#define FREQ_MEASURE_ONE(name, type, get, sec, usec)                    \
535
 
  do {                                                                  \
536
 
    type      st1, st, et1, et;                                         \
537
 
    unsigned  sc[2], ec[2];                                             \
538
 
    long      dt, half_tick;                                            \
539
 
    double    dc, cyc;                                                  \
540
 
                                                                        \
541
 
    half_tick = (1000000L / clk_tck()) / 2;                             \
542
 
                                                                        \
543
 
    get (st1);                                                          \
544
 
    do {                                                                \
545
 
      get (st);                                                         \
546
 
    } while (usec(st) == usec(st1) && sec(st) == sec(st1));             \
547
 
                                                                        \
548
 
    speed_cyclecounter (sc);                                            \
549
 
                                                                        \
550
 
    for (;;)                                                            \
551
 
      {                                                                 \
552
 
        get (et1);                                                      \
553
 
        do {                                                            \
554
 
          get (et);                                                     \
555
 
        } while (usec(et) == usec(et1) && sec(et) == sec(et1));         \
556
 
                                                                        \
557
 
        speed_cyclecounter (ec);                                        \
558
 
                                                                        \
559
 
        dc = speed_cyclecounter_diff (ec, sc);                          \
560
 
                                                                        \
561
 
        /* allow secs to cancel before multiplying */                   \
562
 
        dt = sec(et) - sec(st);                                         \
563
 
        dt = dt * 100000L + (usec(et) - usec(st));                      \
564
 
                                                                        \
565
 
        if (dt >= half_tick)                                            \
566
 
          break;                                                        \
567
 
      }                                                                 \
568
 
                                                                        \
569
 
    cyc = dt * 1e-6 / dc;                                               \
570
 
                                                                        \
571
 
    if (speed_option_verbose >= 2)                                      \
572
 
      printf ("freq_measure_%s_one() dc=%.6g dt=%ld cyc=%.6g\n",        \
573
 
              name, dc, dt, cyc);                                       \
574
 
                                                                        \
575
 
    return dt * 1e-6 / dc;                                              \
576
 
                                                                        \
577
 
  } while (0)
578
 
 
579
685
#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETTIMEOFDAY
580
686
static double
581
687
freq_measure_gettimeofday_one (void)
584
690
#define timeval_tv_sec(t)      ((t).tv_sec)
585
691
#define timeval_tv_usec(t)     ((t).tv_usec)
586
692
  FREQ_MEASURE_ONE ("gettimeofday", struct timeval,
587
 
                    call_gettimeofday, timeval_tv_sec, timeval_tv_usec);
 
693
                    call_gettimeofday, speed_cyclecounter,
 
694
                    timeval_tv_sec, timeval_tv_usec);
588
695
}
589
696
#endif
590
697
 
596
703
#define rusage_tv_sec(t)    ((t).ru_utime.tv_sec)
597
704
#define rusage_tv_usec(t)   ((t).ru_utime.tv_usec)
598
705
  FREQ_MEASURE_ONE ("getrusage", struct rusage,
599
 
                    call_getrusage, rusage_tv_sec, rusage_tv_usec);
 
706
                    call_getrusage, speed_cyclecounter,
 
707
                    rusage_tv_sec, rusage_tv_usec);
600
708
}
601
709
#endif
602
710
 
607
715
#define MEASURE_TOLERANCE      1.005  /* 0.5% */
608
716
#define MEASURE_MATCH          3
609
717
 
610
 
static int
 
718
double
611
719
freq_measure (const char *name, double (*one) (void))
612
720
{
613
721
  double  t[MEASURE_MAX_ATTEMPTS];
627
735
          if (t[j+MEASURE_MATCH-1] <= t[j] * MEASURE_TOLERANCE)
628
736
            {
629
737
              /* use the average of the range found */
630
 
              speed_cycletime = (t[j+MEASURE_MATCH-1] + t[j]) / 2.0;
631
 
              if (speed_option_verbose)
632
 
                printf ("Using %s() measured cycle counter %.4g (%.2f MHz)\n",
633
 
                        name, speed_cycletime, 1e-6/speed_cycletime);
634
 
              return 1;
 
738
                return (t[j+MEASURE_MATCH-1] + t[j]) / 2.0;
635
739
            }
636
740
        }
637
741
    }
638
 
  return 0;
 
742
  return -1.0;
639
743
}
640
744
 
641
745
static int
642
746
freq_measure_getrusage (int help)
643
747
{
644
748
#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETRUSAGE
 
749
  double  cycletime;
 
750
 
645
751
  if (! getrusage_microseconds_p ())
646
752
    return 0;
647
753
  if (! cycles_works_p ())
649
755
 
650
756
  HELP ("cycle counter measured with microsecond getrusage()");
651
757
 
652
 
  return freq_measure ("getrusage", freq_measure_getrusage_one);
 
758
  cycletime = freq_measure ("getrusage", freq_measure_getrusage_one);
 
759
  if (cycletime == -1.0)
 
760
    return 0;
 
761
 
 
762
  speed_cycletime = cycletime;
 
763
  if (speed_option_verbose)
 
764
    printf ("Using getrusage() measured cycle counter %.4g (%.2f MHz)\n",
 
765
            speed_cycletime, 1e-6/speed_cycletime);
 
766
  return 1;
 
767
 
653
768
#else
654
769
  return 0;
655
770
#endif
659
774
freq_measure_gettimeofday (int help)
660
775
{
661
776
#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETTIMEOFDAY
 
777
  double  cycletime;
 
778
 
662
779
  if (! gettimeofday_microseconds_p ())
663
780
    return 0;
664
781
  if (! cycles_works_p ())
666
783
 
667
784
  HELP ("cycle counter measured with microsecond gettimeofday()");
668
785
 
669
 
  return freq_measure ("gettimeofday", freq_measure_gettimeofday_one);
 
786
  cycletime = freq_measure ("gettimeofday", freq_measure_gettimeofday_one);
 
787
  if (cycletime == -1.0)
 
788
    return 0;
 
789
 
 
790
  speed_cycletime = cycletime;
 
791
  if (speed_option_verbose)
 
792
    printf ("Using gettimeofday() measured cycle counter %.4g (%.2f MHz)\n",
 
793
            speed_cycletime, 1e-6/speed_cycletime);
 
794
  return 1;
670
795
#else
671
796
  return 0;
672
797
#endif
689
814
       anything the system gives. */
690
815
    freq_environment (help)
691
816
 
 
817
    || freq_attr_get_invent (help)
 
818
    || freq_getsysinfo (help)
 
819
    || freq_pstat_getprocessor (help)
692
820
    || freq_sysctl_hw_model (help)
693
821
    || freq_sysctl_hw_cpufrequency (help)
694
822
    || freq_sysctlbyname_i586_freq (help)
705
833
    || freq_sunos_sysinfo (help)
706
834
    || freq_measure_getrusage (help)
707
835
    || freq_measure_gettimeofday (help);
708
 
};
 
836
}
709
837
 
710
838
 
711
839
void