summaryrefslogtreecommitdiff
path: root/nacl/cpucycles/alpha.c
diff options
context:
space:
mode:
Diffstat (limited to 'nacl/cpucycles/alpha.c')
-rw-r--r--nacl/cpucycles/alpha.c80
1 files changed, 80 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}