1 /* Copyright (c) 2011 The Regents of the University of California
2 * Barret Rhoden <brho@cs.berkeley.edu>
3 * See LICENSE for details.
5 * Alarms. This includes various ways to sleep for a while or defer work on a
6 * specific timer. These can be per-core, global or whatever. Deferred work
7 * is a function pointer which runs in interrupt context when the alarm goes off
8 * (picture running the ksched then). The other style is to block/sleep on the
9 * awaiter after the alarm is set.
11 * Like with most systems, you won't wake up til after the time you specify (for
12 * now). This might change, esp if we tweak things to coalesce alarms.
14 * All tchains come with locks. Originally, I left these out, since the pcpu
15 * tchains didn't need them (disable_irq was sufficient). However, disabling
16 * alarms remotely (a valid use case) is a real pain without locks, so now
17 * everyone has locks. As an added benefit, you can submit an alarm to another
18 * core's pcpu tchain (though it probably costs an extra IRQ). Note there is a
19 * lock ordering, tchains before awaiters (when they are grabbed together).
21 * Quick howto, using the pcpu tchains:
22 * struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
23 * 1) To block your kthread on an alarm:
24 * struct alarm_waiter a_waiter;
25 * init_awaiter(&a_waiter, 0);
26 * set_awaiter_rel(&a_waiter, USEC);
27 * set_alarm(tchain, &a_waiter);
28 * sleep_on_awaiter(&a_waiter);
29 * 2) To set a handler to run on an alarm:
30 * struct alarm_waiter *waiter = kmalloc(sizeof(struct alarm_waiter), 0);
31 * init_awaiter(waiter, HANDLER);
32 * set_awaiter_rel(waiter, USEC);
33 * set_alarm(tchain, waiter);
34 * If you want the HANDLER to run again, do this at the end of it:
35 * set_awaiter_rel(waiter, USEC);
36 * __set_alarm(tchain, waiter);
37 * Do not call set_alarm() from within an alarm handler; you'll deadlock.
38 * Don't forget to manage your memory at some (safe) point:
40 * In the future, we might have a slab for these. You can get it from wherever
41 * you want, just don't use the stack for handler style, since you'll usually
42 * return and pop up the stack after setting the alarm.
45 #ifndef ROS_KERN_ALARM_H
46 #define ROS_KERN_ALARM_H
48 #include <ros/common.h>
49 #include <sys/queue.h>
52 /* These structures allow code to block or defer work for a certain amount of
53 * time. Timer chains (like off a per-core timer) are made of lists/trees of
56 * If you have a func pointer, that handler will run when the alarm goes off.
57 * If you don't have a func pointer, you sleep on the semaphore and block your
58 * kthread. In the latter case, you ought to allocate space for them on the
59 * stack of the thread you're about to block on. */
61 uint64_t wake_up_time; /* ugh, this is a TSC for now */
62 void (*func) (struct alarm_waiter *waiter); /* either this, or a kthread */
63 struct semaphore sem; /* kthread will sleep on this */
65 TAILQ_ENTRY(alarm_waiter) next;
68 TAILQ_HEAD(awaiters_tailq, alarm_waiter); /* ideally not a LL */
70 typedef void (*alarm_handler)(struct alarm_waiter *waiter);
72 /* One of these per alarm source, such as a per-core timer. All tchains come
73 * with a lock, even if its rarely needed (like the pcpu tchains).
74 * set_interrupt() is a method for setting the interrupt source. */
77 struct awaiters_tailq waiters;
78 uint64_t earliest_time;
80 void (*set_interrupt) (uint64_t time, struct timer_chain *);
83 /* Called once per timer chain, currently in per_cpu_init() */
84 void init_timer_chain(struct timer_chain *tchain,
85 void (*set_interrupt) (uint64_t, struct timer_chain *));
86 /* For fresh alarm waiters. func == 0 for kthreads */
87 void init_awaiter(struct alarm_waiter *waiter,
88 void (*func) (struct alarm_waiter *));
89 /* Sets the time an awaiter goes off */
90 void set_awaiter_abs(struct alarm_waiter *waiter, uint64_t abs_time);
91 void set_awaiter_rel(struct alarm_waiter *waiter, uint64_t usleep);
92 void set_awaiter_inc(struct alarm_waiter *waiter, uint64_t usleep);
93 /* Arms/disarms the alarm */
94 void __set_alarm(struct timer_chain *tchain, struct alarm_waiter *waiter);
95 void set_alarm(struct timer_chain *tchain, struct alarm_waiter *waiter);
96 bool unset_alarm(struct timer_chain *tchain, struct alarm_waiter *waiter);
97 void reset_alarm_abs(struct timer_chain *tchain, struct alarm_waiter *waiter,
99 /* Blocks on the alarm waiter */
100 int sleep_on_awaiter(struct alarm_waiter *waiter);
101 /* Interrupt handlers needs to RKM this. Don't call it directly. */
102 void __trigger_tchain(uint32_t srcid, long a0, long a1, long a2);
103 /* How to set a specific alarm: the per-cpu timer interrupt */
104 void set_pcpu_alarm_interrupt(uint64_t time, struct timer_chain *tchain);
107 #define ALARM_POISON_TIME 12345 /* could use some work */
108 void print_chain(struct timer_chain *tchain);
109 void print_pcpu_chains(void);
111 #endif /* ROS_KERN_ALARM_H */