Xenomai  3.0.5
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 (*set_gravity)(struct xnclock *clock,
68  const struct xnclock_gravity *p);
69  void (*reset_gravity)(struct xnclock *clock);
70 #ifdef CONFIG_XENO_OPT_VFILE
71  void (*print_status)(struct xnclock *clock,
72  struct xnvfile_regular_iterator *it);
73 #endif
74  } ops;
75  /* Private section. */
76  struct xntimerdata *timerdata;
77  int id;
78 #ifdef CONFIG_SMP
79 
80  cpumask_t affinity;
81 #endif
82 #ifdef CONFIG_XENO_OPT_STATS
83  struct xnvfile_snapshot timer_vfile;
84  struct xnvfile_rev_tag timer_revtag;
85  struct list_head timerq;
86  int nrtimers;
87 #endif /* CONFIG_XENO_OPT_STATS */
88 #ifdef CONFIG_XENO_OPT_VFILE
89  struct xnvfile_regular vfile;
90 #endif
91 };
92 
93 extern struct xnclock nkclock;
94 
95 extern unsigned long nktimerlat;
96 
97 extern unsigned int nkclock_lock;
98 
99 int xnclock_register(struct xnclock *clock,
100  const cpumask_t *affinity);
101 
102 void xnclock_deregister(struct xnclock *clock);
103 
104 void xnclock_tick(struct xnclock *clock);
105 
106 void xnclock_adjust(struct xnclock *clock,
107  xnsticks_t delta);
108 
109 void xnclock_core_local_shot(struct xnsched *sched);
110 
111 void xnclock_core_remote_shot(struct xnsched *sched);
112 
113 xnsticks_t xnclock_core_ns_to_ticks(xnsticks_t ns);
114 
115 xnsticks_t xnclock_core_ticks_to_ns(xnsticks_t ticks);
116 
117 xnsticks_t xnclock_core_ticks_to_ns_rounded(xnsticks_t ticks);
118 
119 xnticks_t xnclock_core_read_monotonic(void);
120 
121 static inline xnticks_t xnclock_core_read_raw(void)
122 {
123  unsigned long long t;
124  ipipe_read_tsc(t);
125  return t;
126 }
127 
128 #ifdef CONFIG_XENO_OPT_EXTCLOCK
129 
130 static inline void xnclock_program_shot(struct xnclock *clock,
131  struct xnsched *sched)
132 {
133  if (likely(clock == &nkclock))
134  xnclock_core_local_shot(sched);
135  else if (clock->ops.program_local_shot)
136  clock->ops.program_local_shot(clock, sched);
137 }
138 
139 static inline void xnclock_remote_shot(struct xnclock *clock,
140  struct xnsched *sched)
141 {
142 #ifdef CONFIG_SMP
143  if (likely(clock == &nkclock))
144  xnclock_core_remote_shot(sched);
145  else if (clock->ops.program_remote_shot)
146  clock->ops.program_remote_shot(clock, sched);
147 #endif
148 }
149 
150 static inline xnticks_t xnclock_read_raw(struct xnclock *clock)
151 {
152  if (likely(clock == &nkclock))
153  return xnclock_core_read_raw();
154 
155  return clock->ops.read_raw(clock);
156 }
157 
158 static inline xnsticks_t xnclock_ns_to_ticks(struct xnclock *clock,
159  xnsticks_t ns)
160 {
161  if (likely(clock == &nkclock))
162  return xnclock_core_ns_to_ticks(ns);
163 
164  return clock->ops.ns_to_ticks(clock, ns);
165 }
166 
167 static inline xnsticks_t xnclock_ticks_to_ns(struct xnclock *clock,
168  xnsticks_t ticks)
169 {
170  if (likely(clock == &nkclock))
171  return xnclock_core_ticks_to_ns(ticks);
172 
173  return clock->ops.ticks_to_ns(clock, ticks);
174 }
175 
176 static inline xnsticks_t xnclock_ticks_to_ns_rounded(struct xnclock *clock,
177  xnsticks_t ticks)
178 {
179  if (likely(clock == &nkclock))
180  return xnclock_core_ticks_to_ns_rounded(ticks);
181 
182  return clock->ops.ticks_to_ns_rounded(clock, ticks);
183 }
184 
185 static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
186 {
187  if (likely(clock == &nkclock))
188  return xnclock_core_read_monotonic();
189 
190  return clock->ops.read_monotonic(clock);
191 }
192 
193 static inline int xnclock_set_time(struct xnclock *clock,
194  const struct timespec *ts)
195 {
196  if (likely(clock == &nkclock))
197  return -EINVAL;
198 
199  return clock->ops.set_time(clock, ts);
200 }
201 
202 #else /* !CONFIG_XENO_OPT_EXTCLOCK */
203 
204 static inline void xnclock_program_shot(struct xnclock *clock,
205  struct xnsched *sched)
206 {
207  xnclock_core_local_shot(sched);
208 }
209 
210 static inline void xnclock_remote_shot(struct xnclock *clock,
211  struct xnsched *sched)
212 {
213 #ifdef CONFIG_SMP
214  xnclock_core_remote_shot(sched);
215 #endif
216 }
217 
218 static inline xnticks_t xnclock_read_raw(struct xnclock *clock)
219 {
220  return xnclock_core_read_raw();
221 }
222 
223 static inline xnsticks_t xnclock_ns_to_ticks(struct xnclock *clock,
224  xnsticks_t ns)
225 {
226  return xnclock_core_ns_to_ticks(ns);
227 }
228 
229 static inline xnsticks_t xnclock_ticks_to_ns(struct xnclock *clock,
230  xnsticks_t ticks)
231 {
232  return xnclock_core_ticks_to_ns(ticks);
233 }
234 
235 static inline xnsticks_t xnclock_ticks_to_ns_rounded(struct xnclock *clock,
236  xnsticks_t ticks)
237 {
238  return xnclock_core_ticks_to_ns_rounded(ticks);
239 }
240 
241 static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
242 {
243  return xnclock_core_read_monotonic();
244 }
245 
246 static inline int xnclock_set_time(struct xnclock *clock,
247  const struct timespec *ts)
248 {
249  /*
250  * There is no way to change the core clock's idea of time.
251  */
252  return -EINVAL;
253 }
254 
255 #endif /* !CONFIG_XENO_OPT_EXTCLOCK */
256 
257 #ifdef CONFIG_SMP
258 int xnclock_get_default_cpu(struct xnclock *clock, int cpu);
259 #else
260 static inline int xnclock_get_default_cpu(struct xnclock *clock, int cpu)
261 {
262  return cpu;
263 }
264 #endif
265 
266 static inline xnticks_t xnclock_get_offset(struct xnclock *clock)
267 {
268  return clock->wallclock_offset;
269 }
270 
271 static inline xnticks_t xnclock_get_resolution(struct xnclock *clock)
272 {
273  return clock->resolution; /* ns */
274 }
275 
276 static inline void xnclock_set_resolution(struct xnclock *clock,
277  xnticks_t resolution)
278 {
279  clock->resolution = resolution; /* ns */
280 }
281 
282 static inline int xnclock_set_gravity(struct xnclock *clock,
283  const struct xnclock_gravity *gravity)
284 {
285  if (clock->ops.set_gravity)
286  return clock->ops.set_gravity(clock, gravity);
287 
288  return -EINVAL;
289 }
290 
291 static inline void xnclock_reset_gravity(struct xnclock *clock)
292 {
293  if (clock->ops.reset_gravity)
294  clock->ops.reset_gravity(clock);
295 }
296 
297 #define xnclock_get_gravity(__clock, __type) ((__clock)->gravity.__type)
298 
299 static inline xnticks_t xnclock_read_realtime(struct xnclock *clock)
300 {
301  /*
302  * Return an adjusted value of the monotonic time with the
303  * translated system wallclock offset.
304  */
305  return xnclock_read_monotonic(clock) + xnclock_get_offset(clock);
306 }
307 
308 unsigned long long xnclock_divrem_billion(unsigned long long value,
309  unsigned long *rem);
310 
311 xnticks_t xnclock_get_host_time(void);
312 
313 #ifdef CONFIG_XENO_OPT_VFILE
314 
315 void xnclock_init_proc(void);
316 
317 void xnclock_cleanup_proc(void);
318 
319 static inline void xnclock_print_status(struct xnclock *clock,
320  struct xnvfile_regular_iterator *it)
321 {
322  if (clock->ops.print_status)
323  clock->ops.print_status(clock, it);
324 }
325 
326 #else
327 static inline void xnclock_init_proc(void) { }
328 static inline void xnclock_cleanup_proc(void) { }
329 #endif
330 
331 void xnclock_update_freq(unsigned long long freq);
332 
333 int xnclock_init(unsigned long long freq);
334 
335 void xnclock_cleanup(void);
336 
339 #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:702
Scheduling information structure.
Definition: sched.h:57
Regular vfile iterator.
Definition: vfile.h:269
void xnclock_adjust(struct xnclock *clock, xnsticks_t delta)
Adjust a clock time.
Definition: clock.c:305
void xnclock_tick(struct xnclock *clock)
Process a clock tick.
Definition: clock.c:736
int xnclock_register(struct xnclock *clock, const cpumask_t *affinity)
Register a Xenomai clock.
Definition: clock.c:640
Snapshot vfile descriptor.
Definition: vfile.h:506