1 /******************************************************************************
2  * timer.h
3  *
4  * Copyright (c) 2002-2003 Rolf Neugebauer
5  * Copyright (c) 2002-2005 K A Fraser
6  */
7 
8 #ifndef _TIMER_H_
9 #define _TIMER_H_
10 
11 #include <xen/spinlock.h>
12 #include <xen/time.h>
13 #include <xen/string.h>
14 #include <xen/list.h>
15 #include <xen/percpu.h>
16 
17 struct timer {
18     /* System time expiry value (nanoseconds since boot). */
19     s_time_t expires;
20 
21     /* Position in active-timer data structure. */
22     union {
23         /* Timer-heap offset (TIMER_STATUS_in_heap). */
24         unsigned int heap_offset;
25         /* Linked list (TIMER_STATUS_in_list). */
26         struct timer *list_next;
27         /* Linked list of inactive timers (TIMER_STATUS_inactive). */
28         struct list_head inactive;
29     };
30 
31     /* On expiry, '(*function)(data)' will be executed in softirq context. */
32     void (*function)(void *);
33     void *data;
34 
35     /* CPU on which this timer will be installed and executed. */
36 #define TIMER_CPU_status_killed 0xffffu /* Timer is TIMER_STATUS_killed */
37     uint16_t cpu;
38 
39     /* Timer status. */
40 #define TIMER_STATUS_invalid  0 /* Should never see this.           */
41 #define TIMER_STATUS_inactive 1 /* Not in use; can be activated.    */
42 #define TIMER_STATUS_killed   2 /* Not in use; cannot be activated. */
43 #define TIMER_STATUS_in_heap  3 /* In use; on timer heap.           */
44 #define TIMER_STATUS_in_list  4 /* In use; on overflow linked list. */
45     uint8_t status;
46 };
47 
48 /*
49  * All functions below can be called for any CPU from any CPU in any context.
50  */
51 
52 /*
53  * Initialise a timer structure with an initial callback CPU, callback
54  * function and callback data pointer. This function must only be called on
55  * a brand new timer, or a killed timer. It must *never* execute concurrently
56  * with any other operation on the same timer.
57  */
58 void init_timer(
59     struct timer *timer,
60     void        (*function)(void *),
61     void         *data,
62     unsigned int  cpu);
63 
64 /* Set the expiry time and activate a timer. */
65 void set_timer(struct timer *timer, s_time_t expires);
66 
67 /*
68  * Deactivate a timer This function has no effect if the timer is not currently
69  * active.
70  */
71 void stop_timer(struct timer *timer);
72 
73 /* True if a timer is active, and its expiry time is earlier than t. */
74 bool timer_expires_before(struct timer *timer, s_time_t t);
75 
76 #define timer_is_expired(t) timer_expires_before(t, NOW())
77 
78 /*
79  * True if a timer is active.
80  *
81  * Unlike for timer_expires_before(), it is the caller's responsibility to
82  * use suitable locking such that the returned value isn't stale by the time
83  * it gets acted upon.
84  */
timer_is_active(const struct timer * timer)85 static inline bool timer_is_active(const struct timer *timer)
86 {
87     ASSERT(timer->status <= TIMER_STATUS_in_list);
88     return timer->status >= TIMER_STATUS_in_heap;
89 }
90 
91 /* Migrate a timer to a different CPU. The timer may be currently active. */
92 void migrate_timer(struct timer *timer, unsigned int new_cpu);
93 
94 /*
95  * Deactivate a timer and prevent it from being re-set (future calls to
96  * set_timer will silently fail). When this function returns it is guaranteed
97  * that the timer callback handler is not running on any CPU.
98  */
99 void kill_timer(struct timer *timer);
100 
101 /* Bootstrap initialisation. Must be called before any other timer function. */
102 void timer_init(void);
103 
104 /* Next timer deadline for each CPU. */
105 DECLARE_PER_CPU(s_time_t, timer_deadline);
106 
107 /* Arch-defined function to reprogram timer hardware for new deadline. */
108 int reprogram_timer(s_time_t timeout);
109 
110 /* Calculate the aligned first tick time for a given periodic timer. */
111 s_time_t align_timer(s_time_t firsttick, uint64_t period);
112 
113 #endif /* _TIMER_H_ */
114 
115 /*
116  * Local variables:
117  * mode: C
118  * c-file-style: "BSD"
119  * c-basic-offset: 4
120  * tab-width: 4
121  * indent-tabs-mode: nil
122  * End:
123  */
124