aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--litmus/Makefile3
-rw-r--r--litmus/sched_edf_hsb.c376
-rw-r--r--litmus/sched_edf_hsb_noslack.c2556
-rw-r--r--litmus/servers.c92
4 files changed, 14 insertions, 3013 deletions
diff --git a/litmus/Makefile b/litmus/Makefile
index 9468312b39e4..62c2bb064581 100644
--- a/litmus/Makefile
+++ b/litmus/Makefile
@@ -18,8 +18,7 @@ obj-y = sched_plugin.o litmus.o \
18 ctrldev.o \ 18 ctrldev.o \
19 servers.o \ 19 servers.o \
20 sched_gsn_edf.o \ 20 sched_gsn_edf.o \
21 sched_edf_hsb.o \ 21 sched_edf_hsb.o
22 sched_edf_hsb_noslack.o
23 22
24obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o 23obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o
25obj-$(CONFIG_PLUGIN_PFAIR) += sched_pfair.o 24obj-$(CONFIG_PLUGIN_PFAIR) += sched_pfair.o
diff --git a/litmus/sched_edf_hsb.c b/litmus/sched_edf_hsb.c
index d74f4337ac2b..4bc6c1382171 100644
--- a/litmus/sched_edf_hsb.c
+++ b/litmus/sched_edf_hsb.c
@@ -1,29 +1,7 @@
1/* 1/*
2 * litmus/sched_edf_hsb.c 2 * litmus/sched_edf_hsb.c
3 * 3 *
4 * Implentation of the EDF-HSB scheduling algorithm. 4 * Implementation of the EDF-HSB scheduling algorithm.
5 *
6 * The following 6 events are fired by timers and not handled by
7 * the plugin infrastructure itself:
8 *
9 * release_[hrt|srt|be]_jobs
10 * [hrt|be]_server_released
11 * server_completed (for HRT, SRT, and BE)
12 *
13 * The following 4 events are caused by a write to the proc entry
14 * and should never be run when the plugin is already running:
15 * stop_[hrt|be]_servers
16 * admit_[hrt|be]_server
17 *
18 * TODO system for removing tasks from their release queues
19 * TODO clean up link_to_cpu and check_slack args
20 * TODO move slack completion into release
21 * TODO fix concurrent arms
22 * TODO slack and BE servers, include slack higher prio
23 * TODO start servers should no longer be cessary
24 * TODO harmonize order of method arguments
25 * TODO test crazy task_new hack
26 * TODO remove bheap_node_in_heap check in litmus_exit_task
27 */ 5 */
28#include <linux/module.h> 6#include <linux/module.h>
29#include <linux/uaccess.h> 7#include <linux/uaccess.h>
@@ -43,32 +21,17 @@
43#include <litmus/servers.h> 21#include <litmus/servers.h>
44#define DEBUG_EDF_HSB 22#define DEBUG_EDF_HSB
45 23
46/* DOES NOT WORK */
47//#define SLACK_ON_MASTER
48
49#define BE_PROC_NAME "be_servers" 24#define BE_PROC_NAME "be_servers"
50#define HRT_PROC_NAME "hrt_servers" 25#define HRT_PROC_NAME "hrt_servers"
51#define BE_SERVER_BASE 100 26#define BE_SERVER_BASE 100
52#define IDLE_SLACK_BASE 1000 27#define IDLE_SLACK_BASE 1000
53#define SLACK_MIN NSEC_PER_MSEC 28#define SLACK_MIN NSEC_PER_MSEC
54 29
55/* SCHED_TRACE action events */
56#define SERVER_COMPLETED_ACTION 1
57#define SERVER_RELEASED_ACTION 2
58#define NO_SLACK_ACTION 3
59#define SLACK_RUN_ACTION 4
60#define SLACK_STOP_ACTION 5
61#define SLACK_RECLAIM_ACTION 6
62#define SLACK_EXPIRED_ACTION 7
63#define SLACK_DONATED_ACTION 8
64#define CANDIDATE_ADDED_ACTION 9
65
66/* Uncomment for human readable time */ 30/* Uncomment for human readable time */
67#define TIME(x) \ 31#define TIME(x) \
68 (x) 32({lt_t y = x; \
69/* ({lt_t y = x; \ */ 33do_div(y, NSEC_PER_MSEC); \
70/* do_div(y, NSEC_PER_MSEC); \ */ 34y;})
71/* y;}) */
72#define TRACE_TIMER(fmt, args...) \ 35#define TRACE_TIMER(fmt, args...) \
73 sched_trace_log_message("%d P%d*[%s@%s:%d]: " fmt " at %d\n", \ 36 sched_trace_log_message("%d P%d*[%s@%s:%d]: " fmt " at %d\n", \
74 TRACE_ARGS, ## args, TIME(litmus_clock())) 37 TRACE_ARGS, ## args, TIME(litmus_clock()))
@@ -77,28 +40,6 @@
77 (t)->rt_param.job_params.job_no, ## args) 40 (t)->rt_param.job_params.job_no, ## args)
78 41
79/* 42/*
80 * Useful debugging macros. Remove for actual use as they cause
81 * a lot of lock contention.
82 */
83#ifdef DEBUG_EDF_HSB
84
85#define TRACE_SUB(fmt, args...) \
86 sched_trace_log_message("%d P%d [%s@%s:%d]: " fmt "\n", \
87 TRACE_ARGS, ## args)
88#define TRACE_TASK_SUB(t, fmt, args...) \
89 TRACE_SUB(TASK_FMT " " fmt, TASK_ARGS(t), ##args)
90#define TRACE_SERVER_SUB(s, fmt, args...) \
91 TRACE_SUB(SERVER_FMT " " fmt, SERVER_ARGS(s), ##args)
92#define TRACE_TASK_SERVER_SUB(t, s, fmt, args...) \
93 TRACE_TASK_SUB(t, SERVER_FMT " " fmt, SERVER_ARGS(s), ##args)
94#else
95#define TRACE_SUB(fmt, args...)
96#define TRACE_TASK_SUB(t, fmt, args...)
97#define TRACE_SERVER_SUB(s, fmt, args...)
98#define TRACE_TASK_SERVER_SUB(t, s, fmt, args...)
99#endif
100
101/*
102 * Different types of servers 43 * Different types of servers
103 */ 44 */
104typedef enum { 45typedef enum {
@@ -186,7 +127,6 @@ static struct sched_plugin edf_hsb_plugin __cacheline_aligned_in_smp;
186 */ 127 */
187static inline int head_in_list(struct list_head *head) 128static inline int head_in_list(struct list_head *head)
188{ 129{
189 BUG_ON(!head);
190 return !(head->next == head->prev && head->prev == head); 130 return !(head->next == head->prev && head->prev == head);
191} 131}
192 132
@@ -242,8 +182,6 @@ static void remove_slack(server_t *slack)
242{ 182{
243 if (!slack) 183 if (!slack)
244 return; 184 return;
245 TRACE_SERVER_SUB(slack, "slack removed");
246 //////sched_trace_action(NULL, SLACK_EXPIRED_ACTION);
247 185
248 if (head_in_list(&slack->list)) 186 if (head_in_list(&slack->list))
249 list_del_init(&slack->list); 187 list_del_init(&slack->list);
@@ -260,12 +198,8 @@ static void add_slack(server_t *slack)
260 struct list_head *pos; 198 struct list_head *pos;
261 server_t *queued; 199 server_t *queued;
262 200
263 TRACE_SERVER_SUB(slack, "slack added"); 201 if (head_in_list(&slack->list))
264
265 if (head_in_list(&slack->list)) {
266 TRACE_SERVER_SUB(slack, "already in list");
267 return; 202 return;
268 }
269 203
270 list_for_each_prev(pos, &slack_queue) { 204 list_for_each_prev(pos, &slack_queue) {
271 queued = list_entry(pos, server_t, list); 205 queued = list_entry(pos, server_t, list);
@@ -303,8 +237,6 @@ static void add_slack_candidate(struct task_struct *task)
303 struct list_head *pos; 237 struct list_head *pos;
304 struct task_struct *queued; 238 struct task_struct *queued;
305 239
306 TRACE_TASK_SUB(task, "candidate added");
307
308 list_for_each_prev(pos, &slack_candidates) { 240 list_for_each_prev(pos, &slack_candidates) {
309 queued = get_candidate(pos); 241 queued = get_candidate(pos);
310 if (lt_before_eq(real_deadline(queued), real_deadline(task))) { 242 if (lt_before_eq(real_deadline(queued), real_deadline(task))) {
@@ -321,11 +253,8 @@ static void donate_slack(server_t *donator)
321 server_t *slack = (server_t*)donator->data; 253 server_t *slack = (server_t*)donator->data;
322 hrt_server_t *hrt_server; 254 hrt_server_t *hrt_server;
323 255
324 TRACE_SERVER_SUB(donator, "%llu slack donated", TIME(donator->budget));
325
326 if (donator->type == S_HRT) { 256 if (donator->type == S_HRT) {
327 hrt_server = container_of(donator, hrt_server_t, server); 257 hrt_server = container_of(donator, hrt_server_t, server);
328 BUG_ON(!hrt_server->ready);
329 } 258 }
330 259
331 slack->wcet = donator->budget; 260 slack->wcet = donator->budget;
@@ -345,20 +274,15 @@ static noinline void check_donate_slack(server_t *donator, struct task_struct *w
345 hrt_server_t *hrt_server; 274 hrt_server_t *hrt_server;
346 int donate = 0; 275 int donate = 0;
347 276
348 TRACE_SERVER_SUB(donator, "checking donation");
349
350 if (!slack) 277 if (!slack)
351 return; 278 return;
352 279
353 /* Donating small amounts of slack will result in excess migrations */ 280 /* Donating small amounts of slack will result in excess migrations */
354 if (donator->budget < SLACK_MIN) 281 if (donator->budget < SLACK_MIN || server_has_slack(donator))