summaryrefslogtreecommitdiff
path: root/nacl/cpucycles
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-07-02 09:53:34 -0400
committerirungentoo <irungentoo@gmail.com>2013-07-02 09:53:34 -0400
commite2967396ac73cb7410787886cdaf072a184ffc49 (patch)
tree527a74d25a4a0705fc641994fd35bfab22662034 /nacl/cpucycles
parent8928c817df345f29aa0b194743595aa11bd6a8ba (diff)
Added NaCl crypto library.
Diffstat (limited to 'nacl/cpucycles')
-rw-r--r--nacl/cpucycles/alpha.c80
-rw-r--r--nacl/cpucycles/alpha.h27
-rw-r--r--nacl/cpucycles/amd64cpuinfo.c16
-rw-r--r--nacl/cpucycles/amd64cpuinfo.h27
-rw-r--r--nacl/cpucycles/amd64cpuspeed.c25
-rw-r--r--nacl/cpucycles/amd64cpuspeed.h27
-rw-r--r--nacl/cpucycles/amd64tscfreq.c18
-rw-r--r--nacl/cpucycles/amd64tscfreq.h27
-rw-r--r--nacl/cpucycles/celllinux.c83
-rw-r--r--nacl/cpucycles/celllinux.h27
-rw-r--r--nacl/cpucycles/cortex.c73
-rw-r--r--nacl/cpucycles/cortex.h27
-rw-r--r--nacl/cpucycles/dev4ns.c62
-rw-r--r--nacl/cpucycles/dev4ns.h27
-rwxr-xr-xnacl/cpucycles/do105
-rw-r--r--nacl/cpucycles/gettimeofday.c32
-rw-r--r--nacl/cpucycles/gettimeofday.h27
-rw-r--r--nacl/cpucycles/hppapstat.c26
-rw-r--r--nacl/cpucycles/hppapstat.h27
-rw-r--r--nacl/cpucycles/ia64cpuinfo.c15
-rw-r--r--nacl/cpucycles/ia64cpuinfo.h27
-rw-r--r--nacl/cpucycles/mips.c65
-rw-r--r--nacl/cpucycles/mips.h27
-rw-r--r--nacl/cpucycles/monotonic.c34
-rw-r--r--nacl/cpucycles/monotonic.h27
-rw-r--r--nacl/cpucycles/monotoniccpuinfo.c33
-rw-r--r--nacl/cpucycles/monotoniccpuinfo.h27
-rw-r--r--nacl/cpucycles/osfreq.c65
-rw-r--r--nacl/cpucycles/powerpccpuinfo.c95
-rw-r--r--nacl/cpucycles/powerpccpuinfo.h27
-rw-r--r--nacl/cpucycles/powerpcmacos.c42
-rw-r--r--nacl/cpucycles/powerpcmacos.h27
-rw-r--r--nacl/cpucycles/sgi.c38
-rw-r--r--nacl/cpucycles/sgi.h27
-rw-r--r--nacl/cpucycles/sparc32cpuinfo.c16
-rw-r--r--nacl/cpucycles/sparc32cpuinfo.h27
-rw-r--r--nacl/cpucycles/sparccpuinfo.c15
-rw-r--r--nacl/cpucycles/sparccpuinfo.h27
-rw-r--r--nacl/cpucycles/test.c77
-rw-r--r--nacl/cpucycles/x86cpuinfo.c15
-rw-r--r--nacl/cpucycles/x86cpuinfo.h27
-rw-r--r--nacl/cpucycles/x86cpuspeed.c24
-rw-r--r--nacl/cpucycles/x86cpuspeed.h27
-rw-r--r--nacl/cpucycles/x86estimate.c59
-rw-r--r--nacl/cpucycles/x86estimate.h27
-rw-r--r--nacl/cpucycles/x86tscfreq.c17
-rw-r--r--nacl/cpucycles/x86tscfreq.h27
47 files changed, 1724 insertions, 0 deletions
diff --git a/nacl/cpucycles/alpha.c b/nacl/cpucycles/alpha.c
new file mode 100644
index 00000000..ef497999
--- /dev/null
+++ b/nacl/cpucycles/alpha.c
@@ -0,0 +1,80 @@
1/*
2cpucycles/alpha.c version 20060316
3D. J. Bernstein
4Public domain.
5*/
6
7#include <time.h>
8#include <unistd.h>
9#include <sys/time.h>
10
11static long long tod(void)
12{
13 struct timeval t;
14 gettimeofday(&t,(struct timezone *) 0);
15 return t.tv_sec * (long long) 1000000 + t.tv_usec;
16}
17
18static long long rpcc(void)
19{
20 unsigned long long t;
21 asm volatile("rpcc %0" : "=r"(t));
22 return t & 0xffffffff;
23}
24
25static long long firstrpcc;
26static long long firsttod;
27static long long lastrpcc;
28static long long lasttod;
29static double mhz = 0;
30
31static void init(void)
32{
33 firstrpcc = rpcc();
34 firsttod = tod();
35
36 do {
37 lastrpcc = rpcc();
38 lasttod = tod();
39 } while (lasttod - firsttod < 10000);
40
41 lastrpcc -= firstrpcc; lastrpcc &= 0xffffffff;
42 lasttod -= firsttod;
43
44 mhz = (double) lastrpcc / (double) lasttod;
45}
46
47long long cpucycles_alpha(void)
48{
49 double x;
50 long long y;
51
52 if (!mhz) init();
53
54 lastrpcc = rpcc();
55 lasttod = tod();
56
57 lastrpcc -= firstrpcc; lastrpcc &= 0xffffffff;
58 lasttod -= firsttod;
59
60 /* Number of cycles since firstrpcc is lastrpcc + 2^32 y for unknown y. */
61 /* Number of microseconds since firsttod is lasttod. */
62
63 x = (lasttod * mhz - lastrpcc) * 0.00000000023283064365386962890625;
64 y = x;
65 while (x > y + 0.5) y += 1;
66 while (x < y - 0.5) y -= 1;
67
68 y *= 4294967296ULL;
69 lastrpcc += y;
70
71 mhz = (double) lastrpcc / (double) lasttod;
72
73 return firstrpcc + lastrpcc;
74}
75
76long long cpucycles_alpha_persecond(void)
77{
78 if (!mhz) init();
79 return 1000000.0 * mhz;
80}
diff --git a/nacl/cpucycles/alpha.h b/nacl/cpucycles/alpha.h
new file mode 100644
index 00000000..c97672af
--- /dev/null
+++ b/nacl/cpucycles/alpha.h
@@ -0,0 +1,27 @@
1/*
2cpucycles alpha.h version 20060318
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_alpha_h
8#define CPUCYCLES_alpha_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_alpha(void);
15extern long long cpucycles_alpha_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "alpha"
23#define cpucycles cpucycles_alpha
24#define cpucycles_persecond cpucycles_alpha_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/amd64cpuinfo.c b/nacl/cpucycles/amd64cpuinfo.c
new file mode 100644
index 00000000..729f2612
--- /dev/null
+++ b/nacl/cpucycles/amd64cpuinfo.c
@@ -0,0 +1,16 @@
1#include <stdio.h>
2#include <sys/types.h>
3#include "osfreq.c"
4
5long long cpucycles_amd64cpuinfo(void)
6{
7 unsigned long long result;
8 asm volatile(".byte 15;.byte 49;shlq $32,%%rdx;orq %%rdx,%%rax"
9 : "=a" (result) :: "%rdx");
10 return result;
11}
12
13long long cpucycles_amd64cpuinfo_persecond(void)
14{
15 return osfreq();
16}
diff --git a/nacl/cpucycles/amd64cpuinfo.h b/nacl/cpucycles/amd64cpuinfo.h
new file mode 100644
index 00000000..8f858ae7
--- /dev/null
+++ b/nacl/cpucycles/amd64cpuinfo.h
@@ -0,0 +1,27 @@
1/*
2cpucycles amd64cpuinfo.h version 20100803
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_amd64cpuinfo_h
8#define CPUCYCLES_amd64cpuinfo_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_amd64cpuinfo(void);
15extern long long cpucycles_amd64cpuinfo_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "amd64cpuinfo"
23#define cpucycles cpucycles_amd64cpuinfo
24#define cpucycles_persecond cpucycles_amd64cpuinfo_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/amd64cpuspeed.c b/nacl/cpucycles/amd64cpuspeed.c
new file mode 100644
index 00000000..7e89511c
--- /dev/null
+++ b/nacl/cpucycles/amd64cpuspeed.c
@@ -0,0 +1,25 @@
1#include <stdio.h>
2#include <sys/types.h>
3#include <sys/param.h>
4#include <sys/sysctl.h>
5
6long long cpucycles_amd64cpuspeed(void)
7{
8 unsigned long long result;
9 asm volatile(".byte 15;.byte 49;shlq $32,%%rdx;orq %%rdx,%%rax"
10 : "=a" (result) :: "%rdx");
11 return result;
12}
13
14long long cpucycles_amd64cpuspeed_persecond(void)
15{
16 int oid[2];
17 int val;
18 size_t size;
19 oid[0] = CTL_HW;
20 oid[1] = HW_CPUSPEED;
21 size = sizeof val;
22 if (sysctl(oid,2,&val,&size,0,0) == -1) return 0;
23 if (size != sizeof val) return 0;
24 return val * 1000000LL;
25}
diff --git a/nacl/cpucycles/amd64cpuspeed.h b/nacl/cpucycles/amd64cpuspeed.h
new file mode 100644
index 00000000..1f6ed54d
--- /dev/null
+++ b/nacl/cpucycles/amd64cpuspeed.h
@@ -0,0 +1,27 @@
1/*
2cpucycles amd64cpuspeed.h version 20090716
3Matthew Dempsky
4Public domain.
5*/
6
7#ifndef CPUCYCLES_amd64cpuspeed_h
8#define CPUCYCLES_amd64cpuspeed_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_amd64cpuspeed(void);
15extern long long cpucycles_amd64cpuspeed_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "amd64cpuspeed"
23#define cpucycles cpucycles_amd64cpuspeed
24#define cpucycles_persecond cpucycles_amd64cpuspeed_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/amd64tscfreq.c b/nacl/cpucycles/amd64tscfreq.c
new file mode 100644
index 00000000..ef182c1b
--- /dev/null
+++ b/nacl/cpucycles/amd64tscfreq.c
@@ -0,0 +1,18 @@
1#include <stdio.h>
2#include <sys/types.h>
3
4long long cpucycles_amd64tscfreq(void)
5{
6 unsigned long long result;
7 asm volatile(".byte 15;.byte 49;shlq $32,%%rdx;orq %%rdx,%%rax"
8 : "=a" (result) :: "%rdx");
9 return result;
10}
11
12long long cpucycles_amd64tscfreq_persecond(void)
13{
14 long result = 0;
15 size_t resultlen = sizeof(long);
16 sysctlbyname("machdep.tsc_freq",&result,&resultlen,0,0);
17 return result;
18}
diff --git a/nacl/cpucycles/amd64tscfreq.h b/nacl/cpucycles/amd64tscfreq.h
new file mode 100644
index 00000000..a3c7aa6f
--- /dev/null
+++ b/nacl/cpucycles/amd64tscfreq.h
@@ -0,0 +1,27 @@
1/*
2cpucycles amd64tscfreq.h version 20060318
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_amd64tscfreq_h
8#define CPUCYCLES_amd64tscfreq_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_amd64tscfreq(void);
15extern long long cpucycles_amd64tscfreq_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "amd64tscfreq"
23#define cpucycles cpucycles_amd64tscfreq
24#define cpucycles_persecond cpucycles_amd64tscfreq_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/celllinux.c b/nacl/cpucycles/celllinux.c
new file mode 100644
index 00000000..83a0c38a
--- /dev/null
+++ b/nacl/cpucycles/celllinux.c
@@ -0,0 +1,83 @@
1#include <time.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <sys/time.h>
5#include <sys/types.h>
6#include <spu_mfcio.h>
7
8static long myround(double u)
9{
10 long result = u;
11 while (result + 0.5 < u) result += 1;
12 while (result - 0.5 > u) result -= 1;
13 return result;
14}
15
16static long long microseconds(void)
17{
18 struct timeval t;
19 gettimeofday(&t,(struct timezone *) 0);
20 return t.tv_sec * (long long) 1000000 + t.tv_usec;
21}
22
23static long long timebase(void)
24{
25 unsigned long long result;
26 result = -spu_read_decrementer();
27 return 0xffffffff & result;
28}
29
30static double cpufrequency = 0;
31static long tbcycles = 0;
32
33static double guesstbcycles(void)
34{
35 long long tb0; long long us0;
36 long long tb1; long long us1;
37
38 tb0 = timebase();
39 us0 = microseconds();
40 do {
41 tb1 = timebase();
42 us1 = microseconds();
43 } while (us1 - us0 < 10000 || tb1 - tb0 < 1000);
44 if (tb1 <= tb0) return 0;
45 tb1 -= tb0;
46 us1 -= us0;
47 return (cpufrequency * 0.000001 * (double) us1) / (double) tb1;
48}
49
50static void init(void)
51{
52 int loop;
53 double guess1;
54 double guess2;
55
56 spu_write_decrementer(0xffffffff);
57
58 cpufrequency = 3192000000.0;
59
60 for (loop = 0;loop < 100;++loop) {
61 guess1 = guesstbcycles();
62 guess2 = guesstbcycles();
63 tbcycles = myround(guess1);
64 if (guess1 - tbcycles > 0.1) continue;
65 if (tbcycles - guess1 > 0.1) continue;
66 if (guess2 - tbcycles > 0.1) continue;
67 if (tbcycles - guess2 > 0.1) continue;
68 return;
69 }
70 tbcycles = 0;
71}
72
73long long cpucycles_celllinux(void)
74{
75 if (!tbcycles) init();
76 return timebase() * tbcycles;
77}
78
79long long cpucycles_celllinux_persecond(void)
80{
81 if (!tbcycles) init();
82 return cpufrequency;
83}
diff --git a/nacl/cpucycles/celllinux.h b/nacl/cpucycles/celllinux.h
new file mode 100644
index 00000000..75a5a3f2
--- /dev/null
+++ b/nacl/cpucycles/celllinux.h
@@ -0,0 +1,27 @@
1/*
2cpucycles celllinux.h version 20081201
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_celllinux_h
8#define CPUCYCLES_celllinux_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_celllinux(void);
15extern long long cpucycles_celllinux_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "celllinux"
23#define cpucycles cpucycles_celllinux
24#define cpucycles_persecond cpucycles_celllinux_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/cortex.c b/nacl/cpucycles/cortex.c
new file mode 100644
index 00000000..07e2fa02
--- /dev/null
+++ b/nacl/cpucycles/cortex.c
@@ -0,0 +1,73 @@
1/*
2cpucycles/cortex.c version 20101203
3D. J. Bernstein
4Public domain.
5*/
6
7#define SCALE 1
8#include <time.h>
9#include <unistd.h>
10#include <sys/time.h>
11
12static int enabled = 0;
13
14static int prev[3];
15static unsigned long long prevcycles = 0;
16static int now[3];
17static long long cyclespersec = 0;
18
19static void readticks(unsigned int *result)
20{
21 struct timeval t;
22 unsigned int cc;
23 if (!enabled) {
24 asm volatile("mcr p15, 0, %0, c9, c12, 0" :: "r"(17));
25 asm volatile("mcr p15, 0, %0, c9, c12, 1" :: "r"(0x8000000f));
26 asm volatile("mcr p15, 0, %0, c9, c12, 3" :: "r"(0x8000000f));
27 enabled = 1;
28 }
29 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(cc));
30 gettimeofday(&t,(struct timezone *) 0);
31 result[0] = cc;
32 result[1] = t.tv_usec;
33 result[2] = t.tv_sec;
34}
35
36long long cpucycles_cortex(void)
37{
38 unsigned long long delta4;
39 int deltan;
40 int deltas;
41 unsigned long long guesscycles;
42
43 readticks(now);
44 delta4 = (unsigned int) (now[0] - prev[0]); /* unsigned change in number of cycles mod 2^32 */
45 deltan = now[1] - prev[1]; /* signed change in number of nanoseconds mod 10^9 */
46 deltas = now[2] - prev[2]; /* signed change in number of seconds */
47 if ((deltas == 0 && deltan < 200000) || (deltas == 1 && deltan < -800000))
48 return (prevcycles + delta4) * SCALE;
49
50 prev[0] = now[0];
51 prev[1] = now[1];
52 prev[2] = now[2];
53
54 if ((deltas == 0 && deltan < 300000) || (deltas == 1 && deltan < -700000)) {
55 // actual number of cycles cannot have increased by 2^32 in <0.3ms
56 cyclespersec = 1000000 * (unsigned long long) delta4;
57 cyclespersec /= deltan + 1000000 * (long long) deltas;
58 } else {
59 guesscycles = deltas * cyclespersec;
60 guesscycles += (deltan * cyclespersec) / 1000000;
61 while (delta4 + 2147483648ULL < guesscycles) delta4 += 4294967296ULL;
62 /* XXX: could do longer-term extrapolation here */
63 }
64
65 prevcycles += delta4;
66 return prevcycles * SCALE;
67}
68
69long long cpucycles_cortex_persecond(void)
70{
71 while (!cyclespersec) cpucycles_cortex();
72 return cyclespersec * SCALE;
73}
diff --git a/nacl/cpucycles/cortex.h b/nacl/cpucycles/cortex.h
new file mode 100644
index 00000000..e622f132
--- /dev/null
+++ b/nacl/cpucycles/cortex.h
@@ -0,0 +1,27 @@
1/*
2cpucycles cortex.h version 20100912
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_cortex_h
8#define CPUCYCLES_cortex_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_cortex(void);
15extern long long cpucycles_cortex_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "cortex"
23#define cpucycles cpucycles_cortex
24#define cpucycles_persecond cpucycles_cortex_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/dev4ns.c b/nacl/cpucycles/dev4ns.c
new file mode 100644
index 00000000..73ff5755
--- /dev/null
+++ b/nacl/cpucycles/dev4ns.c
@@ -0,0 +1,62 @@
1#include <sys/types.h>
2#include <fcntl.h>
3#include <time.h>
4#include <stdio.h>
5#include <unistd.h>
6#include <sys/time.h>
7
8static int fddev = -1;
9static int prev[3];
10static unsigned long long prevcycles = 0;
11static int now[3];
12static long long cyclespersec = 0;
13
14static void readdev(unsigned int *result)
15{
16 if (read(fddev,result,12) == 12) return;
17 result[0] = result[1] = result[2] = 0;
18}
19
20long long cpucycles_dev4ns(void)
21{
22 unsigned long long delta4;
23 int deltan;
24 int deltas;
25 unsigned long long guesscycles;
26
27 if (fddev == -1) {
28 fddev = open("/dev/cpucycles4ns",O_RDONLY);
29 readdev(prev);
30 }
31
32 readdev(now);
33 delta4 = (unsigned int) (now[0] - prev[0]); /* unsigned change in number of cycles mod 2^32 */
34 deltan = now[1] - prev[1]; /* signed change in number of nanoseconds mod 10^9 */
35 deltas = now[2] - prev[2]; /* signed change in number of seconds */
36 if ((deltas == 0 && deltan < 200000000) || (deltas == 1 && deltan < -800000000))
37 return prevcycles + delta4;
38
39 prev[0] = now[0];
40 prev[1] = now[1];
41 prev[2] = now[2];
42
43 if ((deltas == 0 && deltan < 300000000) || (deltas == 1 && deltan < -700000000)) {
44 // actual number of cycles cannot have increased by 2^32 in <0.3ms
45 cyclespersec = 1000000000 * (unsigned long long) delta4;
46 cyclespersec /= deltan + 1000000000 * (long long) deltas;
47 } else {
48 guesscycles = deltas * cyclespersec;
49 guesscycles += (deltan * cyclespersec) / 1000000000;
50 while (delta4 + 2147483648ULL < guesscycles) delta4 += 4294967296ULL;
51 /* XXX: could do longer-term extrapolation here */
52 }
53
54 prevcycles += delta4;
55 return prevcycles;
56}
57
58long long cpucycles_dev4ns_persecond(void)
59{
60 while (!cyclespersec) cpucycles_dev4ns();
61 return cyclespersec;
62}
diff --git a/nacl/cpucycles/dev4ns.h b/nacl/cpucycles/dev4ns.h
new file mode 100644
index 00000000..1d99639a
--- /dev/null
+++ b/nacl/cpucycles/dev4ns.h
@@ -0,0 +1,27 @@
1/*
2cpucycles dev4ns.h version 20100803
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_dev4ns_h
8#define CPUCYCLES_dev4ns_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_dev4ns(void);
15extern long long cpucycles_dev4ns_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "dev4ns"
23#define cpucycles cpucycles_dev4ns
24#define cpucycles_persecond cpucycles_dev4ns_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/do b/nacl/cpucycles/do
new file mode 100755
index 00000000..efc063de
--- /dev/null
+++ b/nacl/cpucycles/do
@@ -0,0 +1,105 @@
1#!/bin/sh -e
2
3okabi | (
4 while read abi
5 do
6
7 rm -f cpucycles.o cpucycles.h
8
9 (
10 case "$abi" in
11 ppc*)
12 echo powerpccpuinfo
13 echo powerpcmacos
14 ;;
15 amd64*)
16 echo amd64tscfreq
17 echo amd64cpuinfo
18 echo amd64cpuspeed
19 ;;
20 x86*)
21 echo x86tscfreq
22 echo x86cpuinfo
23 echo x86cpuspeed
24 echo x86estimate
25 ;;
26 cell*)
27 echo celllinux
28 ;;
29 sparc*)
30 echo sparccpuinfo
31 echo sparc32cpuinfo
32 ;;
33 mips*)
34 echo mips
35 ;;
36 hppa*)
37 echo hppapstat
38 ;;
39 alpha*)
40 echo alpha
41 ;;
42 sgi*)
43 echo sgi
44 ;;
45 arm*)
46 echo cortex
47 echo dev4ns
48 ;;
49 esac
50
51 echo amd64tscfreq
52 echo amd64cpuinfo
53 echo amd64cpuspeed
54 echo x86tscfreq
55 echo x86cpuinfo
56 echo x86cpuspeed
57 echo x86estimate
58 echo ia64cpuinfo
59 echo powerpccpuinfo
60 echo powerpcmacos
61 echo celllinux
62 echo sparccpuinfo
63 echo sparc32cpuinfo
64 echo mips
65 echo hppapstat
66 echo alpha
67 echo sgi
68 echo cortex
69 echo dev4ns
70 echo monotoniccpuinfo
71 echo monotonic
72 echo gettimeofday
73 ) | (
74 while read n
75 do
76 okc-$abi | (
77 while read c
78 do
79 echo "=== `date` === Trying $n.c with $c..." >&2
80 rm -f test cpucycles-impl.o cpucycles-impl.h cpucycles-impl.c
81 cp $n.c cpucycles-impl.c || continue
82 cp $n.h cpucycles-impl.h || continue
83 $c -c cpucycles-impl.c || continue
84 $c -o test test.c cpucycles-impl.o || continue
85 ./test || continue
86 echo "=== `date` === Success. Using $n.c." >&2
87 mkdir -p lib/$abi
88 mv cpucycles-impl.o lib/$abi/cpucycles.o
89 mkdir -p include/$abi
90 mv cpucycles-impl.h include/$abi/cpucycles.h
91 exit 0
92 done
93 exit 111
94 ) && exit 0
95 done
96 exit 111
97 ) || (
98 echo ===== Giving up. >&2
99 rm -f test cpucycles-impl.o cpucycles-impl.h cpucycles-impl.c
100 exit 111
101 ) || exit 0
102
103 done
104 exit 0
105) || exit 111
diff --git a/nacl/cpucycles/gettimeofday.c b/nacl/cpucycles/gettimeofday.c
new file mode 100644
index 00000000..0bf5e03c
--- /dev/null
+++ b/nacl/cpucycles/gettimeofday.c
@@ -0,0 +1,32 @@
1#include <time.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <sys/time.h>
5#include <sys/types.h>
6#include "osfreq.c"
7
8static double cpufrequency = 0;
9
10static void init(void)
11{
12 cpufrequency = osfreq();
13}
14
15long long cpucycles_gettimeofday(void)
16{
17 double result;
18 struct timeval t;
19 if (!cpufrequency) init();
20 gettimeofday(&t,(struct timezone *) 0);
21 result = t.tv_usec;
22 result *= 0.000001;
23 result += (double) t.tv_sec;
24 result *= cpufrequency;
25 return result;
26}
27
28long long cpucycles_gettimeofday_persecond(void)
29{
30 if (!cpufrequency) init();
31 return cpufrequency;
32}
diff --git a/nacl/cpucycles/gettimeofday.h b/nacl/cpucycles/gettimeofday.h
new file mode 100644
index 00000000..147b127b
--- /dev/null
+++ b/nacl/cpucycles/gettimeofday.h
@@ -0,0 +1,27 @@
1/*
2cpucycles gettimeofday.h version 20060318
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_gettimeofday_h
8#define CPUCYCLES_gettimeofday_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_gettimeofday(void);
15extern long long cpucycles_gettimeofday_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "gettimeofday"
23#define cpucycles cpucycles_gettimeofday
24#define cpucycles_persecond cpucycles_gettimeofday_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/hppapstat.c b/nacl/cpucycles/hppapstat.c
new file mode 100644
index 00000000..5ae1e843
--- /dev/null
+++ b/nacl/cpucycles/hppapstat.c
@@ -0,0 +1,26 @@
1#include <stdio.h>
2#include <unistd.h>
3#include <sys/types.h>
4#include <sys/param.h>
5#include <sys/pstat.h>
6#include <machine/inline.h>
7
8long long cpucycles_hppapstat(void)
9{
10 register long long result;
11 _MFCTL(16,result);
12 return result;
13}
14
15long long cpucycles_hppapstat_persecond(void)
16{
17 struct pst_processor pst;
18 union pstun pu;
19 double result;
20
21 pu.pst_processor = &pst;
22 if (pstat(PSTAT_PROCESSOR,pu,sizeof(pst),1,0) < 0) return 0;
23 result = pst.psp_iticksperclktick;
24 result *= (double) sysconf(_SC_CLK_TCK);
25 return result;
26}
diff --git a/nacl/cpucycles/hppapstat.h b/nacl/cpucycles/hppapstat.h
new file mode 100644
index 00000000..721814bb
--- /dev/null
+++ b/nacl/cpucycles/hppapstat.h
@@ -0,0 +1,27 @@
1/*
2cpucycles hppapstat.h version 20060319
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_hppapstat_h
8#define CPUCYCLES_hppapstat_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_hppapstat(void);
15extern long long cpucycles_hppapstat_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "hppapstat"
23#define cpucycles cpucycles_hppapstat
24#define cpucycles_persecond cpucycles_hppapstat_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/ia64cpuinfo.c b/nacl/cpucycles/ia64cpuinfo.c
new file mode 100644
index 00000000..580c6cee
--- /dev/null
+++ b/nacl/cpucycles/ia64cpuinfo.c
@@ -0,0 +1,15 @@
1#include <stdio.h>
2#include <sys/types.h>
3#include "osfreq.c"
4
5long long cpucycles_ia64cpuinfo(void)
6{
7 long long result;
8 asm volatile("mov %0=ar.itc" : "=r"(result));
9 return result;
10}
11
12long long cpucycles_ia64cpuinfo_persecond(void)
13{
14 return osfreq();
15}
diff --git a/nacl/cpucycles/ia64cpuinfo.h b/nacl/cpucycles/ia64cpuinfo.h
new file mode 100644
index 00000000..a6bcf47d
--- /dev/null
+++ b/nacl/cpucycles/ia64cpuinfo.h
@@ -0,0 +1,27 @@
1/*
2cpucycles ia64cpuinfo.h version 20100803
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_ia64cpuinfo_h
8#define CPUCYCLES_ia64cpuinfo_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_ia64cpuinfo(void);
15extern long long cpucycles_ia64cpuinfo_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "ia64cpuinfo"
23#define cpucycles cpucycles_ia64cpuinfo
24#define cpucycles_persecond cpucycles_ia64cpuinfo_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/mips.c b/nacl/cpucycles/mips.c
new file mode 100644
index 00000000..8b75f824
--- /dev/null
+++ b/nacl/cpucycles/mips.c
@@ -0,0 +1,65 @@
1/*
2cpucycles/mips.c version 20100803
3D. J. Bernstein
4Public domain.
5*/
6
7#define SCALE 2
8#include <time.h>
9#include <unistd.h>
10#include <sys/time.h>
11
12static int prev[3];
13static unsigned long long prevcycles = 0;
14static int now[3];
15static long long cyclespersec = 0;
16
17static void readticks(unsigned int *result)
18{
19 struct timeval t;
20 unsigned int cc;
21 asm volatile(".byte 59; .byte 16; .byte 2; .byte 124; move %0,$2" : "=r"(cc) : : "$2");
22 gettimeofday(&t,(struct timezone *) 0);
23 result[0] = cc;
24 result[1] = t.tv_usec;
25 result[2] = t.tv_sec;
26}
27
28long long cpucycles_mips(void)
29{
30 unsigned long long delta4;
31 int deltan;
32 int deltas;
33 unsigned long long guesscycles;
34
35 readticks(now);
36 delta4 = (unsigned int) (now[0] - prev[0]); /* unsigned change in number of cycles mod 2^32 */
37 deltan = now[1] - prev[1]; /* signed change in number of nanoseconds mod 10^9 */
38 deltas = now[2] - prev[2]; /* signed change in number of seconds */
39 if ((deltas == 0 && deltan < 200000) || (deltas == 1 && deltan < -800000))
40 return (prevcycles + delta4) * SCALE;
41
42 prev[0] = now[0];
43 prev[1] = now[1];
44 prev[2] = now[2];
45
46 if ((deltas == 0 && deltan < 300000) || (deltas == 1 && deltan < -700000)) {
47 // actual number of cycles cannot have increased by 2^32 in <0.3ms
48 cyclespersec = 1000000 * (unsigned long long) delta4;
49 cyclespersec /= deltan + 1000000 * (long long) deltas;
50 } else {
51 guesscycles = deltas * cyclespersec;
52 guesscycles += (deltan * cyclespersec) / 1000000;
53 while (delta4 + 2147483648ULL < guesscycles) delta4 += 4294967296ULL;
54 /* XXX: could do longer-term extrapolation here */
55 }
56
57 prevcycles += delta4;
58 return prevcycles * SCALE;
59}
60
61long long cpucycles_mips_persecond(void)
62{
63 while (!cyclespersec) cpucycles_mips();
64 return cyclespersec * SCALE;
65}
diff --git a/nacl/cpucycles/mips.h b/nacl/cpucycles/mips.h
new file mode 100644
index 00000000..6f1b26c3
--- /dev/null
+++ b/nacl/cpucycles/mips.h
@@ -0,0 +1,27 @@
1/*
2cpucycles mips.h version 20100802
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_mips_h
8#define CPUCYCLES_mips_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_mips(void);
15extern long long cpucycles_mips_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "mips"
23#define cpucycles cpucycles_mips
24#define cpucycles_persecond cpucycles_mips_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/monotonic.c b/nacl/cpucycles/monotonic.c
new file mode 100644
index 00000000..412a44fb
--- /dev/null
+++ b/nacl/cpucycles/monotonic.c
@@ -0,0 +1,34 @@
1#include <time.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <sys/time.h>
5#include <sys/types.h>
6#include <sys/sysctl.h>
7
8static double cpufrequency = 0;
9
10static void init(void)
11{
12 long result = 0; size_t resultlen = sizeof(long);
13 sysctlbyname("machdep.tsc_freq",&result,&resultlen,0,0);
14 cpufrequency = result;
15}
16
17long long cpucycles_monotonic(void)
18{
19 double result;
20 struct timespec t;
21 if (!cpufrequency) init();
22 clock_gettime(CLOCK_MONOTONIC,&t);
23 result = t.tv_nsec;
24 result *= 0.000000001;
25 result += (double) t.tv_sec;
26 result *= cpufrequency;
27 return result;
28}
29
30long long cpucycles_monotonic_persecond(void)
31{
32 if (!cpufrequency) init();
33 return cpufrequency;
34}
diff --git a/nacl/cpucycles/monotonic.h b/nacl/cpucycles/monotonic.h
new file mode 100644
index 00000000..9070860b
--- /dev/null
+++ b/nacl/cpucycles/monotonic.h
@@ -0,0 +1,27 @@
1/*
2cpucycles monotonic.h version 20100803
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_monotonic_h
8#define CPUCYCLES_monotonic_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_monotonic(void);
15extern long long cpucycles_monotonic_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "monotonic"
23#define cpucycles cpucycles_monotonic
24#define cpucycles_persecond cpucycles_monotonic_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/monotoniccpuinfo.c b/nacl/cpucycles/monotoniccpuinfo.c
new file mode 100644
index 00000000..609c6305
--- /dev/null
+++ b/nacl/cpucycles/monotoniccpuinfo.c
@@ -0,0 +1,33 @@
1#include <time.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <sys/time.h>
5#include <sys/types.h>
6#include <sys/sysctl.h>
7#include "osfreq.c"
8
9static double cpufrequency = 0;
10
11static void init(void)
12{
13 cpufrequency = osfreq();
14}
15
16long long cpucycles_monotoniccpuinfo(void)
17{
18 double result;
19 struct timespec t;
20 if (!cpufrequency) init();
21 clock_gettime(CLOCK_MONOTONIC,&t);
22 result = t.tv_nsec;
23 result *= 0.000000001;
24 result += (double) t.tv_sec;
25 result *= cpufrequency;
26 return result;
27}
28
29long long cpucycles_monotoniccpuinfo_persecond(void)
30{
31 if (!cpufrequency) init();
32 return cpufrequency;
33}
diff --git a/nacl/cpucycles/monotoniccpuinfo.h b/nacl/cpucycles/monotoniccpuinfo.h
new file mode 100644
index 00000000..d4ba7ea8
--- /dev/null
+++ b/nacl/cpucycles/monotoniccpuinfo.h
@@ -0,0 +1,27 @@
1/*
2cpucycles monotoniccpuinfo.h version 20100804
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_monotoniccpuinfo_h
8#define CPUCYCLES_monotoniccpuinfo_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_monotoniccpuinfo(void);
15extern long long cpucycles_monotoniccpuinfo_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "monotoniccpuinfo"
23#define cpucycles cpucycles_monotoniccpuinfo
24#define cpucycles_persecond cpucycles_monotoniccpuinfo_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/osfreq.c b/nacl/cpucycles/osfreq.c
new file mode 100644
index 00000000..4e106a23
--- /dev/null
+++ b/nacl/cpucycles/osfreq.c
@@ -0,0 +1,65 @@
1static double osfreq(void)
2{
3 FILE *f;
4 double result;
5 int s;
6
7 f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", "r");
8 if (f) {
9 s = fscanf(f,"%lf",&result);
10 fclose(f);
11 if (s > 0) return 1000.0 * result;
12 }
13
14 f = fopen("/sys/devices/system/cpu/cpu0/clock_tick", "r");
15 if (f) {
16 s = fscanf(f,"%lf",&result);
17 fclose(f);
18 if (s > 0) return result;
19 }
20
21 f = fopen("/proc/cpuinfo","r");
22 if (f) {
23 for (;;) {
24 s = fscanf(f,"cpu MHz : %lf",&result);
25 if (s > 0) break;
26 if (s == 0) s = fscanf(f,"%*[^\n]\n");
27 if (s < 0) { result = 0; break; }
28 }
29 fclose(f);
30 if (result) return 1000000.0 * result;
31 }
32
33 f = fopen("/proc/cpuinfo","r");
34 if (f) {
35 for (;;) {
36 s = fscanf(f,"clock : %lf",&result);
37 if (s > 0) break;
38 if (s == 0) s = fscanf(f,"%*[^\n]\n");
39 if (s < 0) { result = 0; break; }
40 }
41 fclose(f);
42 if (result) return 1000000.0 * result;
43 }
44
45 f = popen("/usr/sbin/lsattr -E -l proc0 -a frequency 2>/dev/null","r");
46 if (f) {
47 s = fscanf(f,"frequency %lf",&result);
48 pclose(f);
49 if (s > 0) return result;
50 }
51
52 f = popen("/usr/sbin/psrinfo -v 2>/dev/null","r");
53 if (f) {
54 for (;;) {
55 s = fscanf(f," The %*s processor operates at %lf MHz",&result);
56 if (s > 0) break;
57 if (s == 0) s = fscanf(f,"%*[^\n]\n");
58 if (s < 0) { result = 0; break; }
59 }
60 pclose(f);
61 if (result) return 1000000.0 * result;
62 }
63
64 return 0;
65}
diff --git a/nacl/cpucycles/powerpccpuinfo.c b/nacl/cpucycles/powerpccpuinfo.c
new file mode 100644
index 00000000..b70c745a
--- /dev/null
+++ b/nacl/cpucycles/powerpccpuinfo.c
@@ -0,0 +1,95 @@
1#include <time.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <sys/time.h>
5#include <sys/types.h>
6#include "osfreq.c"
7
8static long myround(double u)
9{
10 long result = u;
11 while (result + 0.5 < u) result += 1;
12 while (result - 0.5 > u) result -= 1;
13 return result;
14}
15
16static long long microseconds(void)
17{
18 struct timeval t;
19 gettimeofday(&t,(struct timezone *) 0);
20 return t.tv_sec * (long long) 1000000 + t.tv_usec;
21}
22
23static int tbshift = 0;
24
25static long long timebase(void)
26{
27 unsigned long high;
28 unsigned long low;
29 unsigned long newhigh;
30 unsigned long long result;
31 asm volatile(
32 "7:mftbu %0;mftb %1;mftbu %2;cmpw %0,%2;bne 7b"
33 : "=r" (high), "=r" (low), "=r" (newhigh)
34 );
35 result = high;
36 result <<= 32;
37 result |= low;
38 return result >> tbshift;
39}
40
41static double cpufrequency = 0;
42static long tbcycles = 0;
43
44static double guesstbcycles(void)
45{
46 long long tb0; long long us0;
47 long long tb1; long long us1;
48
49 tb0 = timebase();
50 us0 = microseconds();
51 do {
52 tb1 = timebase();
53 us1 = microseconds();
54 } while (us1 - us0 < 10000 || tb1 - tb0 < 1000);
55 if (tb1 <= tb0) return 0;
56 tb1 -= tb0;
57 us1 -= us0;
58 return (cpufrequency * 0.000001 * (double) us1) / (double) tb1;
59}
60
61static void init(void)
62{
63 int loop;
64 double guess1;
65 double guess2;
66
67 cpufrequency = osfreq();
68 if (!cpufrequency) return;
69
70 for (tbshift = 0;tbshift < 10;++tbshift) {
71 for (loop = 0;loop < 100;++loop) {
72 guess1 = guesstbcycles();
73 guess2 = guesstbcycles();
74 tbcycles = myround(guess1);
75 if (guess1 - tbcycles > 0.1) continue;
76 if (tbcycles - guess1 > 0.1) continue;
77 if (guess2 - tbcycles > 0.1) continue;
78 if (tbcycles - guess2 > 0.1) continue;
79 return;
80 }
81 }
82 tbcycles = 0;
83}
84
85long long cpucycles_powerpccpuinfo(void)
86{
87 if (!tbcycles) init();
88 return timebase() * tbcycles;
89}
90
91long long cpucycles_powerpccpuinfo_persecond(void)
92{
93 if (!tbcycles) init();
94 return cpufrequency;
95}
diff --git a/nacl/cpucycles/powerpccpuinfo.h b/nacl/cpucycles/powerpccpuinfo.h
new file mode 100644
index 00000000..c763a1b4
--- /dev/null
+++ b/nacl/cpucycles/powerpccpuinfo.h
@@ -0,0 +1,27 @@
1/*
2cpucycles powerpccpuinfo.h version 20100803
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_powerpccpuinfo_h
8#define CPUCYCLES_powerpccpuinfo_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_powerpccpuinfo(void);
15extern long long cpucycles_powerpccpuinfo_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "powerpccpuinfo"
23#define cpucycles cpucycles_powerpccpuinfo
24#define cpucycles_persecond cpucycles_powerpccpuinfo_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/powerpcmacos.c b/nacl/cpucycles/powerpcmacos.c
new file mode 100644
index 00000000..ab0be1ea
--- /dev/null
+++ b/nacl/cpucycles/powerpcmacos.c
@@ -0,0 +1,42 @@
1#include <sys/types.h>
2#include <sys/sysctl.h>
3#include <mach/mach_time.h>
4
5#define timebase mach_absolute_time
6
7static int cpumib[2] = { CTL_HW, HW_CPU_FREQ } ;
8static int tbmib[2] = { CTL_HW, HW_TB_FREQ } ;
9
10static long myround(double u)
11{
12 long result = u;
13 while (result + 0.5 < u) result += 1;
14 while (result - 0.5 > u) result -= 1;
15 return result;
16}
17
18static long tbcycles = 0;
19
20static void init(void)
21{
22 unsigned int cpufrequency = 0; size_t cpufrequencylen = sizeof(unsigned int);
23 unsigned int tbfrequency = 0; size_t tbfrequencylen = sizeof(unsigned int);
24 sysctl(cpumib,2,&cpufrequency,&cpufrequencylen,0,0);
25 sysctl(tbmib,2,&tbfrequency,&tbfrequencylen,0,0);
26 if (tbfrequency > 0)
27 tbcycles = myround((double) (unsigned long long) cpufrequency
28 / (double) (unsigned long long) tbfrequency);
29}
30
31long long cpucycles_powerpcmacos(void)
32{
33 if (!tbcycles) init();
34 return timebase() * tbcycles;
35}
36
37long long cpucycles_powerpcmacos_persecond(void)
38{
39 unsigned int result = 0; size_t resultlen = sizeof(unsigned int);
40 sysctl(cpumib,2,&result,&resultlen,0,0);
41 return (unsigned long long) result;
42}
diff --git a/nacl/cpucycles/powerpcmacos.h b/nacl/cpucycles/powerpcmacos.h
new file mode 100644
index 00000000..f66c0e36
--- /dev/null
+++ b/nacl/cpucycles/powerpcmacos.h
@@ -0,0 +1,27 @@
1/*
2cpucycles powerpcmacos.h version 20060319
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_powerpcmacos_h
8#define CPUCYCLES_powerpcmacos_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_powerpcmacos(void);
15extern long long cpucycles_powerpcmacos_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "powerpcmacos"
23#define cpucycles cpucycles_powerpcmacos
24#define cpucycles_persecond cpucycles_powerpcmacos_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/sgi.c b/nacl/cpucycles/sgi.c
new file mode 100644
index 00000000..c232af09
--- /dev/null
+++ b/nacl/cpucycles/sgi.c
@@ -0,0 +1,38 @@
1#include <time.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <sys/time.h>
5#include <sys/types.h>
6#include <sys/sysctl.h>
7
8static double cpufrequency = 0;
9
10static void init(void)
11{
12 FILE *f;
13
14 f = popen("hinv -c processor | awk '{if ($3==\"MHZ\") print $2*1000000}'","r");
15 if (!f) return;
16 if (fscanf(f,"%lf",&cpufrequency) < 1) cpufrequency = 0;
17 pclose(f);
18 if (!cpufrequency) return;
19}
20
21long long cpucycles_sgi(void)
22{
23 double result;
24 struct timespec t;
25 if (!cpufrequency) init();
26 clock_gettime(CLOCK_SGI_CYCLE,&t);
27 result = t.tv_nsec;
28 result *= 0.000000001;
29 result += (double) t.tv_sec;
30 result *= cpufrequency;
31 return result;
32}
33
34long long cpucycles_sgi_persecond(void)
35{
36 if (!cpufrequency) init();
37 return cpufrequency;
38}
diff --git a/nacl/cpucycles/sgi.h b/nacl/cpucycles/sgi.h
new file mode 100644
index 00000000..56bad976
--- /dev/null
+++ b/nacl/cpucycles/sgi.h
@@ -0,0 +1,27 @@
1/*
2cpucycles sgi.h version 20070916
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_sgi_h
8#define CPUCYCLES_sgi_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_sgi(void);
15extern long long cpucycles_sgi_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "sgi"
23#define cpucycles cpucycles_sgi
24#define cpucycles_persecond cpucycles_sgi_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/sparc32cpuinfo.c b/nacl/cpucycles/sparc32cpuinfo.c
new file mode 100644
index 00000000..1fc53d06
--- /dev/null
+++ b/nacl/cpucycles/sparc32cpuinfo.c
@@ -0,0 +1,16 @@
1#include <stdio.h>
2#include <sys/types.h>
3#include "osfreq.c"
4
5long long cpucycles_sparc32cpuinfo(void)
6{
7 long long result;
8 asm volatile(".word 2202075136; .word 2570088480; srl %%g1,0,%L0; mov %%o4,%H0"
9 : "=r" (result) : : "g1","o4");
10 return result;
11}
12
13long long cpucycles_sparc32cpuinfo_persecond(void)
14{
15 return osfreq();
16}
diff --git a/nacl/cpucycles/sparc32cpuinfo.h b/nacl/cpucycles/sparc32cpuinfo.h
new file mode 100644
index 00000000..9d39dc65
--- /dev/null
+++ b/nacl/cpucycles/sparc32cpuinfo.h
@@ -0,0 +1,27 @@
1/*
2cpucycles sparc32cpuinfo.h version 20100804
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_sparc32cpuinfo_h
8#define CPUCYCLES_sparc32cpuinfo_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_sparc32cpuinfo(void);
15extern long long cpucycles_sparc32cpuinfo_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "sparc32cpuinfo"
23#define cpucycles cpucycles_sparc32cpuinfo
24#define cpucycles_persecond cpucycles_sparc32cpuinfo_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/sparccpuinfo.c b/nacl/cpucycles/sparccpuinfo.c
new file mode 100644
index 00000000..d07aafec
--- /dev/null
+++ b/nacl/cpucycles/sparccpuinfo.c
@@ -0,0 +1,15 @@
1#include <stdio.h>
2#include <sys/types.h>
3#include "osfreq.c"
4
5long long cpucycles_sparccpuinfo(void)
6{
7 long long result;
8 asm volatile("rd %%tick,%0" : "=r" (result));
9 return result;
10}
11
12long long cpucycles_sparccpuinfo_persecond(void)
13{
14 return osfreq();
15}
diff --git a/nacl/cpucycles/sparccpuinfo.h b/nacl/cpucycles/sparccpuinfo.h
new file mode 100644
index 00000000..badb2144
--- /dev/null
+++ b/nacl/cpucycles/sparccpuinfo.h
@@ -0,0 +1,27 @@
1/*
2cpucycles sparccpuinfo.h version 20100803
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_sparccpuinfo_h
8#define CPUCYCLES_sparccpuinfo_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_sparccpuinfo(void);
15extern long long cpucycles_sparccpuinfo_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "sparccpuinfo"
23#define cpucycles cpucycles_sparccpuinfo
24#define cpucycles_persecond cpucycles_sparccpuinfo_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/test.c b/nacl/cpucycles/test.c
new file mode 100644
index 00000000..bc43d719
--- /dev/null
+++ b/nacl/cpucycles/test.c
@@ -0,0 +1,77 @@
1#include <time.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <sys/time.h>
5#include "cpucycles-impl.h"
6
7static long long tod(void)
8{
9 struct timeval t;
10 gettimeofday(&t,(struct timezone *) 0);
11 return t.tv_sec * (long long) 1000000 + t.tv_usec;
12}
13
14long long todstart;
15long long todend;
16long long cpustart;
17long long cpuend;
18
19long long cyclespersecond;
20long long cyclespertod;
21
22long long t[1001];
23
24int main()
25{
26 int j;
27 int i;
28
29 if (!cpucycles()) {
30 fprintf(stderr,"cpucycles() = %lld\n",cpucycles());
31 return 100;
32 }
33 for (i = 0;i <= 1000;++i) t[i] = cpucycles();
34 for (i = 0;i < 1000;++i) if (t[i] > t[i + 1]) {
35 fprintf(stderr,"t[%d] = %lld\n",i,t[i]);
36 fprintf(stderr,"t[%d] = %lld\n",i + 1,t[i + 1]);
37 fprintf(stderr,"cpucycles_persecond() = %lld\n",cpucycles_persecond());
38 return 100;
39 }
40 if (t[0] == t[1000]) {
41 fprintf(stderr,"t[%d] = %lld\n",0,t[0]);
42 fprintf(stderr,"t[%d] = %lld\n",1000,t[1000]);
43 fprintf(stderr,"cpucycles_persecond() = %lld\n",cpucycles_persecond());
44 return 100;
45 }
46
47 cyclespersecond = cpucycles_persecond();
48
49 if (cyclespersecond <= 0) {
50 fprintf(stderr,"cpucycles_persecond() = %lld\n",cyclespersecond);
51 return 100;
52 }
53
54 todstart = tod();
55 cpustart = cpucycles();
56 for (j = 0;j < 1000;++j) for (i = 0;i <= 1000;++i) t[i] = t[i] + i + j;
57 todend = tod();
58 cpuend = cpucycles();
59
60 todend -= todstart;
61 cpuend -= cpustart;
62
63 cyclespertod = (long long) (((double) cpuend) * 1000000.0 / (double) todend);
64
65 if (cyclespertod > 10 * cyclespersecond) {
66 fprintf(stderr,"cyclespertod = %lld, cyclespersecond = %lld\n",cyclespertod,cyclespersecond);
67 return 100;
68 }
69
70 for (i = 0;i <= 1000;++i) t[i] = cpucycles();
71 printf("%s",cpucycles_implementation);
72 printf(" %lld",cyclespersecond);
73 printf(" %lld",cyclespertod);
74 for (i = 0;i < 64;++i) printf(" %lld",t[i + 1] - t[i]);
75 printf("\n");
76 return 0;
77}
diff --git a/nacl/cpucycles/x86cpuinfo.c b/nacl/cpucycles/x86cpuinfo.c
new file mode 100644
index 00000000..3fb0a1b0
--- /dev/null
+++ b/nacl/cpucycles/x86cpuinfo.c
@@ -0,0 +1,15 @@
1#include <stdio.h>
2#include <sys/types.h>
3#include "osfreq.c"
4
5long long cpucycles_x86cpuinfo(void)
6{
7 long long result;
8 asm volatile(".byte 15;.byte 49" : "=A" (result));
9 return result;
10}
11
12long long cpucycles_x86cpuinfo_persecond(void)
13{
14 return osfreq();
15}
diff --git a/nacl/cpucycles/x86cpuinfo.h b/nacl/cpucycles/x86cpuinfo.h
new file mode 100644
index 00000000..88f151dd
--- /dev/null
+++ b/nacl/cpucycles/x86cpuinfo.h
@@ -0,0 +1,27 @@
1/*
2cpucycles x86cpuinfo.h version 20100803
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_x86cpuinfo_h
8#define CPUCYCLES_x86cpuinfo_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_x86cpuinfo(void);
15extern long long cpucycles_x86cpuinfo_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "x86cpuinfo"
23#define cpucycles cpucycles_x86cpuinfo
24#define cpucycles_persecond cpucycles_x86cpuinfo_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/x86cpuspeed.c b/nacl/cpucycles/x86cpuspeed.c
new file mode 100644
index 00000000..34222565
--- /dev/null
+++ b/nacl/cpucycles/x86cpuspeed.c
@@ -0,0 +1,24 @@
1#include <stdio.h>
2#include <sys/types.h>
3#include <sys/param.h>
4#include <sys/sysctl.h>
5
6long long cpucycles_x86cpuspeed(void)
7{
8 long long result;
9 asm volatile(".byte 15;.byte 49" : "=A" (result));
10 return result;
11}
12
13long long cpucycles_x86cpuspeed_persecond(void)
14{
15 int oid[2];
16 int val;
17 size_t size;
18 oid[0] = CTL_HW;
19 oid[1] = HW_CPUSPEED;
20 size = sizeof val;
21 if (sysctl(oid,2,&val,&size,0,0) == -1) return 0;
22 if (size != sizeof val) return 0;
23 return val * 1000000LL;
24}
diff --git a/nacl/cpucycles/x86cpuspeed.h b/nacl/cpucycles/x86cpuspeed.h
new file mode 100644
index 00000000..43005cda
--- /dev/null
+++ b/nacl/cpucycles/x86cpuspeed.h
@@ -0,0 +1,27 @@
1/*
2cpucycles x86cpuspeed.h version 20090716
3Matthew Dempsky
4Public domain.
5*/
6
7#ifndef CPUCYCLES_x86cpuspeed_h
8#define CPUCYCLES_x86cpuspeed_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_x86cpuspeed(void);
15extern long long cpucycles_x86cpuspeed_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "x86cpuspeed"
23#define cpucycles cpucycles_x86cpuspeed
24#define cpucycles_persecond cpucycles_x86cpuspeed_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/x86estimate.c b/nacl/cpucycles/x86estimate.c
new file mode 100644
index 00000000..e5ae66cf
--- /dev/null
+++ b/nacl/cpucycles/x86estimate.c
@@ -0,0 +1,59 @@
1#include <time.h>
2#include <sys/time.h>
3#include <sys/types.h>
4#include <sys/sysctl.h>
5
6long long cpucycles_x86estimate(void)
7{
8 long long result;
9 asm volatile(".byte 15;.byte 49" : "=A" (result));
10 return result;
11}
12
13static long long microseconds(void)
14{
15 struct timeval t;
16 gettimeofday(&t,(struct timezone *) 0);
17 return t.tv_sec * (long long) 1000000 + t.tv_usec;
18}
19
20static double guessfreq(void)
21{
22 long long tb0; long long us0;
23 long long tb1; long long us1;
24
25 tb0 = cpucycles_x86estimate();
26 us0 = microseconds();
27 do {
28 tb1 = cpucycles_x86estimate();
29 us1 = microseconds();
30 } while (us1 - us0 < 10000 || tb1 - tb0 < 1000);
31 if (tb1 <= tb0) return 0;
32 tb1 -= tb0;
33 us1 -= us0;
34 return ((double) tb1) / (0.000001 * (double) us1);
35}
36
37static double cpufrequency = 0;
38
39static void init(void)
40{
41 double guess1;
42 double guess2;
43 int loop;
44
45 for (loop = 0;loop < 100;++loop) {
46 guess1 = guessfreq();
47 guess2 = guessfreq();
48 if (guess1 > 1.01 * guess2) continue;
49 if (guess2 > 1.01 * guess1) continue;
50 cpufrequency = 0.5 * (guess1 + guess2);
51 break;
52 }
53}
54
55long long cpucycles_x86estimate_persecond(void)
56{
57 if (!cpufrequency) init();
58 return cpufrequency;
59}
diff --git a/nacl/cpucycles/x86estimate.h b/nacl/cpucycles/x86estimate.h
new file mode 100644
index 00000000..98f2dd15
--- /dev/null
+++ b/nacl/cpucycles/x86estimate.h
@@ -0,0 +1,27 @@
1/*
2cpucycles x86estimate.h version 20070121
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_x86estimate_h
8#define CPUCYCLES_x86estimate_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_x86estimate(void);
15extern long long cpucycles_x86estimate_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "x86estimate"
23#define cpucycles cpucycles_x86estimate
24#define cpucycles_persecond cpucycles_x86estimate_persecond
25#endif
26
27#endif
diff --git a/nacl/cpucycles/x86tscfreq.c b/nacl/cpucycles/x86tscfreq.c
new file mode 100644
index 00000000..a1b94b62
--- /dev/null
+++ b/nacl/cpucycles/x86tscfreq.c
@@ -0,0 +1,17 @@
1#include <sys/types.h>
2#include <sys/sysctl.h>
3
4long long cpucycles_x86tscfreq(void)
5{
6 long long result;
7 asm volatile(".byte 15;.byte 49" : "=A" (result));
8 return result;
9}
10
11long long cpucycles_x86tscfreq_persecond(void)
12{
13 long result = 0;
14 size_t resultlen = sizeof(long);
15 sysctlbyname("machdep.tsc_freq",&result,&resultlen,0,0);
16 return result;
17}
diff --git a/nacl/cpucycles/x86tscfreq.h b/nacl/cpucycles/x86tscfreq.h
new file mode 100644
index 00000000..abf616e5
--- /dev/null
+++ b/nacl/cpucycles/x86tscfreq.h
@@ -0,0 +1,27 @@
1/*
2cpucycles x86tscfreq.h version 20060318
3D. J. Bernstein
4Public domain.
5*/
6
7#ifndef CPUCYCLES_x86tscfreq_h
8#define CPUCYCLES_x86tscfreq_h
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14extern long long cpucycles_x86tscfreq(void);
15extern long long cpucycles_x86tscfreq_persecond(void);
16
17#ifdef __cplusplus
18}
19#endif
20
21#ifndef cpucycles_implementation
22#define cpucycles_implementation "x86tscfreq"
23#define cpucycles cpucycles_x86tscfreq
24#define cpucycles_persecond cpucycles_x86tscfreq_persecond
25#endif
26
27#endif