Padding in MCS-PDR qnodes (XCC)
[akaros.git] / kern / include / alarm.h
1 /* Copyright (c) 2011 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
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.
10  *
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.
13  *
14  * If you're using a global alarm timer_chain, you'll probably need to grab a
15  * lock.  The only current user is pcpu tchains, though the code ought be able
16  * to handle other uses.
17  *
18  * Quick howto, using the pcpu tchains:
19  *      struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
20  * 1) To block your kthread on an alarm:
21  *      struct alarm_waiter a_waiter;
22  *      init_awaiter(&a_waiter, 0);
23  *      set_awaiter_rel(&a_waiter, USEC);
24  *      set_alarm(tchain, &a_waiter);
25  *      sleep_on_awaiter(&a_waiter);
26  * 2) To set a handler to run on an alarm:
27  *      struct alarm_waiter *waiter = kmalloc(sizeof(struct alarm_waiter), 0);
28  *      init_awaiter(waiter, HANDLER);
29  *      set_awaiter_rel(waiter, USEC);
30  *      set_alarm(tchain, waiter);
31  * If you want the HANDLER to run again, do this at the end of it:
32  *      set_awaiter_rel(waiter, USEC);
33  *      set_alarm(tchain, waiter);
34  * Don't forget to manage your memory at some (safe) point:
35  *      kfree(waiter);
36  * In the future, we might have a slab for these.  You can get it from wherever
37  * you want, just don't use the stack for handler style, since you'll usually
38  * return and pop up the stack after setting the alarm.
39  * */
40
41 #ifndef ROS_KERN_ALARM_H
42 #define ROS_KERN_ALARM_H
43
44 #include <ros/common.h>
45 #include <sys/queue.h>
46 #include <kthread.h>
47
48 /* These structures allow code to block or defer work for a certain amount of
49  * time.  Timer chains (like off a per-core timer) are made of lists/trees of
50  * these. 
51  *
52  * If you have a func pointer, that handler will run when the alarm goes off.
53  * If you don't have a func pointer, you sleep on the semaphore and block your
54  * kthread.  In the latter case, you ought to allocate space for them on the
55  * stack of the thread you're about to block on. */
56 struct alarm_waiter {
57         uint64_t                                        wake_up_time;   /* ugh, this is a TSC for now */
58         void (*func) (struct alarm_waiter *waiter);     /* either this, or a kthread */
59         struct semaphore                        sem;                    /* kthread will sleep on this */
60         void                                            *data;
61         TAILQ_ENTRY(alarm_waiter)       next;
62 };
63 TAILQ_HEAD(awaiters_tailq, alarm_waiter);               /* ideally not a LL */
64
65 /* One of these per alarm source, such as a per-core timer.  Based on the
66  * source, you may need a lock (such as for a global timer).  set_interrupt() is
67  * a method for setting the interrupt source. */
68 struct timer_chain {
69         struct awaiters_tailq           waiters;
70         uint64_t                                        earliest_time;
71         uint64_t                                        latest_time;
72         void (*set_interrupt) (uint64_t time, struct timer_chain *);
73 };
74
75 /* Called once per timer chain, currently in per_cpu_init() */
76 void init_timer_chain(struct timer_chain *tchain,
77                       void (*set_interrupt) (uint64_t, struct timer_chain *));
78 /* For fresh alarm waiters.  func == 0 for kthreads */
79 void init_awaiter(struct alarm_waiter *waiter,
80                   void (*func) (struct alarm_waiter *));
81 /* Sets the time an awaiter goes off */
82 void set_awaiter_abs(struct alarm_waiter *waiter, uint64_t abs_time);
83 void set_awaiter_rel(struct alarm_waiter *waiter, uint64_t usleep);
84 void set_awaiter_inc(struct alarm_waiter *waiter, uint64_t usleep);
85 /* Arms/disarms the alarm */
86 void set_alarm(struct timer_chain *tchain, struct alarm_waiter *waiter);
87 void unset_alarm(struct timer_chain *tchain, struct alarm_waiter *waiter);
88 /* Blocks on the alarm waiter */
89 int sleep_on_awaiter(struct alarm_waiter *waiter);
90 /* Interrupt handlers needs to call this.  Don't call it directly. */
91 void trigger_tchain(struct timer_chain *tchain);
92 /* How to set a specific alarm: the per-cpu timer interrupt */
93 void set_pcpu_alarm_interrupt(uint64_t time, struct timer_chain *tchain);
94
95 /* Debugging */
96 #define ALARM_POISON_TIME 12345
97 void print_chain(struct timer_chain *tchain);
98 void print_pcpu_chains(void);
99
100 #endif /* ROS_KERN_ALARM_H */