20 #ifndef _COBALT_KERNEL_TIMER_H
21 #define _COBALT_KERNEL_TIMER_H
23 #include <cobalt/kernel/clock.h>
24 #include <cobalt/kernel/stat.h>
25 #include <cobalt/kernel/list.h>
26 #include <cobalt/kernel/assert.h>
27 #include <cobalt/kernel/ancillaries.h>
28 #include <asm/xenomai/wrappers.h>
34 #define XN_INFINITE ((xnticks_t)0)
35 #define XN_NONBLOCK ((xnticks_t)-1)
38 typedef enum xntmode {
45 #define XNTIMER_DEQUEUED 0x00000001
46 #define XNTIMER_KILLED 0x00000002
47 #define XNTIMER_PERIODIC 0x00000004
48 #define XNTIMER_REALTIME 0x00000008
49 #define XNTIMER_FIRED 0x00000010
50 #define XNTIMER_NOBLCK 0x00000020
51 #define XNTIMER_RUNNING 0x00000040
52 #define XNTIMER_KGRAVITY 0x00000080
53 #define XNTIMER_UGRAVITY 0x00000100
54 #define XNTIMER_IGRAVITY 0
56 #define XNTIMER_GRAVITY_MASK (XNTIMER_KGRAVITY|XNTIMER_UGRAVITY)
57 #define XNTIMER_INIT_MASK (XNTIMER_GRAVITY_MASK|XNTIMER_NOBLCK)
59 #define __XNTIMER_CORE 0x10000000
62 #define XNTIMER_SPARE0 0x01000000
63 #define XNTIMER_SPARE1 0x02000000
64 #define XNTIMER_SPARE2 0x04000000
65 #define XNTIMER_SPARE3 0x08000000
66 #define XNTIMER_SPARE4 0x10000000
67 #define XNTIMER_SPARE5 0x20000000
68 #define XNTIMER_SPARE6 0x40000000
69 #define XNTIMER_SPARE7 0x80000000
72 #define XNTIMER_LOPRIO (-999999999)
73 #define XNTIMER_STDPRIO 0
74 #define XNTIMER_HIPRIO 999999999
77 struct list_head link;
82 #define xntlholder_date(h) ((h)->key)
83 #define xntlholder_prio(h) ((h)->prio)
84 #define xntlist_init(q) INIT_LIST_HEAD(q)
85 #define xntlist_empty(q) list_empty(q)
87 static inline struct xntlholder *xntlist_head(
struct list_head *q)
92 return list_first_entry(q,
struct xntlholder, link);
95 static inline struct xntlholder *xntlist_next(
struct list_head *q,
98 if (list_is_last(&h->link, q))
101 return list_entry(h->link.next,
struct xntlholder, link);
104 static inline struct xntlholder *xntlist_second(
struct list_head *q,
105 struct xntlholder *h)
107 return xntlist_next(q, h);
110 static inline void xntlist_insert(
struct list_head *q,
struct xntlholder *holder)
112 struct xntlholder *p;
115 list_add(&holder->link, q);
124 list_for_each_entry_reverse(p, q, link) {
125 if ((xnsticks_t) (holder->key - p->key) > 0 ||
126 (holder->key == p->key && holder->prio <= p->prio))
130 list_add(&holder->link, &p->link);
133 #define xntlist_remove(q, h) \
136 list_del(&(h)->link); \
139 #if defined(CONFIG_XENO_OPT_TIMER_RBTREE)
141 #include <linux/rbtree.h>
144 unsigned long long date;
149 #define xntimerh_date(h) ((h)->date)
150 #define xntimerh_prio(h) ((h)->prio)
151 #define xntimerh_init(h) do { } while (0)
158 #define xntimerq_init(q) \
160 xntimerq_t *_q = (q); \
161 _q->root = RB_ROOT; \
165 #define xntimerq_destroy(q) do { } while (0)
166 #define xntimerq_empty(q) ((q)->head != NULL)
168 #define xntimerq_head(q) ((q)->head)
170 #define xntimerq_next(q, h) \
172 struct rb_node *_node = rb_next(&(h)->link); \
173 _node ? (container_of(_node, xntimerh_t, link)) : NULL; \
176 #define xntimerq_second(q, h) xntimerq_next(q, h)
178 void xntimerq_insert(xntimerq_t *q, xntimerh_t *holder);
180 static inline void xntimerq_remove(xntimerq_t *q, xntimerh_t *holder)
182 if (holder == q->head)
183 q->head = xntimerq_second(q, holder);
185 rb_erase(&holder->link, &q->root);
188 typedef struct { } xntimerq_it_t;
190 #define xntimerq_it_begin(q,i) ((void) (i), xntimerq_head(q))
191 #define xntimerq_it_next(q,i,h) ((void) (i), xntimerq_next((q),(h)))
195 typedef struct xntlholder xntimerh_t;
197 #define xntimerh_date(h) xntlholder_date(h)
198 #define xntimerh_prio(h) xntlholder_prio(h)
199 #define xntimerh_init(h) do { } while (0)
201 typedef struct list_head xntimerq_t;
203 #define xntimerq_init(q) xntlist_init(q)
204 #define xntimerq_destroy(q) do { } while (0)
205 #define xntimerq_empty(q) xntlist_empty(q)
206 #define xntimerq_head(q) xntlist_head(q)
207 #define xntimerq_second(q, h) xntlist_second((q),(h))
208 #define xntimerq_insert(q, h) xntlist_insert((q),(h))
209 #define xntimerq_remove(q, h) xntlist_remove((q),(h))
211 typedef struct { } xntimerq_it_t;
213 #define xntimerq_it_begin(q,i) ((void) (i), xntlist_head(q))
214 #define xntimerq_it_next(q,i,h) ((void) (i), xntlist_next((q),(h)))
224 static inline struct xntimerdata *
225 xnclock_percpu_timerdata(
struct xnclock *clock,
int cpu)
227 return per_cpu_ptr(clock->timerdata, cpu);
230 static inline struct xntimerdata *
231 xnclock_this_timerdata(
struct xnclock *clock)
233 return raw_cpu_ptr(clock->timerdata);
237 #ifdef CONFIG_XENO_OPT_EXTCLOCK
238 struct xnclock *clock;
242 struct list_head adjlink;
244 unsigned long status;
248 xnticks_t interval_ns;
250 xnticks_t periodic_ticks;
252 xnticks_t start_date;
254 xnticks_t pexpect_ticks;
258 void (*handler)(
struct xntimer *timer);
259 #ifdef CONFIG_XENO_OPT_STATS
260 #ifdef CONFIG_XENO_OPT_EXTCLOCK
261 struct xnclock *tracker;
264 char name[XNOBJECT_NAME_LEN];
266 struct list_head next_stat;
268 xnstat_counter_t scheduled;
270 xnstat_counter_t fired;
274 #ifdef CONFIG_XENO_OPT_EXTCLOCK
276 static inline struct xnclock *xntimer_clock(
struct xntimer *timer)
281 void xntimer_set_clock(
struct xntimer *timer,
282 struct xnclock *newclock);
286 static inline struct xnclock *xntimer_clock(
struct xntimer *timer)
291 static inline void xntimer_set_clock(
struct xntimer *timer,
292 struct xnclock *newclock)
294 XENO_BUG_ON(COBALT, newclock != &nkclock);
300 static inline struct xnsched *xntimer_sched(
struct xntimer *timer)
305 #define xntimer_sched(t) xnsched_current()
308 #define xntimer_percpu_queue(__timer) \
310 struct xntimerdata *tmd; \
311 int cpu = xnsched_cpu((__timer)->sched); \
312 tmd = xnclock_percpu_timerdata(xntimer_clock(__timer), cpu); \
316 static inline xntimerq_t *xntimer_this_queue(
struct xntimer *timer)
318 struct xntimerdata *tmd;
320 tmd = xnclock_this_timerdata(xntimer_clock(timer));
325 static inline unsigned long xntimer_gravity(
struct xntimer *timer)
327 struct xnclock *clock = xntimer_clock(timer);
329 if (timer->status & XNTIMER_KGRAVITY)
330 return clock->gravity.kernel;
332 if (timer->status & XNTIMER_UGRAVITY)
333 return clock->gravity.user;
335 return clock->gravity.irq;
338 static inline void xntimer_update_date(
struct xntimer *timer)
340 xntimerh_date(&timer->aplink) = timer->start_date
341 + xnclock_ns_to_ticks(xntimer_clock(timer),
342 timer->periodic_ticks * timer->interval_ns)
343 - xntimer_gravity(timer);
346 static inline xnticks_t xntimer_pexpect(
struct xntimer *timer)
348 return timer->start_date +
349 xnclock_ns_to_ticks(xntimer_clock(timer),
350 timer->pexpect_ticks * timer->interval_ns);
353 static inline void xntimer_set_priority(
struct xntimer *timer,
356 xntimerh_prio(&timer->aplink) = prio;
359 static inline int xntimer_active_p(
struct xntimer *timer)
361 return timer->sched != NULL;
364 static inline int xntimer_running_p(
struct xntimer *timer)
366 return (timer->status & XNTIMER_RUNNING) != 0;
369 static inline int xntimer_fired_p(
struct xntimer *timer)
371 return (timer->status & XNTIMER_FIRED) != 0;
374 static inline int xntimer_periodic_p(
struct xntimer *timer)
376 return (timer->status & XNTIMER_PERIODIC) != 0;
379 void __xntimer_init(
struct xntimer *timer,
380 struct xnclock *clock,
381 void (*handler)(
struct xntimer *timer),
385 void xntimer_set_gravity(
struct xntimer *timer,
388 #ifdef CONFIG_XENO_OPT_STATS
390 #define xntimer_init(__timer, __clock, __handler, __sched, __flags) \
392 __xntimer_init(__timer, __clock, __handler, __sched, __flags); \
393 xntimer_set_name(__timer, #__handler); \
396 static inline void xntimer_reset_stats(
struct xntimer *timer)
398 xnstat_counter_set(&timer->scheduled, 0);
399 xnstat_counter_set(&timer->fired, 0);
402 static inline void xntimer_account_scheduled(
struct xntimer *timer)
404 xnstat_counter_inc(&timer->scheduled);
407 static inline void xntimer_account_fired(
struct xntimer *timer)
409 xnstat_counter_inc(&timer->fired);
412 static inline void xntimer_set_name(
struct xntimer *timer,
const char *name)
414 knamecpy(timer->name, name);
419 #define xntimer_init __xntimer_init
421 static inline void xntimer_reset_stats(
struct xntimer *timer) { }
423 static inline void xntimer_account_scheduled(
struct xntimer *timer) { }
425 static inline void xntimer_account_fired(
struct xntimer *timer) { }
427 static inline void xntimer_set_name(
struct xntimer *timer,
const char *name) { }
431 #if defined(CONFIG_XENO_OPT_EXTCLOCK) && defined(CONFIG_XENO_OPT_STATS)
432 void xntimer_switch_tracking(
struct xntimer *timer,
433 struct xnclock *newclock);
436 void xntimer_switch_tracking(
struct xntimer *timer,
437 struct xnclock *newclock) { }
459 return timer->interval_ns;
462 static inline xnticks_t xntimer_expiry(
struct xntimer *timer)
465 return xntimerh_date(&timer->aplink) + xntimer_gravity(timer);
473 void __xntimer_stop(
struct xntimer *timer);
477 xnticks_t __xntimer_get_timeout(
struct xntimer *timer);
479 xnticks_t xntimer_get_interval(
struct xntimer *timer);
481 int xntimer_heading_p(
struct xntimer *timer);
485 if (timer->status & XNTIMER_RUNNING)
486 __xntimer_stop(timer);
491 if (!xntimer_running_p(timer))
494 return __xntimer_get_timeout(timer);
497 static inline xnticks_t xntimer_get_timeout_stopped(
struct xntimer *timer)
499 return __xntimer_get_timeout(timer);
502 static inline void xntimer_enqueue(
struct xntimer *timer,
505 xntimerq_insert(q, &timer->aplink);
506 timer->status &= ~XNTIMER_DEQUEUED;
507 xntimer_account_scheduled(timer);
510 static inline void xntimer_dequeue(
struct xntimer *timer,
513 xntimerq_remove(q, &timer->aplink);
514 timer->status |= XNTIMER_DEQUEUED;
526 void xntimer_migrate(
struct xntimer *timer,
struct xnsched *sched)
528 if (timer->sched != sched)
532 int xntimer_setup_ipi(
void);
534 void xntimer_release_ipi(
void);
538 static inline void xntimer_migrate(
struct xntimer *timer,
542 static inline int xntimer_setup_ipi(
void)
547 static inline void xntimer_release_ipi(
void) { }
551 static inline void xntimer_set_sched(
struct xntimer *timer,
554 xntimer_migrate(timer, sched);
557 char *xntimer_format_time(xnticks_t ns,
558 char *buf,
size_t bufsz);
static xnticks_t xntimer_get_timeout(struct xntimer *timer)
Return the relative expiration date.
Definition: timer.h:489
xnticks_t xntimer_get_date(struct xntimer *timer)
Return the absolute expiration date.
Definition: timer.c:242
void __xntimer_migrate(struct xntimer *timer, struct xnsched *sched)
Migrate a timer.
Definition: timer.c:525
Scheduling information structure.
Definition: sched.h:57
int xntimer_start(struct xntimer *timer, xnticks_t value, xnticks_t interval, xntmode_t mode)
Arm a timer.
Definition: timer.c:113
void xntimer_destroy(struct xntimer *timer)
Release a timer object.
Definition: timer.c:491
unsigned long long xntimer_get_overruns(struct xntimer *timer, xnticks_t now)
Get the count of overruns for the last tick.
Definition: timer.c:590
void xntimer_release_hardware(void)
Release hardware timers.
Definition: timer.c:908
static xnticks_t xntimer_interval(struct xntimer *timer)
Return the timer interval value.
Definition: timer.h:457
static void xntimer_stop(struct xntimer *timer)
Disarm a timer.
Definition: timer.h:483
int xntimer_grab_hardware(void)
Grab the hardware timer on all real-time CPUs.
Definition: timer.c:811