Xenomai 3.3.2
Loading...
Searching...
No Matches
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 <pipeline/pipeline.h>
23#include <pipeline/clock.h>
24#include <cobalt/kernel/list.h>
25#include <cobalt/kernel/vfile.h>
26#include <cobalt/uapi/kernel/types.h>
27#include <asm/xenomai/wrappers.h>
28
34struct xnsched;
35struct xntimerdata;
36struct __kernel_timex;
37
38struct xnclock_gravity {
39 unsigned long irq;
40 unsigned long kernel;
41 unsigned long user;
42};
43
44struct xnclock {
46 xnsticks_t wallclock_offset;
48 xnticks_t resolution;
50 struct xnclock_gravity gravity;
52 const char *name;
53 struct {
54#ifdef CONFIG_XENO_OPT_EXTCLOCK
55 xnticks_t (*read_raw)(struct xnclock *clock);
56 xnticks_t (*read_monotonic)(struct xnclock *clock);
57 int (*set_time)(struct xnclock *clock,
58 const struct timespec64 *ts);
59 xnsticks_t (*ns_to_ticks)(struct xnclock *clock,
60 xnsticks_t ns);
61 xnsticks_t (*ticks_to_ns)(struct xnclock *clock,
62 xnsticks_t ticks);
63 xnsticks_t (*ticks_to_ns_rounded)(struct xnclock *clock,
64 xnsticks_t ticks);
65 void (*program_local_shot)(struct xnclock *clock,
66 struct xnsched *sched);
67 void (*program_remote_shot)(struct xnclock *clock,
68 struct xnsched *sched);
69#endif
70 int (*adjust_time)(struct xnclock *clock,
71 struct __kernel_timex *tx);
72 int (*set_gravity)(struct xnclock *clock,
73 const struct xnclock_gravity *p);
74 void (*reset_gravity)(struct xnclock *clock);
75#ifdef CONFIG_XENO_OPT_VFILE
76 void (*print_status)(struct xnclock *clock,
77 struct xnvfile_regular_iterator *it);
78#endif
79 } ops;
80 /* Private section. */
81 struct xntimerdata __percpu *timerdata;
82 int id;
83#ifdef CONFIG_SMP
85 cpumask_t affinity;
86#endif
87#ifdef CONFIG_XENO_OPT_STATS
88 struct xnvfile_snapshot timer_vfile;
89 struct xnvfile_rev_tag timer_revtag;
90 struct list_head timerq;
91 int nrtimers;
92#endif /* CONFIG_XENO_OPT_STATS */
93#ifdef CONFIG_XENO_OPT_VFILE
94 struct xnvfile_regular vfile;
95#endif
96};
97
98struct xnclock_ratelimit_state {
99 xnticks_t interval;
100 xnticks_t begin;
101 int burst;
102 int printed;
103 int missed;
104};
105
106extern struct xnclock nkclock;
107
108int xnclock_register(struct xnclock *clock,
109 const cpumask_t *affinity);
110
111void xnclock_deregister(struct xnclock *clock);
112
113void xnclock_tick(struct xnclock *clock);
114
115void xnclock_core_local_shot(struct xnsched *sched);
116
117void xnclock_core_remote_shot(struct xnsched *sched);
118
119xnsticks_t xnclock_core_ns_to_ticks(xnsticks_t ns);
120
121xnsticks_t xnclock_core_ticks_to_ns(xnsticks_t ticks);
122
123xnsticks_t xnclock_core_ticks_to_ns_rounded(xnsticks_t ticks);
124
125xnticks_t xnclock_core_read_monotonic(void);
126
127static inline xnticks_t xnclock_core_read_raw(void)
128{
129 return pipeline_read_cycle_counter();
130}
131
132/* We use the Linux defaults */
133#define XN_RATELIMIT_INTERVAL 5000000000LL
134#define XN_RATELIMIT_BURST 10
135
136int __xnclock_ratelimit(struct xnclock_ratelimit_state *rs, const char *func);
137
138#define xnclock_ratelimit() ({ \
139 static struct xnclock_ratelimit_state __state = { \
140 .interval = XN_RATELIMIT_INTERVAL, \
141 .burst = XN_RATELIMIT_BURST, \
142 }; \
143 __xnclock_ratelimit(&__state, __func__); \
144})
145
146#ifdef CONFIG_XENO_OPT_EXTCLOCK
147
148static inline void xnclock_program_shot(struct xnclock *clock,
149 struct xnsched *sched)
150{
151 if (likely(clock == &nkclock))
152 xnclock_core_local_shot(sched);
153 else if (clock->ops.program_local_shot)
154 clock->ops.program_local_shot(clock, sched);
155}
156
157static inline void xnclock_remote_shot(struct xnclock *clock,
158 struct xnsched *sched)
159{
160#ifdef CONFIG_SMP
161 if (likely(clock == &nkclock))
162 xnclock_core_remote_shot(sched);
163 else if (clock->ops.program_remote_shot)
164 clock->ops.program_remote_shot(clock, sched);
165#endif
166}
167
168static inline xnticks_t xnclock_read_raw(struct xnclock *clock)
169{
170 if (likely(clock == &nkclock))
171 return xnclock_core_read_raw();
172
173 return clock->ops.read_raw(clock);
174}
175
176static inline xnsticks_t xnclock_ns_to_ticks(struct xnclock *clock,
177 xnsticks_t ns)
178{
179 if (likely(clock == &nkclock))
180 return xnclock_core_ns_to_ticks(ns);
181
182 return clock->ops.ns_to_ticks(clock, ns);
183}
184
185static inline xnsticks_t xnclock_ticks_to_ns(struct xnclock *clock,
186 xnsticks_t ticks)
187{
188 if (likely(clock == &nkclock))
189 return xnclock_core_ticks_to_ns(ticks);
190
191 return clock->ops.ticks_to_ns(clock, ticks);
192}
193
194static inline xnsticks_t xnclock_ticks_to_ns_rounded(struct xnclock *clock,
195 xnsticks_t ticks)
196{
197 if (likely(clock == &nkclock))
198 return xnclock_core_ticks_to_ns_rounded(ticks);
199
200 return clock->ops.ticks_to_ns_rounded(clock, ticks);
201}
202
203static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
204{
205 if (likely(clock == &nkclock))
206 return xnclock_core_read_monotonic();
207
208 return clock->ops.read_monotonic(clock);
209}
210
211static inline int xnclock_set_time(struct xnclock *clock,
212 const struct timespec64 *ts)
213{
214 if (likely(clock == &nkclock))
215 return -EINVAL;
216
217 return clock->ops.set_time(clock, ts);
218}
219
220#else /* !CONFIG_XENO_OPT_EXTCLOCK */
221
222static inline void xnclock_program_shot(struct xnclock *clock,
223 struct xnsched *sched)
224{
225 xnclock_core_local_shot(sched);
226}
227
228static inline void xnclock_remote_shot(struct xnclock *clock,
229 struct xnsched *sched)
230{
231#ifdef CONFIG_SMP
232 xnclock_core_remote_shot(sched);
233#endif
234}
235
236static inline xnticks_t xnclock_read_raw(struct xnclock *clock)
237{
238 return xnclock_core_read_raw();
239}
240
241static inline xnsticks_t xnclock_ns_to_ticks(struct xnclock *clock,
242 xnsticks_t ns)
243{
244 return xnclock_core_ns_to_ticks(ns);
245}
246
247static inline xnsticks_t xnclock_ticks_to_ns(struct xnclock *clock,
248 xnsticks_t ticks)
249{
250 return xnclock_core_ticks_to_ns(ticks);
251}
252
253static inline xnsticks_t xnclock_ticks_to_ns_rounded(struct xnclock *clock,
254 xnsticks_t ticks)
255{
256 return xnclock_core_ticks_to_ns_rounded(ticks);
257}
258
259static inline xnticks_t xnclock_read_monotonic(struct xnclock *clock)
260{
261 return xnclock_core_read_monotonic();
262}
263
264static inline int xnclock_set_time(struct xnclock *clock,
265 const struct timespec64 *ts)
266{
267 /*
268 * There is no way to change the core clock's idea of time.
269 */
270 return -EINVAL;
271}
272
273#endif /* !CONFIG_XENO_OPT_EXTCLOCK */
274
275static inline int xnclock_adjust_time(struct xnclock *clock,
276 struct __kernel_timex *tx)
277{
278 if (clock->ops.adjust_time == NULL)
279 return -EOPNOTSUPP;
280
281 return clock->ops.adjust_time(clock, tx);
282}
283
284static inline xnticks_t xnclock_get_offset(struct xnclock *clock)
285{
286 return clock->wallclock_offset;
287}
288
289static inline xnticks_t xnclock_get_resolution(struct xnclock *clock)
290{
291 return clock->resolution; /* ns */
292}
293
294static inline void xnclock_set_resolution(struct xnclock *clock,
295 xnticks_t resolution)
296{
297 clock->resolution = resolution; /* ns */
298}
299
300static inline int xnclock_set_gravity(struct xnclock *clock,
301 const struct xnclock_gravity *gravity)
302{
303 if (clock->ops.set_gravity)
304 return clock->ops.set_gravity(clock, gravity);
305
306 return -EINVAL;
307}
308
309static inline void xnclock_reset_gravity(struct xnclock *clock)
310{
311 if (clock->ops.reset_gravity)
312 clock->ops.reset_gravity(clock);
313}
314
315#define xnclock_get_gravity(__clock, __type) ((__clock)->gravity.__type)
316
317static inline xnticks_t xnclock_read_realtime(struct xnclock *clock)
318{
319 if (likely(clock == &nkclock))
320 return pipeline_read_wallclock();
321 /*
322 * Return an adjusted value of the monotonic time with the
323 * translated system wallclock offset.
324 */
325 return xnclock_read_monotonic(clock) + xnclock_get_offset(clock);
326}
327
328void xnclock_apply_offset(struct xnclock *clock,
329 xnsticks_t delta_ns);
330
331void xnclock_set_wallclock(xnticks_t epoch_ns);
332
333unsigned long long xnclock_divrem_billion(unsigned long long value,
334 unsigned long *rem);
335
336#ifdef CONFIG_XENO_OPT_VFILE
337
338void xnclock_init_proc(void);
339
340void xnclock_cleanup_proc(void);
341
342static inline void xnclock_print_status(struct xnclock *clock,
343 struct xnvfile_regular_iterator *it)
344{
345 if (clock->ops.print_status)
346 clock->ops.print_status(clock, it);
347}
348
349#else
350static inline void xnclock_init_proc(void) { }
351static inline void xnclock_cleanup_proc(void) { }
352#endif
353
354int xnclock_init(void);
355
356void xnclock_cleanup(void);
357
360#endif /* !_COBALT_KERNEL_CLOCK_H */
void xnclock_tick(struct xnclock *clock)
Process a clock tick.
Definition clock.c:681
void xnclock_deregister(struct xnclock *clock)
Deregister a Xenomai clock.
Definition clock.c:647
int xnclock_register(struct xnclock *clock, const cpumask_t *affinity)
Register a Xenomai clock.
Definition clock.c:584
Scheduling information structure.
Definition sched.h:64
Regular vfile iterator .
Definition vfile.h:270
Snapshot revision tag .
Definition vfile.h:483
Snapshot vfile descriptor .
Definition vfile.h:507