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/ancillaries.h>
32 #define XN_INFINITE ((xnticks_t)0)
33 #define XN_NONBLOCK ((xnticks_t)-1)
36 typedef enum xntmode {
43 #define XNTIMER_DEQUEUED 0x00000001
44 #define XNTIMER_KILLED 0x00000002
45 #define XNTIMER_PERIODIC 0x00000004
46 #define XNTIMER_REALTIME 0x00000008
47 #define XNTIMER_FIRED 0x00000010
48 #define XNTIMER_NOBLCK 0x00000020
49 #define XNTIMER_RUNNING 0x00000040
50 #define XNTIMER_KGRAVITY 0x00000080
51 #define XNTIMER_UGRAVITY 0x00000100
52 #define XNTIMER_IGRAVITY 0
54 #define XNTIMER_GRAVITY_MASK (XNTIMER_KGRAVITY|XNTIMER_UGRAVITY)
55 #define XNTIMER_INIT_MASK (XNTIMER_GRAVITY_MASK|XNTIMER_NOBLCK)
58 #define XNTIMER_SPARE0 0x01000000
59 #define XNTIMER_SPARE1 0x02000000
60 #define XNTIMER_SPARE2 0x04000000
61 #define XNTIMER_SPARE3 0x08000000
62 #define XNTIMER_SPARE4 0x10000000
63 #define XNTIMER_SPARE5 0x20000000
64 #define XNTIMER_SPARE6 0x40000000
65 #define XNTIMER_SPARE7 0x80000000
68 #define XNTIMER_LOPRIO (-999999999)
69 #define XNTIMER_STDPRIO 0
70 #define XNTIMER_HIPRIO 999999999
73 struct list_head link;
78 #define xntlholder_date(h) ((h)->key)
79 #define xntlholder_prio(h) ((h)->prio)
80 #define xntlist_init(q) INIT_LIST_HEAD(q)
81 #define xntlist_empty(q) list_empty(q)
82 #define xntlist_head(q) \
84 struct xntlholder *h = list_empty(q) ? NULL : \
85 list_first_entry(q, struct xntlholder, link); \
89 #define xntlist_next(q, h) \
91 struct xntlholder *_h = list_is_last(&h->link, q) ? NULL : \
92 list_entry(h->link.next, struct xntlholder, link); \
96 static inline void xntlist_insert(
struct list_head *q,
struct xntlholder *holder)
101 list_add(&holder->link, q);
110 list_for_each_entry_reverse(p, q, link) {
111 if ((xnsticks_t) (holder->key - p->key) > 0 ||
112 (holder->key == p->key && holder->prio <= p->prio))
116 list_add(&holder->link, &p->link);
119 #define xntlist_remove(q, h) \
122 list_del(&(h)->link); \
125 #if defined(CONFIG_XENO_OPT_TIMER_HEAP)
127 #include <cobalt/kernel/bheap.h>
129 typedef bheaph_t xntimerh_t;
131 #define xntimerh_date(h) bheaph_key(h)
132 #define xntimerh_prio(h) bheaph_prio(h)
133 #define xntimerh_init(h) bheaph_init(h)
135 typedef DECLARE_BHEAP_CONTAINER(xntimerq_t, CONFIG_XENO_OPT_TIMER_HEAP_CAPACITY);
137 #define xntimerq_init(q) bheap_init((q), CONFIG_XENO_OPT_TIMER_HEAP_CAPACITY)
138 #define xntimerq_destroy(q) bheap_destroy(q)
139 #define xntimerq_empty(q) bheap_empty(q)
140 #define xntimerq_head(q) bheap_gethead(q)
141 #define xntimerq_insert(q, h) bheap_insert((q),(h))
142 #define xntimerq_remove(q, h) bheap_delete((q),(h))
144 typedef struct {} xntimerq_it_t;
146 #define xntimerq_it_begin(q, i) ((void) (i), bheap_gethead(q))
147 #define xntimerq_it_next(q, i, h) ((void) (i), bheap_next((q),(h)))
151 typedef struct xntlholder xntimerh_t;
153 #define xntimerh_date(h) xntlholder_date(h)
154 #define xntimerh_prio(h) xntlholder_prio(h)
155 #define xntimerh_init(h) do { } while (0)
157 typedef struct list_head xntimerq_t;
159 #define xntimerq_init(q) xntlist_init(q)
160 #define xntimerq_destroy(q) do { } while (0)
161 #define xntimerq_empty(q) xntlist_empty(q)
162 #define xntimerq_head(q) xntlist_head(q)
163 #define xntimerq_insert(q,h) xntlist_insert((q),(h))
164 #define xntimerq_remove(q, h) xntlist_remove((q),(h))
166 typedef struct { } xntimerq_it_t;
168 #define xntimerq_it_begin(q,i) ((void) (i), xntlist_head(q))
169 #define xntimerq_it_next(q,i,h) ((void) (i), xntlist_next((q),(h)))
179 static inline struct xntimerdata *
180 xnclock_percpu_timerdata(
struct xnclock *clock,
int cpu)
182 return per_cpu_ptr(clock->timerdata, cpu);
185 static inline struct xntimerdata *
186 xnclock_this_timerdata(
struct xnclock *clock)
188 return __this_cpu_ptr(clock->timerdata);
192 #ifdef CONFIG_XENO_OPT_EXTCLOCK
193 struct xnclock *clock;
197 struct list_head adjlink;
199 unsigned long status;
203 xnticks_t interval_ns;
205 xnticks_t periodic_ticks;
207 xnticks_t start_date;
209 xnticks_t pexpect_ticks;
213 void (*handler)(
struct xntimer *timer);
214 #ifdef CONFIG_XENO_OPT_STATS
215 #ifdef CONFIG_XENO_OPT_EXTCLOCK
216 struct xnclock *tracker;
219 char name[XNOBJECT_NAME_LEN];
221 struct list_head next_stat;
223 xnstat_counter_t scheduled;
225 xnstat_counter_t fired;
229 #ifdef CONFIG_XENO_OPT_EXTCLOCK
231 static inline struct xnclock *xntimer_clock(
struct xntimer *timer)
238 static inline struct xnclock *xntimer_clock(
struct xntimer *timer)
246 static inline struct xnsched *xntimer_sched(
struct xntimer *timer)
251 #define xntimer_sched(t) xnsched_current()
254 #define xntimer_percpu_queue(__timer) \
256 struct xntimerdata *tmd; \
257 int cpu = xnsched_cpu((__timer)->sched); \
258 tmd = xnclock_percpu_timerdata(xntimer_clock(__timer), cpu); \
262 static inline xntimerq_t *xntimer_this_queue(
struct xntimer *timer)
264 struct xntimerdata *tmd;
266 tmd = xnclock_this_timerdata(xntimer_clock(timer));
271 static inline unsigned long xntimer_gravity(
struct xntimer *timer)
273 struct xnclock *clock = xntimer_clock(timer);
275 if (timer->status & XNTIMER_KGRAVITY)
276 return clock->gravity.kernel;
278 if (timer->status & XNTIMER_UGRAVITY)
279 return clock->gravity.user;
281 return clock->gravity.irq;
284 static inline void xntimer_update_date(
struct xntimer *timer)
286 xntimerh_date(&timer->aplink) = timer->start_date
287 + xnclock_ns_to_ticks(xntimer_clock(timer),
288 timer->periodic_ticks * timer->interval_ns)
289 - xntimer_gravity(timer);
292 static inline xnticks_t xntimer_pexpect(
struct xntimer *timer)
294 return timer->start_date +
295 xnclock_ns_to_ticks(xntimer_clock(timer),
296 timer->pexpect_ticks * timer->interval_ns);
299 static inline void xntimer_set_priority(
struct xntimer *timer,
302 xntimerh_prio(&timer->aplink) = prio;
305 static inline int xntimer_active_p(
struct xntimer *timer)
307 return timer->sched != NULL;
310 static inline int xntimer_running_p(
struct xntimer *timer)
312 return (timer->status & XNTIMER_RUNNING) != 0;
315 static inline int xntimer_fired_p(
struct xntimer *timer)
317 return (timer->status & XNTIMER_FIRED) != 0;
320 static inline int xntimer_periodic_p(
struct xntimer *timer)
322 return (timer->status & XNTIMER_PERIODIC) != 0;
325 void __xntimer_init(
struct xntimer *timer,
326 struct xnclock *clock,
327 void (*handler)(
struct xntimer *timer),
331 void xntimer_set_gravity(
struct xntimer *timer,
334 #ifdef CONFIG_XENO_OPT_STATS
336 #define xntimer_init(__timer, __clock, __handler, __sched, __flags) \
338 __xntimer_init(__timer, __clock, __handler, __sched, __flags); \
339 xntimer_set_name(__timer, #__handler); \
342 static inline void xntimer_reset_stats(
struct xntimer *timer)
344 xnstat_counter_set(&timer->scheduled, 0);
345 xnstat_counter_set(&timer->fired, 0);
348 static inline void xntimer_account_scheduled(
struct xntimer *timer)
350 xnstat_counter_inc(&timer->scheduled);
353 static inline void xntimer_account_fired(
struct xntimer *timer)
355 xnstat_counter_inc(&timer->fired);
358 static inline void xntimer_set_name(
struct xntimer *timer,
const char *name)
360 knamecpy(timer->name, name);
365 #define xntimer_init __xntimer_init
367 static inline void xntimer_reset_stats(
struct xntimer *timer) { }
369 static inline void xntimer_account_scheduled(
struct xntimer *timer) { }
371 static inline void xntimer_account_fired(
struct xntimer *timer) { }
373 static inline void xntimer_set_name(
struct xntimer *timer,
const char *name) { }
377 #if defined(CONFIG_XENO_OPT_EXTCLOCK) && defined(CONFIG_XENO_OPT_STATS)
378 void xntimer_switch_tracking(
struct xntimer *timer,
379 struct xnclock *newclock);
382 void xntimer_switch_tracking(
struct xntimer *timer,
383 struct xnclock *newclock) { }
405 return timer->interval_ns;
408 static inline xnticks_t xntimer_expiry(
struct xntimer *timer)
411 return xntimerh_date(&timer->aplink) + xntimer_gravity(timer);
419 void __xntimer_stop(
struct xntimer *timer);
425 xnticks_t xntimer_get_interval(
struct xntimer *timer);
427 int xntimer_heading_p(
struct xntimer *timer);
431 if (timer->status & XNTIMER_RUNNING)
432 __xntimer_stop(timer);
435 static inline xnticks_t xntimer_get_timeout_stopped(
struct xntimer *timer)
440 static inline void xntimer_enqueue(
struct xntimer *timer,
443 xntimerq_insert(q, &timer->aplink);
444 timer->status &= ~XNTIMER_DEQUEUED;
445 xntimer_account_scheduled(timer);
448 static inline void xntimer_dequeue(
struct xntimer *timer,
451 xntimerq_remove(q, &timer->aplink);
452 timer->status |= XNTIMER_DEQUEUED;
464 void xntimer_migrate(
struct xntimer *timer,
struct xnsched *sched)
466 if (timer->sched != sched)
470 int xntimer_setup_ipi(
void);
472 void xntimer_release_ipi(
void);
476 static inline void xntimer_migrate(
struct xntimer *timer,
480 static inline int xntimer_setup_ipi(
void)
485 static inline void xntimer_release_ipi(
void) { }
489 static inline void xntimer_set_sched(
struct xntimer *timer,
492 xntimer_migrate(timer, sched);
495 char *xntimer_format_time(xnticks_t ns,
496 char *buf,
size_t bufsz);
xnticks_t xntimer_get_timeout(struct xntimer *timer)
Return the relative expiration date.
Definition: timer.c:266
xnticks_t xntimer_get_date(struct xntimer *timer)
Return the absolute expiration date.
Definition: timer.c:239
void __xntimer_migrate(struct xntimer *timer, struct xnsched *sched)
Migrate a timer.
Definition: timer.c:464
Scheduling information structure.
Definition: sched.h:58
int xntimer_start(struct xntimer *timer, xnticks_t value, xnticks_t interval, xntmode_t mode)
Arm a timer.
Definition: timer.c:101
void xntimer_destroy(struct xntimer *timer)
Release a timer object.
Definition: timer.c:430
unsigned long long xntimer_get_overruns(struct xntimer *timer, xnticks_t now)
Get the count of overruns for the last tick.
Definition: timer.c:519
void xntimer_release_hardware(void)
Release hardware timers.
Definition: timer.c:822
static xnticks_t xntimer_interval(struct xntimer *timer)
Return the timer interval value.
Definition: timer.h:403
static void xntimer_stop(struct xntimer *timer)
Disarm a timer.
Definition: timer.h:429
int xntimer_grab_hardware(void)
Grab the hardware timer on all real-time CPUs.
Definition: timer.c:725