23 #ifndef _XENO_NUCLEUS_TIMER_H
24 #define _XENO_NUCLEUS_TIMER_H
27 #include <nucleus/stat.h>
29 #if defined(__KERNEL__) || defined(__XENO_SIM__)
31 #ifndef CONFIG_XENO_OPT_DEBUG_TIMERS
32 #define CONFIG_XENO_OPT_DEBUG_TIMERS 0
35 #define XNTIMER_WHEELSIZE 64
36 #define XNTIMER_WHEELMASK (XNTIMER_WHEELSIZE - 1)
39 #define XNTIMER_DEQUEUED 0x00000001
40 #define XNTIMER_KILLED 0x00000002
41 #define XNTIMER_PERIODIC 0x00000004
42 #define XNTIMER_REALTIME 0x00000008
43 #define XNTIMER_FIRED 0x00000010
44 #define XNTIMER_NOBLCK 0x00000020
47 #define XNTIMER_SPARE0 0x01000000
48 #define XNTIMER_SPARE1 0x02000000
49 #define XNTIMER_SPARE2 0x04000000
50 #define XNTIMER_SPARE3 0x08000000
51 #define XNTIMER_SPARE4 0x10000000
52 #define XNTIMER_SPARE5 0x20000000
53 #define XNTIMER_SPARE6 0x40000000
54 #define XNTIMER_SPARE7 0x80000000
57 #define XNTIMER_LOPRIO (-999999999)
58 #define XNTIMER_STDPRIO 0
59 #define XNTIMER_HIPRIO 999999999
61 #define XNTIMER_KEEPER_ID 0
68 #define link2tlholder(ln) container_of(ln, xntlholder_t, link)
72 #define xntlholder_date(h) ((h)->key)
73 #define xntlholder_prio(h) ((h)->prio)
74 #define xntlholder_init(h) inith(&(h)->link)
75 #define xntlist_init(q) initq(q)
76 #define xntlist_head(q) \
77 ({ xnholder_t *_h = getheadq(q); \
78 !_h ? NULL : link2tlholder(_h); \
81 #define xntlist_next(q, h) \
82 ({ xnholder_t *_h = nextq(q, &(h)->link); \
83 !_h ? NULL : link2tlholder(_h); \
86 #define xntlist_second(q, h) xntlist_next((q),(h))
88 static inline void xntlist_insert(xnqueue_t *q, xntlholder_t *holder)
97 for (p = q->head.last; p != &q->head; p = p->last)
98 if ((xnsticks_t) (holder->key - link2tlholder(p)->key) > 0 ||
99 (holder->key == link2tlholder(p)->key &&
100 holder->prio <= link2tlholder(p)->prio))
103 insertq(q,p->next,&holder->link);
106 #define xntlist_remove(q, h) removeq((q),&(h)->link)
108 #if defined(CONFIG_XENO_OPT_TIMER_RBTREE)
110 #include <linux/rbtree.h>
113 unsigned long long date;
118 #define xntimerh_date(h) ((h)->date)
119 #define xntimerh_prio(h) ((h)->prio)
120 #define xntimerh_init(h) do { } while (0)
127 #define xntimerq_init(q) \
129 xntimerq_t *_q = (q); \
130 _q->root = RB_ROOT; \
134 #define xntimerq_destroy(q) do { } while (0)
135 #define xntimerq_empty(q) ((q)->head != NULL)
137 #define xntimerq_head(q) ((q)->head)
139 #define xntimerq_next(q, h) \
141 struct rb_node *_node = rb_next(&(h)->link); \
142 _node ? (container_of(_node, xntimerh_t, link)) : NULL; \
145 #define xntimerq_second(q, h) xntimerq_next(q, h)
147 void xntimerq_insert(xntimerq_t *q, xntimerh_t *holder);
149 static inline void xntimerq_remove(xntimerq_t *q, xntimerh_t *holder)
151 if (holder == q->head)
152 q->head = xntimerq_second(q, holder);
154 rb_erase(&holder->link, &q->root);
157 typedef struct { } xntimerq_it_t;
159 #define xntimerq_it_begin(q,i) ((void) (i), xntimerq_head(q))
160 #define xntimerq_it_next(q,i,h) ((void) (i), xntimerq_next((q),(h)))
164 typedef xntlholder_t xntimerh_t;
166 #define xntimerh_date(h) xntlholder_date(h)
167 #define xntimerh_prio(h) xntlholder_prio(h)
168 #define xntimerh_init(h) xntlholder_init(h)
170 typedef xnqueue_t xntimerq_t;
172 #define xntimerq_init(q) xntlist_init(q)
173 #define xntimerq_destroy(q) do { } while (0)
174 #define xntimerq_head(q) xntlist_head(q)
175 #define xntimerq_second(q,h) xntlist_second((q),(h))
176 #define xntimerq_insert(q,h) xntlist_insert((q),(h))
177 #define xntimerq_remove(q, h) xntlist_remove((q),(h))
179 typedef struct {} xntimerq_it_t;
181 #define xntimerq_it_begin(q,i) ((void) (i), xntlist_head(q))
182 #define xntimerq_it_next(q,i,h) ((void) (i), xntlist_next((q),(h)))
188 typedef struct xntimer {
192 #define aplink2timer(ln) container_of(ln, xntimer_t, aplink)
194 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
199 #define plink2timer(ln) container_of(ln, xntimer_t, plink)
204 #define adjlink2timer(ln) container_of(ln, xntimer_t, adjlink)
215 void (*handler)(
struct xntimer *timer);
217 #ifdef CONFIG_XENO_OPT_STATS
218 char name[XNOBJECT_NAME_LEN];
220 const char *handler_name;
224 #define tblink2timer(ln) container_of(ln, xntimer_t, tblink)
227 xnstat_counter_t scheduled;
229 xnstat_counter_t fired;
231 XNARCH_DECL_DISPLAY_CONTEXT();
235 typedef struct xntimed_slave {
239 struct percpu_cascade {
241 xnqueue_t wheel[XNTIMER_WHEELSIZE];
242 } cascade[XNARCH_NR_CPUS];
244 #define timer2slave(t) \
245 ((xntslave_t *)(((char *)t) - offsetof(xntslave_t, cascade[xnsched_cpu((t)->sched)].timer)))
246 #define base2slave(b) \
247 ((xntslave_t *)(((char *)b) - offsetof(xntslave_t, base)))
252 #define xntimer_sched(t) ((t)->sched)
254 #define xntimer_sched(t) xnpod_current_sched()
256 #define xntimer_interval(t) ((t)->interval)
257 #define xntimer_pexpect(t) ((t)->pexpect)
258 #define xntimer_pexpect_forward(t,delta) ((t)->pexpect += delta)
260 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
261 #define xntimer_base(t) ((t)->base)
262 #define xntimer_set_priority(t,p) \
264 xntimer_t *_t = (t); \
265 unsigned prio = (p); \
266 xntimerh_prio(&(_t)->aplink) = prio; \
267 xntlholder_prio(&(_t)->plink) = prio; \
270 #define xntimer_base(t) (&nktbase)
271 #define xntimer_set_priority(t,p) \
272 do { xntimerh_prio(&(t)->aplink) = (p); } while(0)
275 static inline int xntimer_active_p (xntimer_t *timer)
277 return timer->sched != NULL;
280 static inline int xntimer_running_p(xntimer_t *timer)
282 return !testbits(timer->status,XNTIMER_DEQUEUED);
285 static inline int xntimer_reload_p(xntimer_t *timer)
287 return testbits(timer->status,
288 XNTIMER_PERIODIC|XNTIMER_DEQUEUED|XNTIMER_KILLED) ==
289 (XNTIMER_PERIODIC|XNTIMER_DEQUEUED);
296 extern xntbops_t nktimer_ops_aperiodic,
297 nktimer_ops_periodic;
299 #ifdef CONFIG_XENO_OPT_STATS
300 #define xntimer_init(timer, base, handler) \
302 __xntimer_init(timer, base, handler); \
303 (timer)->handler_name = #handler; \
306 #define xntimer_init __xntimer_init
309 #define xntimer_init_noblock(timer, base, handler) \
311 xntimer_init(timer, base, handler); \
312 (timer)->status |= XNTIMER_NOBLCK; \
315 void __xntimer_init(
struct xntimer *timer,
316 struct xntbase *base,
317 void (*handler)(
struct xntimer *timer));
321 static inline void xntimer_set_name(xntimer_t *timer,
const char *name)
323 #ifdef CONFIG_XENO_OPT_STATS
324 strncpy(timer->name, name,
sizeof(timer->name));
328 void xntimer_next_local_shot(
struct xnsched *sched);
334 #if defined(CONFIG_XENO_OPT_TIMING_PERIODIC) || defined(DOXYGEN_CPP)
389 xnticks_t value, xnticks_t interval,
392 return timer->base->ops->start_timer(timer, value, interval, mode);
426 if (!testbits(timer->status,XNTIMER_DEQUEUED))
427 timer->base->ops->stop_timer(timer);
464 if (!xntimer_running_p(timer))
467 return timer->base->ops->get_timer_date(timer);
506 if (!xntimer_running_p(timer))
509 return timer->base->ops->get_timer_timeout(timer);
512 static inline xnticks_t xntimer_get_timeout_stopped(xntimer_t *timer)
514 return timer->base->ops->get_timer_timeout(timer);
550 return timer->base->ops->get_timer_interval(timer);
553 static inline xnticks_t xntimer_get_raw_expiry (xntimer_t *timer)
555 return timer->base->ops->get_timer_raw_expiry(timer);
558 void xntslave_init(xntslave_t *slave);
560 void xntslave_destroy(xntslave_t *slave);
562 void xntslave_update(xntslave_t *slave,
565 void xntslave_start(xntslave_t *slave,
569 void xntslave_stop(xntslave_t *slave);
571 void xntslave_adjust(xntslave_t *slave, xnsticks_t delta);
575 int xntimer_start_aperiodic(xntimer_t *timer,
580 void xntimer_stop_aperiodic(xntimer_t *timer);
582 xnticks_t xntimer_get_date_aperiodic(xntimer_t *timer);
584 xnticks_t xntimer_get_timeout_aperiodic(xntimer_t *timer);
586 xnticks_t xntimer_get_interval_aperiodic(xntimer_t *timer);
588 xnticks_t xntimer_get_raw_expiry_aperiodic(xntimer_t *timer);
591 xnticks_t value, xnticks_t interval,
594 return xntimer_start_aperiodic(timer, value, interval, mode);
599 if (!testbits(timer->status,XNTIMER_DEQUEUED))
600 xntimer_stop_aperiodic(timer);
605 if (!xntimer_running_p(timer))
608 return xntimer_get_date_aperiodic(timer);
613 if (!xntimer_running_p(timer))
616 return xntimer_get_timeout_aperiodic(timer);
619 static inline xnticks_t xntimer_get_timeout_stopped(xntimer_t *timer)
621 return xntimer_get_timeout_aperiodic(timer);
626 return xntimer_get_interval_aperiodic(timer);
629 static inline xnticks_t xntimer_get_raw_expiry (xntimer_t *timer)
631 return xntimerh_date(&timer->aplink);
638 void xntimer_init_proc(
void);
640 void xntimer_cleanup_proc(
void);
650 void xntimer_tick_periodic_inner(xntslave_t *slave);
652 void xntimer_adjust_all_aperiodic(xnsticks_t delta);
655 int xntimer_migrate(xntimer_t *timer,
658 #define xntimer_migrate(timer, sched) do { } while(0)
661 #define xntimer_set_sched(timer, sched) xntimer_migrate(timer, sched)
663 char *xntimer_format_time(xnticks_t value,
int periodic,
664 char *buf,
size_t bufsz);
void xntimer_tick_aperiodic(void)
Process a timer tick for the aperiodic master time base.
Definition: timer.c:339
void xntimer_tick_periodic(xntimer_t *timer)
Process a timer tick for a slave periodic time base.
Definition: timer.c:606
static xnticks_t xntimer_get_interval(xntimer_t *timer)
Return the timer interval value.
Definition: timer.h:548
void xntimer_destroy(xntimer_t *timer)
Release a timer object.
Definition: timer.c:908
static xnticks_t xntimer_get_date(xntimer_t *timer)
Return the absolute expiration date.
Definition: timer.h:462
Scheduling information structure.
Definition: sched.h:66
static void xntimer_stop(xntimer_t *timer)
Disarm a timer.
Definition: timer.h:420
void xntimer_freeze(void)
Freeze all timers (from every time bases).
Definition: timer.c:1042
static int xntimer_start(xntimer_t *timer, xnticks_t value, xnticks_t interval, xntmode_t mode)
Arm a timer.
Definition: timer.h:388
unsigned long xntimer_get_overruns(xntimer_t *timer, xnticks_t now)
Get the count of overruns for the last tick.
Definition: timer.c:1007
static xnticks_t xntimer_get_timeout(xntimer_t *timer)
Return the relative expiration date.
Definition: timer.h:504