aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-09-22 12:51:06 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2011-01-26 18:20:24 -0500
commit87ef92f3665b9bb4250ec42b5295bd5639b71013 (patch)
tree8756c795b0a225c1b348159120f891a5bc113814
parent289b53f7b55a30c054e4a2fb7b19fa2cbcf27703 (diff)
Add rt_launch_edfwm launcher
As rtspin_edfwm rt_launch_edfwm reads each task information from a text file (same format as rtspin_edfwm).
-rw-r--r--SConstruct1
-rw-r--r--bin/rt_launch_edfwm.c182
-rw-r--r--include/litmus.h6
-rw-r--r--src/task.c5
4 files changed, 194 insertions, 0 deletions
diff --git a/SConstruct b/SConstruct
index 1f4770a..9935396 100644
--- a/SConstruct
+++ b/SConstruct
@@ -214,6 +214,7 @@ rt.Program('rtspin_npsf', ['bin/rtspin_npsf.c', 'bin/common.c'])
214rt.Program('npsf_add_server', ['bin/npsf_add_server.c', 'bin/common.c']) 214rt.Program('npsf_add_server', ['bin/npsf_add_server.c', 'bin/common.c'])
215rt.Program('rt_launch_npsf', ['bin/rt_launch_npsf.c', 'bin/common.c']) 215rt.Program('rt_launch_npsf', ['bin/rt_launch_npsf.c', 'bin/common.c'])
216rt.Program('rtspin_edfwm', ['bin/rtspin_edfwm.c', 'bin/common.c']) 216rt.Program('rtspin_edfwm', ['bin/rtspin_edfwm.c', 'bin/common.c'])
217rt.Program('rt_launch_edfwm', ['bin/rt_launch_edfwm.c', 'bin/common.c'])
217rt.Program('release_ts', 'bin/release_ts.c') 218rt.Program('release_ts', 'bin/release_ts.c')
218rtm.Program('measure_syscall', 'bin/null_call.c') 219rtm.Program('measure_syscall', 'bin/null_call.c')
219 220
diff --git a/bin/rt_launch_edfwm.c b/bin/rt_launch_edfwm.c
new file mode 100644
index 0000000..de65585
--- /dev/null
+++ b/bin/rt_launch_edfwm.c
@@ -0,0 +1,182 @@
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"
10typedef struct {
11 int wait;
12 char * exec_path;
13 char ** argv;
14} startup_info_t;
15
16
17int launch(void *task_info_p) {
18 startup_info_t *info = (startup_info_t*) task_info_p;
19 int ret;
20 if (info->wait) {
21 ret = wait_for_ts_release();
22 if (ret != 0)
23 perror("wait_for_ts_release()");
24 }
25 ret = execvp(info->exec_path, info->argv);
26 perror("execv failed");
27 return ret;
28}
29
30void usage(char *error) {
31 fprintf(stderr, "%s\nUsage: rt_launch [-w] task_parameters_file "
32 "program [arg1 arg2 ...]\n"
33 "\t-w\tSynchronous release\n"
34 "\tprogram to be launched\n",
35 error);
36 exit(1);
37}
38
39#define fms_to_ns(x) (lt_t)(((x) * __NS_PER_MS))
40/*
41 * <task_id, cpu, deadline (from job release), budget, offset> .
42 */
43int parse_edfwm_slice(FILE *ts, int slices_no, int task_id,
44 struct edf_wm_params *wm)
45{
46 int i, tid;
47 unsigned int cpu;
48 double deadline, budget, offset;
49
50 for (i = 0; i < slices_no; i++) {
51
52 if (fscanf(ts, "%d %u %lf %lf %lf\n", &tid, &cpu,
53 &deadline, &budget, &offset) != EOF) {
54
55 printf("slice(tid, cpu, d, e, ph) = (%d, %u, %lf, %lf, %lf)\n",
56 tid, cpu, deadline, budget, offset);
57
58 if (task_id != tid) {
59 fprintf(stderr, "task_id %d != tid %d\n",
60 task_id, tid);
61 return -1;
62 }
63
64 wm->slices[i].deadline = fms_to_ns(deadline);
65 wm->slices[i].budget = fms_to_ns(budget);
66 wm->slices[i].offset = fms_to_ns(offset);
67 }
68 if (ferror(ts)) {
69 fprintf(stderr, "Cannot read file\n");
70 return -1;
71 }
72 }
73 return 1;
74}
75
76/* Custom format to read parameters for tasks from a plain text file:
77 * <task_id, execution_cost, period, phase, cpu, slices_number> .
78 * If the task is split on multiple slices, slices_number is non 0
79 * and we scan a list of slice parameters up to slices_number:
80 * <task_id, cpu, deadline (from job release), budget, offset> .
81 * The offset is the start time for the slice relative to the job release.
82 *
83 * FIXME: this function should go in a separate file where all the parsing
84 * funtions for the semi-part plugins are. It will help in later testing with
85 * "tasks" programs.
86 */
87int parse_edfwm_ts_file(FILE *ts, struct rt_task *rt)
88{
89 int task_id, ret = 1;
90 unsigned int cpu, sliceno;
91 double fwcet, fperiod, fphase;
92
93 ret = fscanf(ts, "%d %lf %lf %lf %d %d\n",
94 &task_id, &fwcet, &fperiod, &fphase, &cpu, &sliceno);
95
96 if (ret != EOF) {
97
98 printf("(tid, wcet, period, ph, cpu, slices) = "
99 "(%d, %.2f, %.2f, %.2f, %u, %u)\n",
100 task_id, fwcet, fperiod, fphase, cpu, sliceno);
101
102 rt->exec_cost = fms_to_ns(fwcet);
103 rt->period = fms_to_ns(fperiod);
104 rt->phase = fms_to_ns(fphase);
105 rt->cpu = cpu;
106 rt->cls = RT_CLASS_HARD;
107 rt->budget_policy = PRECISE_ENFORCEMENT;
108 if (sliceno > 0) {
109 ret = parse_edfwm_slice(ts, sliceno, task_id,
110 (struct edf_wm_params*) &rt->semi_part);
111 if (ret < 0)
112 goto err;
113 }
114 }
115 if (ferror(ts))
116 goto err;
117
118 return EOF;
119
120err:
121 fprintf(stderr, "Error parsing file\n");
122 return -1;
123}
124
125#define OPTSTR "w"
126
127int main(int argc, char** argv)
128{
129 int ret;
130 int wait = 0;
131 int opt;
132 startup_info_t info;
133
134 struct rt_task rt;
135 FILE *file;
136
137 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
138 switch (opt) {
139 case 'w':
140 wait = 1;
141 break;
142 case ':':
143 usage("Argument missing.");
144 break;
145 case '?':
146 default:
147 usage("Bad argument.");
148 break;
149 }
150 }
151
152 signal(SIGUSR1, SIG_IGN);
153
154 if (argc - optind < 2)
155 usage("Arguments missing.");
156
157 if ((file = fopen(argv[optind + 0], "r")) == NULL) {
158 fprintf(stderr, "Cannot open %s\n", argv[1]);
159 return -1;
160 }
161
162 memset(&rt, 0, sizeof(struct rt_task));
163
164 while (parse_edfwm_ts_file(file, &rt) != EOF) {
165
166 if (sporadic_task_ns_semi(&rt) < 0)
167 bail_out("could not setup rt task params");
168 }
169
170 fclose(file);
171
172 info.exec_path = argv[optind + 1];
173 info.argv = argv + optind + 1;
174 info.wait = wait;
175
176 ret = create_rt_task_semi(launch, &info, &rt);
177
178 if (ret < 0)
179 bail_out("could not create rt child process");
180
181 return 0;
182}
diff --git a/include/litmus.h b/include/litmus.h
index fd40e87..9179ca6 100644
--- a/include/litmus.h
+++ b/include/litmus.h
@@ -105,6 +105,12 @@ int __create_rt_task_edffm(rt_fn_t rt_prog, void *arg, int cpu, int wcet,
105int __create_rt_task_npsf(rt_fn_t rt_prog, void *arg, int cpu, int wcet, 105int __create_rt_task_npsf(rt_fn_t rt_prog, void *arg, int cpu, int wcet,
106 int period, int npsf_id, task_class_t class); 106 int period, int npsf_id, task_class_t class);
107 107
108/* wrapper to mask __launch_rt_task() for semi-partitioned algorithms
109 * (it can be extended to cover all algorithms that directly submit
110 * an rt_task structure instead of a set of values).
111 */
112int create_rt_task_semi(rt_fn_t rt_prog, void *arg, struct rt_task *params);
113
108/* per-task modes */ 114/* per-task modes */
109enum rt_task_mode_t { 115enum rt_task_mode_t {
110 BACKGROUND_TASK = 0, 116 BACKGROUND_TASK = 0,
diff --git a/src/task.c b/src/task.c
index 9f6db5e..8621aa2 100644
--- a/src/task.c
+++ b/src/task.c
@@ -106,6 +106,11 @@ int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period) {
106 return __create_rt_task(rt_prog, arg, cpu, wcet, period, RT_CLASS_HARD); 106 return __create_rt_task(rt_prog, arg, cpu, wcet, period, RT_CLASS_HARD);
107} 107}
108 108
109int create_rt_task_semi(rt_fn_t rt_prog, void *arg, struct rt_task *params)
110{
111 return __launch_rt_task(rt_prog, arg,
112 (rt_setup_fn_t) set_rt_task_param, params);
113}
109 114
110#define SCHED_NORMAL 0 115#define SCHED_NORMAL 0
111#define SCHED_LITMUS 6 116#define SCHED_LITMUS 6