aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2014-05-09 05:11:35 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2014-06-03 02:38:40 -0400
commit4cc5780a04d827e075a383b2c37a7fca304c3607 (patch)
tree65cd2b416e14fa85e85c8dac6ab024b4f84e9f2a
parenta5df594496740ef2284fdaab8430af84e835ad57 (diff)
Modernize rt_launch; remove internal API cruft
Switch rt_launch to use a more modern way to launch real-time tasks. This makes rt_launch more flexible, makes it more similar to rtspin, and also allows to let us get rid of a chunk of old, inflexible code in liblitmus that wasn't really serving any useful purpose anymore.
-rw-r--r--bin/rt_launch.c172
-rw-r--r--include/internal.h5
-rw-r--r--include/litmus.h29
-rw-r--r--src/task.c58
4 files changed, 112 insertions, 152 deletions
diff --git a/bin/rt_launch.c b/bin/rt_launch.c
index 5e29893..c468b68 100644
--- a/bin/rt_launch.c
+++ b/bin/rt_launch.c
@@ -8,64 +8,63 @@
8#include "litmus.h" 8#include "litmus.h"
9#include "common.h" 9#include "common.h"
10 10
11typedef struct { 11const char *usage_msg =
12 int wait; 12 "Usage: rt_launch OPTIONS wcet period program [arg1 arg2 ...]\n"
13 char * exec_path; 13 " -w wait for synchronous release\n"
14 char ** argv; 14 " -v verbose (prints PID)\n"
15} startup_info_t; 15 " -p CPU physical partition or cluster to assign to\n"
16 16 " -r VCPU virtual CPU to attach to (irrelevant to most plugins)\n"
17 17 " -d DEADLINE relative deadline, implicit by default (in ms)\n"
18int launch(void *task_info_p) { 18 " -o OFFSET offset (also known as phase), zero by default (in ms)\n"
19 startup_info_t *info = (startup_info_t*) task_info_p; 19 " -q PRIORITY priority to use (ignored by EDF plugins, highest=1, lowest=511)\n"
20 int ret; 20 " -c be|srt|hrt task class (best-effort, soft real-time, hard real-time)\n"
21 if (info->wait) { 21 " -e turn off budget enforcement (DANGEROUS: can result in lockup)\n"
22 ret = wait_for_ts_release(); 22 " wcet, period reservation parameters (in ms)\n"
23 if (ret != 0) 23 " program path to the binary to be launched\n"
24 perror("wait_for_ts_release()"); 24 "\n";
25 }
26 ret = execvp(info->exec_path, info->argv);
27 perror("execv failed");
28 return ret;
29}
30 25
31void usage(char *error) { 26void usage(char *error) {
32 fprintf(stderr, "%s\nUsage: rt_launch [-w][-v][-p partition/cluster [-z cluster size]][-q prio][-c hrt | srt | be] wcet period program [arg1 arg2 ...]\n" 27 fprintf(stderr, "%s\n%s", error, usage_msg);
33 "\t-w\tSynchronous release\n"
34 "\t-v\tVerbose\n"
35 "\t-p\tpartition or cluster\n"
36 "\t-z\tsize of cluster (default = 1 for partitioned)\n"
37 "\t-c\tClass\n"
38 "\twcet, period in ms\n"
39 "\tprogram to be launched\n",
40 error);
41 exit(1); 28 exit(1);
42} 29}
43 30
31#define OPTSTR "wp:q:c:er:b:o:d:vh"
44 32
45#define OPTSTR "p:c:vwq:" 33int main(int argc, char** argv)
46
47int main(int argc, char** argv)
48{ 34{
49 int ret; 35 int ret, opt;
50 lt_t wcet; 36 lt_t wcet;
51 lt_t period; 37 lt_t period;
52 int migrate = 0; 38 lt_t offset;
53 int cluster = 0; 39 lt_t deadline;
54 int opt; 40 double wcet_ms, period_ms, offset_ms, deadline_ms;
55 int verbose = 0; 41 unsigned int priority;
56 int wait = 0; 42 int migrate;
57 startup_info_t info; 43 int cluster;
58 task_class_t class = RT_CLASS_HARD; 44 int reservation;
59 unsigned int priority = LITMUS_LOWEST_PRIORITY; 45 int wait;
46 int want_enforcement;
47 int verbose;
48 task_class_t class;
49 struct rt_task param;
50
51 /* Reasonable defaults */
52 verbose = 0;
53 offset_ms = 0;
54 deadline_ms = 0;
55 priority = LITMUS_LOWEST_PRIORITY;
56 want_enforcement = 1; /* safety: default to enforcement */
57 wait = 0; /* don't wait for task system release */
58 class = RT_CLASS_SOFT; /* ignored by most plugins */
59 migrate = 0; /* assume global unless -p is specified */
60 cluster = -1; /* where to migrate to, invalid by default */
61 reservation = -1; /* set if task should attach to virtual CPU */
60 62
61 while ((opt = getopt(argc, argv, OPTSTR)) != -1) { 63 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
62 switch (opt) { 64 switch (opt) {
63 case 'w': 65 case 'w':
64 wait = 1; 66 wait = 1;
65 break; 67 break;
66 case 'v':
67 verbose = 1;
68 break;
69 case 'p': 68 case 'p':
70 cluster = atoi(optarg); 69 cluster = atoi(optarg);
71 migrate = 1; 70 migrate = 1;
@@ -80,7 +79,28 @@ int main(int argc, char** argv)
80 if (class == -1) 79 if (class == -1)
81 usage("Unknown task class."); 80 usage("Unknown task class.");
82 break; 81 break;
83 82 case 'e':
83 want_enforcement = 0;
84 break;
85 case 'r':
86 reservation = atoi(optarg);
87 break;
88 case 'o':
89 offset_ms = atof(optarg);
90 break;
91 case 'd':
92 deadline_ms = atof(optarg);
93 if (!deadline_ms || deadline_ms < 0) {
94 usage("The relative deadline must be a positive"
95 " number.");
96 }
97 break;
98 case 'v':
99 verbose = 1;
100 break;
101 case 'h':
102 usage("");
103 break;
84 case ':': 104 case ':':
85 usage("Argument missing."); 105 usage("Argument missing.");
86 break; 106 break;
@@ -95,33 +115,65 @@ int main(int argc, char** argv)
95 115
96 if (argc - optind < 3) 116 if (argc - optind < 3)
97 usage("Arguments missing."); 117 usage("Arguments missing.");
98 wcet = ms2ns(atoi(argv[optind + 0])); 118
99 period = ms2ns(atoi(argv[optind + 1])); 119 wcet_ms = atof(argv[optind + 0]);
120 period_ms = atof(argv[optind + 1]);
121
122 wcet = ms2ns(wcet_ms);
123 period = ms2ns(period_ms);
124 offset = ms2ns(offset_ms);
125 deadline = ms2ns(deadline_ms);
100 if (wcet <= 0) 126 if (wcet <= 0)
101 usage("The worst-case execution time must be a " 127 usage("The worst-case execution time must be a "
102 "positive number."); 128 "positive number.");
103 if (period <= 0) 129 if (period <= 0)
104 usage("The period must be a positive number."); 130 usage("The period must be a positive number.");
105 if (wcet > period) { 131 if (wcet > period) {
106 usage("The worst-case execution time must not " 132 usage("The worst-case execution time must not "
107 "exceed the period."); 133 "exceed the period.");
108 } 134 }
109 info.exec_path = argv[optind + 2]; 135
110 info.argv = argv + optind + 2;
111 info.wait = wait;
112 if (migrate) { 136 if (migrate) {
113 ret = be_migrate_to_domain(cluster); 137 ret = be_migrate_to_domain(cluster);
114 if (ret < 0) 138 if (ret < 0)
115 bail_out("could not migrate to target partition or cluster"); 139 bail_out("could not migrate to target partition or cluster.");
116 } 140 }
117 ret = __create_rt_task(launch, &info, cluster, wcet, period,
118 priority, class);
119
120 141
142 init_rt_task_param(&param);
143 param.exec_cost = wcet;
144 param.period = period;
145 param.phase = offset;
146 param.relative_deadline = deadline;
147 param.priority = priority;
148 param.cls = class;
149 param.budget_policy = (want_enforcement) ?
150 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
151 if (migrate) {
152 if (reservation >= 0)
153 param.cpu = reservation;
154 else
155 param.cpu = domain_to_first_cpu(cluster);
156 }
157 ret = set_rt_task_param(gettid(), &param);
121 if (ret < 0) 158 if (ret < 0)
122 bail_out("could not create rt child process"); 159 bail_out("could not setup rt task params");
123 else if (verbose)
124 printf("%d\n", ret);
125 160
126 return 0; 161 init_litmus();
162
163 ret = task_mode(LITMUS_RT_TASK);
164 if (ret != 0)
165 bail_out("could not become RT task");
166