diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2009-12-17 21:23:36 -0500 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-29 17:05:45 -0400 |
commit | 4b38febbd59fd33542a343991262119eb9860f5e (patch) | |
tree | 1af88a0d354abe344c2c2869631f76a1806d75c3 /litmus/sched_plugin.c | |
parent | 22763c5cf3690a681551162c15d34d935308c8d7 (diff) |
[ported from 2008.3] Core LITMUS^RT infrastructure
Port 2008.3 Core LITMUS^RT infrastructure to Linux 2.6.32
litmus_sched_class implements 4 new methods:
- prio_changed:
void
- switched_to:
void
- get_rr_interval:
return infinity (i.e., 0)
- select_task_rq:
return current cpu
Diffstat (limited to 'litmus/sched_plugin.c')
-rw-r--r-- | litmus/sched_plugin.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c new file mode 100644 index 000000000000..0be091ece569 --- /dev/null +++ b/litmus/sched_plugin.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* sched_plugin.c -- core infrastructure for the scheduler plugin system | ||
2 | * | ||
3 | * This file includes the initialization of the plugin system, the no-op Linux | ||
4 | * scheduler plugin and some dummy functions. | ||
5 | */ | ||
6 | |||
7 | #include <linux/list.h> | ||
8 | #include <linux/spinlock.h> | ||
9 | |||
10 | #include <litmus/litmus.h> | ||
11 | #include <litmus/sched_plugin.h> | ||
12 | |||
13 | #include <litmus/jobs.h> | ||
14 | |||
15 | /************************************************************* | ||
16 | * Dummy plugin functions * | ||
17 | *************************************************************/ | ||
18 | |||
19 | static void litmus_dummy_finish_switch(struct task_struct * prev) | ||
20 | { | ||
21 | } | ||
22 | |||
23 | static struct task_struct* litmus_dummy_schedule(struct task_struct * prev) | ||
24 | { | ||
25 | return NULL; | ||
26 | } | ||
27 | |||
28 | static void litmus_dummy_tick(struct task_struct* tsk) | ||
29 | { | ||
30 | } | ||
31 | |||
32 | static long litmus_dummy_admit_task(struct task_struct* tsk) | ||
33 | { | ||
34 | printk(KERN_CRIT "LITMUS^RT: Linux plugin rejects %s/%d.\n", | ||
35 | tsk->comm, tsk->pid); | ||
36 | return -EINVAL; | ||
37 | } | ||
38 | |||
39 | static void litmus_dummy_task_new(struct task_struct *t, int on_rq, int running) | ||
40 | { | ||
41 | } | ||
42 | |||
43 | static void litmus_dummy_task_wake_up(struct task_struct *task) | ||
44 | { | ||
45 | } | ||
46 | |||
47 | static void litmus_dummy_task_block(struct task_struct *task) | ||
48 | { | ||
49 | } | ||
50 | |||
51 | static void litmus_dummy_task_exit(struct task_struct *task) | ||
52 | { | ||
53 | } | ||
54 | |||
55 | static long litmus_dummy_complete_job(void) | ||
56 | { | ||
57 | return -ENOSYS; | ||
58 | } | ||
59 | |||
60 | static long litmus_dummy_activate_plugin(void) | ||
61 | { | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static long litmus_dummy_deactivate_plugin(void) | ||
66 | { | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | #ifdef CONFIG_FMLP | ||
71 | |||
72 | static long litmus_dummy_inherit_priority(struct pi_semaphore *sem, | ||
73 | struct task_struct *new_owner) | ||
74 | { | ||
75 | return -ENOSYS; | ||
76 | } | ||
77 | |||
78 | static long litmus_dummy_return_priority(struct pi_semaphore *sem) | ||
79 | { | ||
80 | return -ENOSYS; | ||
81 | } | ||
82 | |||
83 | static long litmus_dummy_pi_block(struct pi_semaphore *sem, | ||
84 | struct task_struct *new_waiter) | ||
85 | { | ||
86 | return -ENOSYS; | ||
87 | } | ||
88 | |||
89 | #endif | ||
90 | |||
91 | |||
92 | /* The default scheduler plugin. It doesn't do anything and lets Linux do its | ||
93 | * job. | ||
94 | */ | ||
95 | struct sched_plugin linux_sched_plugin = { | ||
96 | .plugin_name = "Linux", | ||
97 | .tick = litmus_dummy_tick, | ||
98 | .task_new = litmus_dummy_task_new, | ||
99 | .task_exit = litmus_dummy_task_exit, | ||
100 | .task_wake_up = litmus_dummy_task_wake_up, | ||
101 | .task_block = litmus_dummy_task_block, | ||
102 | .complete_job = litmus_dummy_complete_job, | ||
103 | .schedule = litmus_dummy_schedule, | ||
104 | .finish_switch = litmus_dummy_finish_switch, | ||
105 | .activate_plugin = litmus_dummy_activate_plugin, | ||
106 | .deactivate_plugin = litmus_dummy_deactivate_plugin, | ||
107 | #ifdef CONFIG_FMLP | ||
108 | .inherit_priority = litmus_dummy_inherit_priority, | ||
109 | .return_priority = litmus_dummy_return_priority, | ||
110 | .pi_block = litmus_dummy_pi_block, | ||
111 | #endif | ||
112 | .admit_task = litmus_dummy_admit_task | ||
113 | }; | ||
114 | |||
115 | /* | ||
116 | * The reference to current plugin that is used to schedule tasks within | ||
117 | * the system. It stores references to actual function implementations | ||
118 | * Should be initialized by calling "init_***_plugin()" | ||
119 | */ | ||
120 | struct sched_plugin *litmus = &linux_sched_plugin; | ||
121 | |||
122 | /* the list of registered scheduling plugins */ | ||
123 | static LIST_HEAD(sched_plugins); | ||
124 | static DEFINE_SPINLOCK(sched_plugins_lock); | ||
125 | |||
126 | #define CHECK(func) {\ | ||
127 | if (!plugin->func) \ | ||
128 | plugin->func = litmus_dummy_ ## func;} | ||
129 | |||
130 | /* FIXME: get reference to module */ | ||
131 | int register_sched_plugin(struct sched_plugin* plugin) | ||
132 | { | ||
133 | printk(KERN_INFO "Registering LITMUS^RT plugin %s.\n", | ||
134 | plugin->plugin_name); | ||
135 | |||
136 | /* make sure we don't trip over null pointers later */ | ||
137 | CHECK(finish_switch); | ||
138 | CHECK(schedule); | ||
139 | CHECK(tick); | ||
140 | CHECK(task_wake_up); | ||
141 | CHECK(task_exit); | ||
142 | CHECK(task_block); | ||
143 | CHECK(task_new); | ||
144 | CHECK(complete_job); | ||
145 | CHECK(activate_plugin); | ||
146 | CHECK(deactivate_plugin); | ||
147 | #ifdef CONFIG_FMLP | ||
148 | CHECK(inherit_priority); | ||
149 | CHECK(return_priority); | ||
150 | CHECK(pi_block); | ||
151 | #endif | ||
152 | CHECK(admit_task); | ||
153 | |||
154 | if (!plugin->release_at) | ||
155 | plugin->release_at = release_at; | ||
156 | |||
157 | spin_lock(&sched_plugins_lock); | ||
158 | list_add(&plugin->list, &sched_plugins); | ||
159 | spin_unlock(&sched_plugins_lock); | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | |||
165 | /* FIXME: reference counting, etc. */ | ||
166 | struct sched_plugin* find_sched_plugin(const char* name) | ||
167 | { | ||
168 | struct list_head *pos; | ||
169 | struct sched_plugin *plugin; | ||
170 | |||
171 | spin_lock(&sched_plugins_lock); | ||
172 | list_for_each(pos, &sched_plugins) { | ||
173 | plugin = list_entry(pos, struct sched_plugin, list); | ||
174 | if (!strcmp(plugin->plugin_name, name)) | ||
175 | goto out_unlock; | ||
176 | } | ||
177 | plugin = NULL; | ||
178 | |||
179 | out_unlock: | ||
180 | spin_unlock(&sched_plugins_lock); | ||
181 | return plugin; | ||
182 | } | ||
183 | |||
184 | int print_sched_plugins(char* buf, int max) | ||
185 | { | ||
186 | int count = 0; | ||
187 | struct list_head *pos; | ||
188 | struct sched_plugin *plugin; | ||
189 | |||
190 | spin_lock(&sched_plugins_lock); | ||
191 | list_for_each(pos, &sched_plugins) { | ||
192 | plugin = list_entry(pos, struct sched_plugin, list); | ||
193 | count += snprintf(buf + count, max - count, "%s\n", plugin->plugin_name); | ||
194 | if (max - count <= 0) | ||
195 | break; | ||
196 | } | ||
197 | spin_unlock(&sched_plugins_lock); | ||
198 | return count; | ||
199 | } | ||