This source file includes following definitions.
- find_info
- opal_timer_linux_find_freq
- opal_timer_linux_open
- opal_timer_linux_get_usec_clock_gettime
- opal_timer_linux_get_cycles_clock_gettime
- opal_timer_linux_get_cycles_sys_timer
- opal_timer_linux_get_usec_sys_timer
- opal_timer_base_get_freq
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include "opal_config.h"
27
28 #include <string.h>
29
30 #include "opal/mca/timer/timer.h"
31 #include "opal/mca/timer/base/base.h"
32 #include "opal/mca/timer/linux/timer_linux.h"
33 #include "opal/constants.h"
34 #include "opal/util/show_help.h"
35
36 static opal_timer_t opal_timer_linux_get_cycles_sys_timer(void);
37 static opal_timer_t opal_timer_linux_get_usec_sys_timer(void);
38
39
40
41
42 #if OPAL_HAVE_CLOCK_GETTIME
43 static opal_timer_t opal_timer_linux_get_cycles_clock_gettime(void);
44 static opal_timer_t opal_timer_linux_get_usec_clock_gettime(void);
45
46 opal_timer_t (*opal_timer_base_get_cycles)(void) =
47 opal_timer_linux_get_cycles_clock_gettime;
48 opal_timer_t (*opal_timer_base_get_usec)(void) =
49 opal_timer_linux_get_usec_clock_gettime;
50 #else
51 opal_timer_t (*opal_timer_base_get_cycles)(void) =
52 opal_timer_linux_get_cycles_sys_timer;
53 opal_timer_t (*opal_timer_base_get_usec)(void) =
54 opal_timer_linux_get_usec_sys_timer;
55 #endif
56
57 static opal_timer_t opal_timer_linux_freq = {0};
58
59 static int opal_timer_linux_open(void);
60
61 const opal_timer_base_component_2_0_0_t mca_timer_linux_component = {
62
63
64 .timerc_version = {
65 OPAL_TIMER_BASE_VERSION_2_0_0,
66
67
68 .mca_component_name = "linux",
69 MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION,
70 OPAL_RELEASE_VERSION),
71
72
73 .mca_open_component = opal_timer_linux_open,
74 },
75 .timerc_data = {
76
77 MCA_BASE_METADATA_PARAM_CHECKPOINT
78 },
79 };
80
81 static char *
82 find_info(FILE* fp, char *str, char *buf, size_t buflen)
83 {
84 char *tmp;
85
86 rewind(fp);
87 while (NULL != fgets(buf, buflen, fp)) {
88 if (strncmp(buf, str, strlen(str)) == 0) {
89
90
91 for (tmp = buf ; (*tmp != '\0') && (*tmp != ':') ; ++tmp) ;
92 if (*tmp == '\0') {
93 continue;
94 }
95 for ( ++tmp ; *tmp == ' ' ; ++tmp);
96 if ('\0' != *tmp) {
97 return tmp;
98 }
99 }
100 }
101
102 return NULL;
103 }
104
105 static int opal_timer_linux_find_freq(void)
106 {
107 FILE *fp;
108 char *loc;
109 float cpu_f;
110 int ret;
111 char buf[1024];
112
113 fp = fopen("/proc/cpuinfo", "r");
114 if (NULL == fp) {
115 return OPAL_ERR_IN_ERRNO;
116 }
117
118 opal_timer_linux_freq = 0;
119
120 #if OPAL_HAVE_SYS_TIMER_GET_FREQ
121 opal_timer_linux_freq = opal_sys_timer_get_freq();
122 #endif
123
124 if (0 == opal_timer_linux_freq) {
125
126
127 loc = find_info(fp, "timebase", buf, 1024);
128 if (NULL != loc) {
129 int freq;
130 ret = sscanf(loc, "%d", &freq);
131 if (1 == ret) {
132 opal_timer_linux_freq = freq;
133 }
134 }
135 }
136
137 #if ((OPAL_ASSEMBLY_ARCH == OPAL_IA32) || (OPAL_ASSEMBLY_ARCH == OPAL_X86_64))
138 if (0 == opal_timer_linux_freq && opal_sys_timer_is_monotonic()) {
139
140 loc = find_info(fp, "bogomips", buf, 1024);
141 if (NULL != loc) {
142 ret = sscanf(loc, "%f", &cpu_f);
143 if (1 == ret) {
144
145
146 opal_timer_linux_freq = (opal_timer_t) (cpu_f * 100.0f) * 5000;
147 }
148 }
149 }
150 #endif
151
152 if (0 == opal_timer_linux_freq) {
153
154 loc = find_info(fp, "cpu MHz", buf, 1024);
155 if (NULL != loc) {
156 ret = sscanf(loc, "%f", &cpu_f);
157 if (1 == ret) {
158
159 opal_timer_linux_freq = (opal_timer_t) (cpu_f * 1000000);
160 }
161 }
162 }
163
164 if (0 == opal_timer_linux_freq) {
165
166 loc = find_info(fp, "Cpu0ClkTck", buf, 1024);
167 if (NULL != loc) {
168 unsigned int freq;
169 ret = sscanf(loc, "%x", &freq);
170 if (1 == ret) {
171 opal_timer_linux_freq = freq;
172 }
173 }
174 }
175
176 fclose(fp);
177
178
179
180 opal_timer_linux_freq /= 1000000;
181
182 return OPAL_SUCCESS;
183 }
184
185 int opal_timer_linux_open(void)
186 {
187 int ret = OPAL_SUCCESS;
188
189 if (mca_timer_base_monotonic && !opal_sys_timer_is_monotonic ()) {
190 #if OPAL_HAVE_CLOCK_GETTIME && (0 == OPAL_TIMER_MONOTONIC)
191 struct timespec res;
192 if( 0 == clock_getres(CLOCK_MONOTONIC, &res)) {
193 opal_timer_linux_freq = 1.e3;
194 opal_timer_base_get_cycles = opal_timer_linux_get_cycles_clock_gettime;
195 opal_timer_base_get_usec = opal_timer_linux_get_usec_clock_gettime;
196 return ret;
197 }
198 #else
199
200 opal_show_help("help-opal-timer-linux.txt", "monotonic not supported", true);
201 #endif
202 }
203 ret = opal_timer_linux_find_freq();
204 opal_timer_base_get_cycles = opal_timer_linux_get_cycles_sys_timer;
205 opal_timer_base_get_usec = opal_timer_linux_get_usec_sys_timer;
206 return ret;
207 }
208
209 #if OPAL_HAVE_CLOCK_GETTIME
210 opal_timer_t opal_timer_linux_get_usec_clock_gettime(void)
211 {
212 struct timespec tp = {.tv_sec = 0, .tv_nsec = 0};
213
214 (void) clock_gettime (CLOCK_MONOTONIC, &tp);
215
216 return (tp.tv_sec * 1e6 + tp.tv_nsec/1000);
217 }
218
219 opal_timer_t opal_timer_linux_get_cycles_clock_gettime(void)
220 {
221 struct timespec tp = {.tv_sec = 0, .tv_nsec = 0};
222
223 (void) clock_gettime(CLOCK_MONOTONIC, &tp);
224
225 return (tp.tv_sec * 1e9 + tp.tv_nsec);
226 }
227 #endif
228
229 opal_timer_t opal_timer_linux_get_cycles_sys_timer(void)
230 {
231 #if OPAL_HAVE_SYS_TIMER_GET_CYCLES
232 return opal_sys_timer_get_cycles();
233 #else
234 return 0;
235 #endif
236 }
237
238
239 opal_timer_t opal_timer_linux_get_usec_sys_timer(void)
240 {
241 #if OPAL_HAVE_SYS_TIMER_GET_CYCLES
242
243 return opal_sys_timer_get_cycles() / opal_timer_linux_freq;
244 #else
245 return 0;
246 #endif
247 }
248
249 opal_timer_t opal_timer_base_get_freq(void)
250 {
251 return opal_timer_linux_freq * 1000000;
252 }