Xenomai  3.1
clock.h
1 /*
2  * Copyright (C) 2006,2007 Philippe Gerum <rpm@xenomai.org>.
3  *
4  * Xenomai is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  *
9  * Xenomai is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Xenomai; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  */
19 #ifndef _COBALT_KERNEL_CLOCK_H
20 #define _COBALT_KERNEL_CLOCK_H
21 
22 #include <linux/ipipe.h>
23 #include <cobalt/kernel/list.h>
24 #include <cobalt/kernel/vfile.h>
25 #include <cobalt/uapi/kernel/types.h>
26 
32 struct xnsched;
33 struct xntimerdata;
34 
35 struct xnclock_gravity {
36  unsigned long irq;
37  unsigned long kernel;
38  unsigned long user;
39 };
40 
41 struct xnclock {
43  xnticks_t wallclock_offset;
45  xnticks_t resolution;
47  struct xnclock_gravity gravity;
49  const char *name;
50  struct {
51 #ifdef CONFIG_XENO_OPT_EXTCLOCK
52  xnticks_t (*read_raw)(struct xnclock *clock);
53  xnticks_t (*read_monotonic)(struct xnclock *clock);
54  int (*set_time)(struct xnclock *clock,
55  const struct timespec *ts);
56  xnsticks_t (*ns_to_ticks)(struct xnclock *clock,
57  xnsticks_t ns);
58  xnsticks_t (*ticks_to_ns)(struct xnclock *clock,
59  xnsticks_t ticks);
60  xnsticks_t (*ticks_to_ns_rounded)(struct xnclock *clock,
61  xnsticks_t ticks);
62  void (*program_local_shot)(struct xnclock *clock,
63  struct xnsched *sched);
64  void (*program_remote_shot)(struct xnclock *clock,
65  struct xnsched *sched);
66 #endif
67  int (*adjust_time)(struct xnclock *clock,
68  struct timex *tx);
69  int (*set_gravity)(struct xnclock *clock,
70  const struct xnclock_gravity *p);
71  void (*reset_gravity)(struct xnclock *clock);
72 #ifdef CONFIG_XENO_OPT_VFILE
73  void (*print_status)(struct xnclock *clock,
74  struct xnvfile_regular_iterator *it);
75 #endif
76  } ops;
77  /* Private section. */
78  struct xntimerdata *timerdata;
79  int id;
80 #ifdef CONFIG_SMP
81 
82  cpumask_t affinity;
83 #endif
84 #ifdef CONFIG_XENO_OPT_STATS
85  struct xnvfile_snapshot timer_vfile;
86  struct xnvfile_rev_tag timer_revtag;
87  struct list_head timerq;
88  int nrtimers;
89 #endif /* CONFIG_XENO_OPT_STATS */
90 #ifdef CONFIG_XENO_OPT_VFILE
91  struct xnvfile_regular vfile;
92 #endif
93 };
94 
95 struct xnclock_ratelimit_state {
96  xnticks_t interval;
97  xnticks_t begin;
98  int burst;
99  int printed;
100  int missed;
101 };
102 
103 extern struct xnclock nkclock;
104 
105 extern unsigned long nktimerlat;
106 
107 int xnclock_register(struct xnclock *clock,
108  const cpumask_t *affinity);
109 
110 void xnclock_deregister(struct xnclock *clock);
111 
112 void xnclock_tick(struct xnclock *clock);
113 
114 void xnclock_adjust(struct xnclock *clock,
115  xnsticks_t delta);
116 
117 void xnclock_core_local_shot(struct xnsched *sched);
118 
119 void xnclock_core_remote_shot(struct xnsched *sched);
120 
121 xnsticks_t xnclock_core_ns_to_ticks(xnsticks_t ns);
122 
123 xnsticks_t xnclock_core_ticks_to_ns(xnsticks_t ticks);
124 
125 xnsticks_t xnclock_core_ticks_to_ns_rounded(xnsticks_t ticks);
126 
127 xnticks_t xnclock_core_read_monotonic(void);
128 
129 static inline xnticks_t xnclock_core_read_raw(void)
130 {
131  unsigned long long t;
132  ipipe_read_tsc(t);
133  return t;
134 }
135 
136 /* We use the Linux defaults */
137 #define XN_RATELIMIT_INTERVAL 5000000000LL
138 #define XN_RATELIMIT_BURST 10
139 
140 int __xnclock_ratelimit(struct xnclock_ratelimit_state *rs, const char *func);
141 
142 #define xnclock_ratelimit() ({ \
143  static struct xnclock_ratelimit_state __state = { \
144  .interval = XN_RATELIMIT_INTERVAL, \
145  .burst = XN_RATELIMIT_BURST, \
146  }; \
147  __xnclock_ratelimit(&__state, __func__); \
148 })
149 
150 #ifdef CONFIG_XENO_OPT_EXTCLOCK
151 
152 static inline void xnclock_program_shot(struct xnclock *clock,
153  struct xnsched *sched)
154 {
155  if (likely(clock == &nkclock))
156  xnclock_core_local_shot(sched);
157  else if (clock->ops.program_local_shot)
158  clock->ops.program_local_shot(clock, sched);
159 }
160 
161 static inline void xnclock_remote_shot(struct xnclock *clock,
162  struct xnsched *sched)
163 {
164 #ifdef CONFIG_SMP
165  if (likely(clock == &nkclock))
166  xnclock_core_remote_shot(sched);
167  else if (clock->ops.program_remote_shot)
168  clock->ops.program_remote_shot(clock, sched);
169 #endif
170 }
171 
172 static inline xnticks_t xnclock_read_raw(struct xnclock *clock)
173 {
174  if (likely(clock == &nkclock))
175  return xnclock_core_read_raw();
176 
177  return clock->ops.read_raw(clock);
178 }
179 
180 static inline xnsticks_t xnclock_ns_to_ticks(struct xnclock *clock,
181  xnsticks_t ns)
182 {
183  if (likely(clock == &nkclock))
184  return xnclock_core_ns_to_ticks(ns);
185 
186  return clock->ops.ns_to_ticks(clock, ns);
187 }
188 
189 static inline xnsticks_t xnclock_ticks_to_ns(struct xnclock *clock,
190  xnsticks_t ticks)
191 {
192  if (likely(clock == &nkclock))
193  return xnclock_core_ticks_to_ns(ticks);
194 
195  return clock->ops.ticks_to_ns(clock, ticks);
196 }
197 
198 static inline xnsticks_t xnclock_ticks_to_ns_rounded(struct xnclock *clock,
199  xnsticks_t ticks)
200 {
201  if (likely(clock == &nkclock))
202  return xnclock_core_ticks_to_ns_rounded(ticks);
203 
204  return clock->ops.ticks_to_ns_rounded(clock, ticks);
205 }
206 
207 static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
208 {
209  if (likely(clock == &nkclock))
210  return xnclock_core_read_monotonic();
211 
212  return clock->ops.read_monotonic(clock);
213 }
214 
215 static inline int xnclock_set_time(struct xnclock *clock,
216  const struct timespec *ts)
217 {
218  if (likely(clock == &nkclock))
219  return -EINVAL;
220 
221  return clock->ops.set_time(clock, ts);
222 }
223 
224 #else /* !CONFIG_XENO_OPT_EXTCLOCK */
225 
226 static inline void xnclock_program_shot(struct xnclock *clock,
227  struct xnsched *sched)
228 {
229  xnclock_core_local_shot(sched);
230 }
231 
232 static inline void xnclock_remote_shot(struct xnclock *clock,
233  struct xnsched *sched)
234 {
235 #ifdef CONFIG_SMP
236  xnclock_core_remote_shot(sched);
237 #endif
238 }
239 
240 static inline xnticks_t xnclock_read_raw(struct xnclock *clock)
241 {
242  return xnclock_core_read_raw();
243 }
244 
245 static inline xnsticks_t xnclock_ns_to_ticks(struct xnclock *clock,
246  xnsticks_t ns)
247 {
248  return xnclock_core_ns_to_ticks(ns);
249 }
250 
251 static inline xnsticks_t xnclock_ticks_to_ns(struct xnclock *clock,
252  xnsticks_t ticks)
253 {
254  return xnclock_core_ticks_to_ns(ticks);
255 }
256 
257 static inline xnsticks_t xnclock_ticks_to_ns_rounded(struct xnclock *clock,
258  xnsticks_t ticks)
259 {
260  return xnclock_core_ticks_to_ns_rounded(ticks);
261 }
262 
263 static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
264 {
265  return xnclock_core_read_monotonic();
266 }
267 
268 static inline int xnclock_set_time(struct xnclock *clock,
269  const struct timespec *ts)
270 {
271  /*
272  * There is no way to change the core clock's idea of time.
273  */
274  return -EINVAL;
275 }
276 
277 #endif /* !CONFIG_XENO_OPT_EXTCLOCK */
278 
279 static inline int xnclock_adjust_time(struct xnclock *clock,
280  struct timex *tx)
281 {
282  if (clock->ops.adjust_time == NULL)
283  return -EOPNOTSUPP;
284 
285  return clock->ops.adjust_time(clock, tx);
286 }
287 
288 static inline xnticks_t xnclock_get_offset(struct xnclock *clock)
289 {
290  return clock->wallclock_offset;
291 }
292 
293 static inline xnticks_t xnclock_get_resolution(struct xnclock *clock)
294 {
295  return clock->resolution; /* ns */
296 }
297 
298 static inline void xnclock_set_resolution(struct xnclock *clock,
299  xnticks_t resolution)
300 {
301  clock->resolution = resolution; /* ns */
302 }
303 
304 static inline int xnclock_set_gravity(struct xnclock *clock,
305  const struct xnclock_gravity *gravity)
306 {
307  if (clock->ops.set_gravity)
308  return clock->ops.set_gravity(clock, gravity);
309 
310  return -EINVAL;
311 }
312 
313 static inline void xnclock_reset_gravity(struct xnclock *clock)
314 {
315  if (clock->ops.reset_gravity)
316  clock->ops.reset_gravity(clock);
317 }
318 
319 #define xnclock_get_gravity(__clock, __type) ((__clock)->gravity.__type)
320 
321 static inline xnticks_t xnclock_read_realtime(struct xnclock *clock)
322 {
323  /*
324  * Return an adjusted value of the monotonic time with the
325  * translated system wallclock offset.
326  */
327  return xnclock_read_monotonic(clock) + xnclock_get_offset(clock);
328 }
329 
330 unsigned long long xnclock_divrem_billion(unsigned long long value,
331  unsigned long *rem);
332 
333 xnticks_t xnclock_get_host_time(void);
334 
335 #ifdef CONFIG_XENO_OPT_VFILE
336 
337 void xnclock_init_proc(void);
338 
339 void xnclock_cleanup_proc(void);
340 
341 static inline void xnclock_print_status(struct xnclock *clock,
342  struct xnvfile_regular_iterator *it)
343 {
344  if (clock->ops.print_status)
345  clock->ops.print_status(clock, it);
346 }
347 
348 #else
349 static inline void xnclock_init_proc(void) { }
350 static inline void xnclock_cleanup_proc(void) { }
351 #endif
352 
353 void xnclock_update_freq(unsigned long long freq);
354 
355 int xnclock_init(unsigned long long freq);
356 
357 void xnclock_cleanup(void);
358 
361 #endif /* !_COBALT_KERNEL_CLOCK_H */
Snapshot revision tag.
Definition: vfile.h:482
void xnclock_deregister(struct xnclock *clock)
Deregister a Xenomai clock.
Definition: clock.c:710
Scheduling information structure.
Definition: sched.h:58
Regular vfile iterator.
Definition: vfile.h:269
void xnclock_adjust(struct xnclock *clock, xnsticks_t delta)
Adjust a clock time.
Definition: clock.c:341
void xnclock_tick(struct xnclock *clock)
Process a clock tick.
Definition: clock.c:745
int xnclock_register(struct xnclock *clock, const cpumask_t *affinity)
Register a Xenomai clock.
Definition: clock.c:646
Snapshot vfile descriptor.
Definition: vfile.h:506