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