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) 60 #define XNTIMER_SPARE0 0x01000000 61 #define XNTIMER_SPARE1 0x02000000 62 #define XNTIMER_SPARE2 0x04000000 63 #define XNTIMER_SPARE3 0x08000000 64 #define XNTIMER_SPARE4 0x10000000 65 #define XNTIMER_SPARE5 0x20000000 66 #define XNTIMER_SPARE6 0x40000000 67 #define XNTIMER_SPARE7 0x80000000 70 #define XNTIMER_LOPRIO (-999999999) 71 #define XNTIMER_STDPRIO 0 72 #define XNTIMER_HIPRIO 999999999 75 struct list_head link;
80 #define xntlholder_date(h) ((h)->key) 81 #define xntlholder_prio(h) ((h)->prio) 82 #define xntlist_init(q) INIT_LIST_HEAD(q) 83 #define xntlist_empty(q) list_empty(q) 85 static inline struct xntlholder *xntlist_head(
struct list_head *q)
90 return list_first_entry(q,
struct xntlholder, link);
93 static inline struct xntlholder *xntlist_next(
struct list_head *q,
96 if (list_is_last(&h->link, q))
99 return list_entry(h->link.next,
struct xntlholder, link);
102 static inline struct xntlholder *xntlist_second(
struct list_head *q,
103 struct xntlholder *h)
105 return xntlist_next(q, h);
108 static inline void xntlist_insert(
struct list_head *q,
struct xntlholder *holder)
110 struct xntlholder *p;
113 list_add(&holder->link, q);
122 list_for_each_entry_reverse(p, q, link) {
123 if ((xnsticks_t) (holder->key - p->key) > 0 ||
124 (holder->key == p->key && holder->prio <= p->prio))
128 list_add(&holder->link, &p->link);
131 #define xntlist_remove(q, h) \ 134 list_del(&(h)->link); \ 137 #if defined(CONFIG_XENO_OPT_TIMER_RBTREE) 139 #include <linux/rbtree.h> 142 unsigned long long date;
147 #define xntimerh_date(h) ((h)->date) 148 #define xntimerh_prio(h) ((h)->prio) 149 #define xntimerh_init(h) do { } while (0) 156 #define xntimerq_init(q) \ 158 xntimerq_t *_q = (q); \ 159 _q->root = RB_ROOT; \ 163 #define xntimerq_destroy(q) do { } while (0) 164 #define xntimerq_empty(q) ((q)->head == NULL) 166 #define xntimerq_head(q) ((q)->head) 168 #define xntimerq_next(q, h) \ 170 struct rb_node *_node = rb_next(&(h)->link); \ 171 _node ? (container_of(_node, xntimerh_t, link)) : NULL; \ 174 #define xntimerq_second(q, h) xntimerq_next(q, h) 176 void xntimerq_insert(xntimerq_t *q, xntimerh_t *holder);
178 static inline void xntimerq_remove(xntimerq_t *q, xntimerh_t *holder)
180 if (holder == q->head)
181 q->head = xntimerq_second(q, holder);
183 rb_erase(&holder->link, &q->root);
186 typedef struct { } xntimerq_it_t;
188 #define xntimerq_it_begin(q,i) ((void) (i), xntimerq_head(q)) 189 #define xntimerq_it_next(q,i,h) ((void) (i), xntimerq_next((q),(h))) 193 typedef struct xntlholder xntimerh_t;
195 #define xntimerh_date(h) xntlholder_date(h) 196 #define xntimerh_prio(h) xntlholder_prio(h) 197 #define xntimerh_init(h) do { } while (0) 199 typedef struct list_head xntimerq_t;
201 #define xntimerq_init(q) xntlist_init(q) 202 #define xntimerq_destroy(q) do { } while (0) 203 #define xntimerq_empty(q) xntlist_empty(q) 204 #define xntimerq_head(q) xntlist_head(q) 205 #define xntimerq_second(q, h) xntlist_second((q),(h)) 206 #define xntimerq_insert(q, h) xntlist_insert((q),(h)) 207 #define xntimerq_remove(q, h) xntlist_remove((q),(h)) 209 typedef struct { } xntimerq_it_t;
211 #define xntimerq_it_begin(q,i) ((void) (i), xntlist_head(q)) 212 #define xntimerq_it_next(q,i,h) ((void) (i), xntlist_next((q),(h))) 222 static inline struct xntimerdata *
223 xnclock_percpu_timerdata(
struct xnclock *clock,
int cpu)
225 return per_cpu_ptr(clock->timerdata, cpu);
228 static inline struct xntimerdata *
229 xnclock_this_timerdata(
struct xnclock *clock)
231 return raw_cpu_ptr(clock->timerdata);
235 #ifdef CONFIG_XENO_OPT_EXTCLOCK 236 struct xnclock *clock;
240 struct list_head adjlink;
242 unsigned long status;
246 xnticks_t interval_ns;
248 xnticks_t periodic_ticks;
250 xnticks_t start_date;
252 xnticks_t pexpect_ticks;
256 void (*handler)(
struct xntimer *timer);
257 #ifdef CONFIG_XENO_OPT_STATS 258 #ifdef CONFIG_XENO_OPT_EXTCLOCK 259 struct xnclock *tracker;
262 char name[XNOBJECT_NAME_LEN];
264 struct list_head next_stat;
266 xnstat_counter_t scheduled;
268 xnstat_counter_t fired;
272 #ifdef CONFIG_XENO_OPT_EXTCLOCK 274 static inline struct xnclock *xntimer_clock(
struct xntimer *timer)
279 void xntimer_set_clock(
struct xntimer *timer,
280 struct xnclock *newclock);
284 static inline struct xnclock *xntimer_clock(
struct xntimer *timer)
289 static inline void xntimer_set_clock(
struct xntimer *timer,
290 struct xnclock *newclock)
292 XENO_BUG_ON(COBALT, newclock != &nkclock);
298 static inline struct xnsched *xntimer_sched(
struct xntimer *timer)
303 #define xntimer_sched(t) xnsched_current() 306 #define xntimer_percpu_queue(__timer) \ 308 struct xntimerdata *tmd; \ 309 int cpu = xnsched_cpu((__timer)->sched); \ 310 tmd = xnclock_percpu_timerdata(xntimer_clock(__timer), cpu); \ 314 static inline unsigned long xntimer_gravity(
struct xntimer *timer)
316 struct xnclock *clock = xntimer_clock(timer);
318 if (timer->status & XNTIMER_KGRAVITY)
319 return clock->gravity.kernel;
321 if (timer->status & XNTIMER_UGRAVITY)
322 return clock->gravity.user;
324 return clock->gravity.irq;
327 static inline void xntimer_update_date(
struct xntimer *timer)
329 xntimerh_date(&timer->aplink) = timer->start_date
330 + xnclock_ns_to_ticks(xntimer_clock(timer),
331 timer->periodic_ticks * timer->interval_ns)
332 - xntimer_gravity(timer);
335 static inline xnticks_t xntimer_pexpect(
struct xntimer *timer)
337 return timer->start_date +
338 xnclock_ns_to_ticks(xntimer_clock(timer),
339 timer->pexpect_ticks * timer->interval_ns);
342 static inline void xntimer_set_priority(
struct xntimer *timer,
345 xntimerh_prio(&timer->aplink) = prio;
348 static inline int xntimer_active_p(
struct xntimer *timer)
350 return timer->sched != NULL;
353 static inline int xntimer_running_p(
struct xntimer *timer)
355 return (timer->status & XNTIMER_RUNNING) != 0;
358 static inline int xntimer_fired_p(
struct xntimer *timer)
360 return (timer->status & XNTIMER_FIRED) != 0;
363 static inline int xntimer_periodic_p(
struct xntimer *timer)
365 return (timer->status & XNTIMER_PERIODIC) != 0;
368 void __xntimer_init(
struct xntimer *timer,
369 struct xnclock *clock,
370 void (*handler)(
struct xntimer *timer),
374 void xntimer_set_gravity(
struct xntimer *timer,
377 #ifdef CONFIG_XENO_OPT_STATS 379 #define xntimer_init(__timer, __clock, __handler, __sched, __flags) \ 381 __xntimer_init(__timer, __clock, __handler, __sched, __flags); \ 382 xntimer_set_name(__timer, #__handler); \ 385 static inline void xntimer_reset_stats(
struct xntimer *timer)
387 xnstat_counter_set(&timer->scheduled, 0);
388 xnstat_counter_set(&timer->fired, 0);
391 static inline void xntimer_account_scheduled(
struct xntimer *timer)
393 xnstat_counter_inc(&timer->scheduled);
396 static inline void xntimer_account_fired(
struct xntimer *timer)
398 xnstat_counter_inc(&timer->fired);
401 static inline void xntimer_set_name(
struct xntimer *timer,
const char *name)
403 knamecpy(timer->name, name);
408 #define xntimer_init __xntimer_init 410 static inline void xntimer_reset_stats(
struct xntimer *timer) { }
412 static inline void xntimer_account_scheduled(
struct xntimer *timer) { }
414 static inline void xntimer_account_fired(
struct xntimer *timer) { }
416 static inline void xntimer_set_name(
struct xntimer *timer,
const char *name) { }
420 #if defined(CONFIG_XENO_OPT_EXTCLOCK) && defined(CONFIG_XENO_OPT_STATS) 421 void xntimer_switch_tracking(
struct xntimer *timer,
422 struct xnclock *newclock);
425 void xntimer_switch_tracking(
struct xntimer *timer,
426 struct xnclock *newclock) { }
448 return timer->interval_ns;
451 static inline xnticks_t xntimer_expiry(
struct xntimer *timer)
454 return xntimerh_date(&timer->aplink) + xntimer_gravity(timer);
462 void __xntimer_stop(
struct xntimer *timer);
466 xnticks_t __xntimer_get_timeout(
struct xntimer *timer);
468 xnticks_t xntimer_get_interval(
struct xntimer *timer);
470 int xntimer_heading_p(
struct xntimer *timer);
474 if (timer->status & XNTIMER_RUNNING)
475 __xntimer_stop(timer);
480 if (!xntimer_running_p(timer))
483 return __xntimer_get_timeout(timer);
486 static inline xnticks_t xntimer_get_timeout_stopped(
struct xntimer *timer)
488 return __xntimer_get_timeout(timer);
491 static inline void xntimer_enqueue(
struct xntimer *timer,
494 xntimerq_insert(q, &timer->aplink);
495 timer->status &= ~XNTIMER_DEQUEUED;
496 xntimer_account_scheduled(timer);
499 static inline void xntimer_dequeue(
struct xntimer *timer,
502 xntimerq_remove(q, &timer->aplink);
503 timer->status |= XNTIMER_DEQUEUED;
515 void xntimer_migrate(
struct xntimer *timer,
struct xnsched *sched)
517 if (timer->sched != sched)
521 int xntimer_setup_ipi(
void);
523 void xntimer_release_ipi(
void);
525 bool xntimer_set_sched(
struct xntimer *timer,
530 static inline void xntimer_migrate(
struct xntimer *timer,
534 static inline int xntimer_setup_ipi(
void)
539 static inline void xntimer_release_ipi(
void) { }
541 static inline bool xntimer_set_sched(
struct xntimer *timer,
549 char *xntimer_format_time(xnticks_t ns,
550 char *buf,
size_t bufsz);
static xnticks_t xntimer_get_timeout(struct xntimer *timer)
Return the relative expiration date.
Definition: timer.h:478
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:514
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:480
unsigned long long xntimer_get_overruns(struct xntimer *timer, xnticks_t now)
Get the count of overruns for the last tick.
Definition: timer.c:601
void xntimer_release_hardware(void)
Release hardware timers.
Definition: timer.c:918
static xnticks_t xntimer_interval(struct xntimer *timer)
Return the timer interval value.
Definition: timer.h:446
static void xntimer_stop(struct xntimer *timer)
Disarm a timer.
Definition: timer.h:472
int xntimer_grab_hardware(void)
Grab the hardware timer on all real-time CPUs.
Definition: timer.c:821