diff options
Diffstat (limited to 'nacl/cpucycles/celllinux.c')
-rw-r--r-- | nacl/cpucycles/celllinux.c | 83 |
1 files changed, 83 insertions, 0 deletions
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 | |||
8 | static 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 | |||
16 | static 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 | |||
23 | static long long timebase(void) | ||
24 | { | ||
25 | unsigned long long result; | ||
26 | result = -spu_read_decrementer(); | ||
27 | return 0xffffffff & result; | ||
28 | } | ||
29 | |||
30 | static double cpufrequency = 0; | ||
31 | static long tbcycles = 0; | ||
32 | |||
33 | static 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 | |||
50 | static 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 | |||
73 | long long cpucycles_celllinux(void) | ||
74 | { | ||
75 | if (!tbcycles) init(); | ||
76 | return timebase() * tbcycles; | ||
77 | } | ||
78 | |||
79 | long long cpucycles_celllinux_persecond(void) | ||
80 | { | ||
81 | if (!tbcycles) init(); | ||
82 | return cpufrequency; | ||
83 | } | ||