aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-06-15 16:35:17 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-06-15 16:36:07 -0400
commit046f99f037d0c862e7bab8856169aa742c8ad65f (patch)
treefb3dddf968d71025435417a4253b5d0176db341d
parent2c34274eb9dca67c916fc8f5d3b6f20bb17202c4 (diff)
[EDF-fm] Add rt_launch_edffm and support for edffm task creation
-rw-r--r--SConstruct1
-rw-r--r--bin/rt_launch_edffm.c133
-rw-r--r--bin/rtspin_edffm.c2
-rw-r--r--include/litmus.h3
-rw-r--r--src/task.c29
5 files changed, 167 insertions, 1 deletions
diff --git a/SConstruct b/SConstruct
index 7ae2883..c0a5f6e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -209,6 +209,7 @@ mtrt.Program('base_mt_task', 'bin/base_mt_task.c')
209rt.Program('rt_launch', ['bin/rt_launch.c', 'bin/common.c']) 209rt.Program('rt_launch', ['bin/rt_launch.c', 'bin/common.c'])
210rt.Program('rtspin', ['bin/rtspin.c', 'bin/common.c']) 210rt.Program('rtspin', ['bin/rtspin.c', 'bin/common.c'])
211rt.Program('rtspin_edffm', ['bin/rtspin_edffm.c', 'bin/common.c']) 211rt.Program('rtspin_edffm', ['bin/rtspin_edffm.c', 'bin/common.c'])
212rt.Program('rt_launch_edffm', ['bin/rt_launch_edffm.c', 'bin/common.c'])
212rt.Program('release_ts', 'bin/release_ts.c') 213rt.Program('release_ts', 'bin/release_ts.c')
213rtm.Program('measure_syscall', 'bin/null_call.c') 214rtm.Program('measure_syscall', 'bin/null_call.c')
214 215
diff --git a/bin/rt_launch_edffm.c b/bin/rt_launch_edffm.c
new file mode 100644
index 0000000..fcb895e
--- /dev/null
+++ b/bin/rt_launch_edffm.c
@@ -0,0 +1,133 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <limits.h>
6#include <signal.h>
7
8#include "litmus.h"
9#include "common.h"
10
11typedef struct {
12 int wait;
13 char * exec_path;
14 char ** argv;
15} startup_info_t;
16
17
18int launch(void *task_info_p) {
19 startup_info_t *info = (startup_info_t*) task_info_p;
20 int ret;
21 if (info->wait) {
22 ret = wait_for_ts_release();
23 if (ret != 0)
24 perror("wait_for_ts_release()");
25 }
26 ret = execvp(info->exec_path, info->argv);
27 perror("execv failed");
28 return ret;
29}
30
31void usage(char *error) {
32 fprintf(stderr, "%s\nUsage: rt_launch [-w][-v][-p cpu][-c hrt | srt | be] wcet period"
33 " fracnum1 fracden2 fracnum2 fracden2 cpu1 cpu2 program [arg1 arg2 ...]\n"
34 "\t-w\tSynchronous release\n"
35 "\t-v\tVerbose\n"
36 "\t-p\tcpu (or initial cpu)\n"
37 "\t-c\tClass\n"
38 "\twcet, period in ms\n"
39 "\tprogram to be launched\n",
40 error);
41 exit(1);
42}
43
44
45#define OPTSTR "p:c:vw"
46
47int main(int argc, char** argv)
48{
49 int ret;
50 lt_t wcet;
51 lt_t period;
52 /* [num,den] */
53 lt_t frac1[2], frac2[2];
54 int cpu1, cpu2;
55 int migrate = 0;
56 int cpu = 0;
57 int opt;
58 int verbose = 0;
59 int wait = 0;
60 startup_info_t info;
61 task_class_t class = RT_CLASS_HARD;
62
63 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
64 switch (opt) {
65 case 'w':
66 wait = 1;
67 break;
68 case 'v':
69 verbose = 1;
70 break;
71 case 'p':
72 cpu = atoi(optarg);
73 migrate = 1;
74 break;
75 case 'c':
76 class = str2class(optarg);
77 if (class == -1)
78 usage("Unknown task class.");
79 break;
80
81 case ':':
82 usage("Argument missing.");
83 break;
84 case '?':
85 default:
86 usage("Bad argument.");
87 break;
88 }
89 }
90
91 signal(SIGUSR1, SIG_IGN);
92
93 if (argc - optind < 8)
94 usage("Arguments missing.");
95 wcet = ms2lt(atoi(argv[optind + 0]));
96 period = ms2lt(atoi(argv[optind + 1]));
97 /* frac num, den = 0 means fixed task */
98 frac1[0] = atoi(argv[optind + 2]);
99 frac1[1] = atoi(argv[optind + 3]);
100 frac2[0] = atoi(argv[optind + 4]);
101 frac2[1] = atoi(argv[optind + 5]);
102 cpu1 = atoi(argv[optind + 6]);
103 cpu2 = atoi(argv[optind + 7]);
104 if (wcet <= 0)
105 usage("The worst-case execution time must be a "
106 "positive number.");
107 if (period <= 0)
108 usage("The period must be a positive number.");
109 if (wcet > period) {
110 usage("The worst-case execution time must not "
111 "exceed the period.");
112 }
113 info.exec_path = argv[optind + 8];
114 info.argv = argv + optind + 8;
115 info.wait = wait;
116 if (migrate) {
117 ret = be_migrate_to(cpu);
118 if (ret < 0)
119 bail_out("could not migrate to target partition");
120 }
121 /* create in src/task.c a new wrapper for the __launch_rt_task
122 * which takes the fraction and the cpus */
123 ret = __create_rt_task_edffm(launch, &info, cpu, wcet, period, frac1,
124 frac2, cpu1, cpu2, class);
125
126
127 if (ret < 0)
128 bail_out("could not create rt child process");
129 else if (verbose)
130 printf("%d\n", ret);
131
132 return 0;
133}
diff --git a/bin/rtspin_edffm.c b/bin/rtspin_edffm.c
index 04dce0a..d28d028 100644
--- a/bin/rtspin_edffm.c
+++ b/bin/rtspin_edffm.c
@@ -201,7 +201,7 @@ int main(int argc, char** argv)
201 return 0; 201 return 0;
202 } 202 }
203 203
204 if (argc - optind < 3) 204 if (argc - optind < 9)
205 usage("Arguments missing."); 205 usage("Arguments missing.");
206 wcet_ms = atof(argv[optind + 0]); 206 wcet_ms = atof(argv[optind + 0]);
207 period_ms = atof(argv[optind + 1]); 207 period_ms = atof(argv[optind + 1]);
diff --git a/include/litmus.h b/include/litmus.h
index e27b10d..3aa790f 100644
--- a/include/litmus.h
+++ b/include/litmus.h
@@ -90,6 +90,9 @@ typedef int (*rt_fn_t)(void*);
90int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period); 90int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period);
91int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, 91int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet,
92 int period, task_class_t cls); 92 int period, task_class_t cls);
93int __create_rt_task_edffm(rt_fn_t rt_prog, void *arg, int cpu, int wcet,
94 int period, lt_t *frac1, lt_t *frac2,
95 int cpu1, int cpu2, task_class_t class);
93 96
94/* per-task modes */ 97/* per-task modes */
95enum rt_task_mode_t { 98enum rt_task_mode_t {
diff --git a/src/task.c b/src/task.c
index 4d237bd..905ab9c 100644
--- a/src/task.c
+++ b/src/task.c
@@ -40,6 +40,35 @@ int __launch_rt_task(rt_fn_t rt_prog, void *rt_arg, rt_setup_fn_t setup,
40 return rt_task; 40 return rt_task;
41} 41}
42 42
43int __create_rt_task_edffm(rt_fn_t rt_prog, void *arg, int cpu, int wcet,
44 int period, lt_t *frac1, lt_t *frac2,
45 int cpu1, int cpu2, task_class_t class)
46{
47 struct rt_task params;
48 params.cpu = cpu;
49 params.period = period;
50 params.exec_cost = wcet;
51 params.cls = class;
52 params.phase = 0;
53 /* enforce budget for tasks that might not use sleep_next_period() */
54 params.budget_policy = QUANTUM_ENFORCEMENT;
55
56 /* edf-fm check on denominators for migratory tasks */
57 if (frac1[1] != 0 && frac2[1] != 0) {
58 /* edf-fm migrat task */
59 params.nr_cpus = 1;
60 params.cpus[0] = cpu1;
61 params.cpus[1] = cpu2;
62 params.fraction[0][0] = frac1[0];
63 params.fraction[1][0] = frac1[1];
64 params.fraction[0][1] = frac2[0];
65 params.fraction[1][1] = frac2[1];
66 }
67
68 return __launch_rt_task(rt_prog, arg,
69 (rt_setup_fn_t) set_rt_task_param, &params);
70}
71
43int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, 72int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period,
44 task_class_t class) 73 task_class_t class)
45{ 74{