diff options
Diffstat (limited to 'include/litmus/litmus_softirq.h')
-rw-r--r-- | include/litmus/litmus_softirq.h | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/include/litmus/litmus_softirq.h b/include/litmus/litmus_softirq.h new file mode 100644 index 000000000000..cfef08187464 --- /dev/null +++ b/include/litmus/litmus_softirq.h | |||
@@ -0,0 +1,166 @@ | |||
1 | #ifndef __LITMUS_SOFTIRQ_H | ||
2 | #define __LITMUS_SOFTIRQ_H | ||
3 | |||
4 | #include <linux/interrupt.h> | ||
5 | #include <linux/workqueue.h> | ||
6 | |||
7 | /* | ||
8 | Threaded tasklet/workqueue handling for Litmus. | ||
9 | Items are scheduled in the following order: hi-tasklet, | ||
10 | lo-tasklet, workqueue. Items are scheduled in FIFO order | ||
11 | within each of these classes. | ||
12 | |||
13 | klmirqd assumes the priority of the owner of the | ||
14 | tasklet when the tasklet is next to execute. | ||
15 | |||
16 | The base-priority of a klimirqd thread is below all regular | ||
17 | real-time tasks, but above all other Linux scheduling | ||
18 | classes (klmirqd threads are within the SHCED_LITMUS class). | ||
19 | Regular real-time tasks may increase the priority of | ||
20 | a klmirqd thread, but klmirqd is unaware of this | ||
21 | (this was not the case in prior incarnations of klmirqd). | ||
22 | */ | ||
23 | |||
24 | |||
25 | /* Initialize klmirqd */ | ||
26 | void init_klmirqd(void); | ||
27 | |||
28 | /* Raises a flag to tell klmirqds to terminate. | ||
29 | Termination is async, so some threads may be running | ||
30 | after function return. */ | ||
31 | void kill_klmirqd(void); | ||
32 | |||
33 | void kill_klmirqd_thread(struct task_struct* klmirqd_thread); | ||
34 | |||
35 | /* Returns 1 if all NR_LITMUS_SOFTIRQD klitirqs are ready | ||
36 | to handle tasklets. 0, otherwise.*/ | ||
37 | int klmirqd_is_ready(void); | ||
38 | |||
39 | /* Returns 1 if no NR_LITMUS_SOFTIRQD klitirqs are ready | ||
40 | to handle tasklets. 0, otherwise.*/ | ||
41 | int klmirqd_is_dead(void); | ||
42 | |||
43 | |||
44 | typedef int (*klmirqd_cb_t) (void *arg); | ||
45 | |||
46 | typedef struct | ||
47 | { | ||
48 | klmirqd_cb_t func; | ||
49 | void* arg; | ||
50 | } klmirqd_callback_t; | ||
51 | |||
52 | /* Launches a klmirqd thread with the provided affinity. | ||
53 | |||
54 | Actual launch of threads is deffered to kworker's | ||
55 | workqueue, so daemons will likely not be immediately | ||
56 | running when this function returns, though the required | ||
57 | data will be initialized. | ||
58 | |||
59 | cpu == -1 for no affinity | ||
60 | |||
61 | provide a name at most 31 (32, + null terminator) characters long. | ||
62 | name == NULL for a default name. (all names are appended with | ||
63 | base-CPU affinity) | ||
64 | */ | ||
65 | #define MAX_KLMIRQD_NAME_LEN 31 | ||
66 | int launch_klmirqd_thread(char* name, int cpu, klmirqd_callback_t* cb); | ||
67 | |||
68 | |||
69 | /* Flushes all pending work out to the OS for regular | ||
70 | * tasklet/work processing. | ||
71 | */ | ||
72 | void flush_pending(struct task_struct* klmirqd_thread); | ||
73 | |||
74 | extern int __litmus_tasklet_schedule( | ||
75 | struct tasklet_struct *t, | ||
76 | struct task_struct *klmirqd_thread); | ||
77 | |||
78 | /* schedule a tasklet on klmirqd #k_id */ | ||
79 | static inline int litmus_tasklet_schedule( | ||
80 | struct tasklet_struct *t, | ||
81 | struct task_struct *klmirqd_thread) | ||
82 | { | ||
83 | int ret = 0; | ||
84 | if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { | ||
85 | ret = __litmus_tasklet_schedule(t, klmirqd_thread); | ||
86 | } | ||
87 | return(ret); | ||
88 | } | ||
89 | |||
90 | /* for use by __tasklet_schedule() */ | ||
91 | static inline int _litmus_tasklet_schedule( | ||
92 | struct tasklet_struct *t, | ||
93 | struct task_struct *klmirqd_thread) | ||
94 | { | ||
95 | return(__litmus_tasklet_schedule(t, klmirqd_thread)); | ||
96 | } | ||
97 | |||
98 | |||
99 | |||
100 | |||
101 | extern int __litmus_tasklet_hi_schedule(struct tasklet_struct *t, | ||
102 | struct task_struct *klmirqd_thread); | ||
103 | |||
104 | /* schedule a hi tasklet on klmirqd #k_id */ | ||
105 | static inline int litmus_tasklet_hi_schedule(struct tasklet_struct *t, | ||
106 | struct task_struct *klmirqd_thread) | ||
107 | { | ||
108 | int ret = 0; | ||
109 | if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { | ||
110 | ret = __litmus_tasklet_hi_schedule(t, klmirqd_thread); | ||
111 | } | ||
112 | return(ret); | ||
113 | } | ||
114 | |||
115 | /* for use by __tasklet_hi_schedule() */ | ||
116 | static inline int _litmus_tasklet_hi_schedule(struct tasklet_struct *t, | ||
117 | struct task_struct *klmirqd_thread) | ||
118 | { | ||
119 | return(__litmus_tasklet_hi_schedule(t, klmirqd_thread)); | ||
120 | } | ||
121 | |||
122 | |||
123 | |||
124 | |||
125 | |||
126 | extern int __litmus_tasklet_hi_schedule_first( | ||
127 | struct tasklet_struct *t, | ||
128 | struct task_struct *klmirqd_thread); | ||
129 | |||
130 | /* schedule a hi tasklet on klmirqd #k_id on next go-around */ | ||
131 | /* PRECONDITION: Interrupts must be disabled. */ | ||
132 | static inline int litmus_tasklet_hi_schedule_first( | ||
133 | struct tasklet_struct *t, | ||
134 | struct task_struct *klmirqd_thread) | ||
135 | { | ||
136 | int ret = 0; | ||
137 | if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { | ||
138 | ret = __litmus_tasklet_hi_schedule_first(t, klmirqd_thread); | ||
139 | } | ||
140 | return(ret); | ||
141 | } | ||
142 | |||
143 | /* for use by __tasklet_hi_schedule_first() */ | ||
144 | static inline int _litmus_tasklet_hi_schedule_first( | ||
145 | struct tasklet_struct *t, | ||
146 | struct task_struct *klmirqd_thread) | ||
147 | { | ||
148 | return(__litmus_tasklet_hi_schedule_first(t, klmirqd_thread)); | ||
149 | } | ||
150 | |||
151 | |||
152 | |||
153 | ////////////// | ||
154 | |||
155 | extern int __litmus_schedule_work( | ||
156 | struct work_struct* w, | ||
157 | struct task_struct *klmirqd_thread); | ||
158 | |||
159 | static inline int litmus_schedule_work( | ||
160 | struct work_struct* w, | ||
161 | struct task_struct *klmirqd_thread) | ||
162 | { | ||
163 | return(__litmus_schedule_work(w, klmirqd_thread)); | ||
164 | } | ||
165 | |||
166 | #endif | ||