aboutsummaryrefslogtreecommitdiffstats
path: root/include/litmus/litmus_softirq.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/litmus/litmus_softirq.h')
-rw-r--r--include/litmus/litmus_softirq.h166
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 */
26void 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. */
31void kill_klmirqd(void);
32
33void 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.*/
37int klmirqd_is_ready(void);
38
39/* Returns 1 if no NR_LITMUS_SOFTIRQD klitirqs are ready
40 to handle tasklets. 0, otherwise.*/
41int klmirqd_is_dead(void);
42
43
44typedef int (*klmirqd_cb_t) (void *arg);
45
46typedef 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
66int 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 */
72void flush_pending(struct task_struct* klmirqd_thread);
73
74extern int __litmus_tasklet_schedule(
75 struct tasklet_struct *t,
76 struct task_struct *klmirqd_thread);
77
78/* schedule a tasklet on klmirqd #k_id */
79static 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() */
91static 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
101extern 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 */
105static 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() */
116static 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
126extern 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. */
132static 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() */
144static 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
155extern int __litmus_schedule_work(
156 struct work_struct* w,
157 struct task_struct *klmirqd_thread);
158
159static 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