aboutsummaryrefslogtreecommitdiffstats
path: root/bin/rt_skeleton_ms.c
diff options
context:
space:
mode:
authorStephen Tang <sytang@cs.unc.edu>2017-04-03 20:31:46 -0400
committerStephen Tang <sytang@cs.unc.edu>2017-04-03 20:31:46 -0400
commitbfee87a910560e022b04c81a026b1f88522cd62f (patch)
treece618ffafaf8f89971faa75f71cc17dda6878c9d /bin/rt_skeleton_ms.c
parent1ae58b9a30fbacd3ba5a1a62f40cb669cc51559a (diff)
Added benchmarks and user tasks
Diffstat (limited to 'bin/rt_skeleton_ms.c')
-rw-r--r--bin/rt_skeleton_ms.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/bin/rt_skeleton_ms.c b/bin/rt_skeleton_ms.c
new file mode 100644
index 0000000..d545635
--- /dev/null
+++ b/bin/rt_skeleton_ms.c
@@ -0,0 +1,282 @@
1#include <sys/time.h>
2#include <sys/mman.h>
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <time.h>
8#include <string.h>
9#include <assert.h>
10#include <limits.h>
11
12
13#include "litmus.h"
14#include "common.h"
15
16extern int main_job(void);
17static char* progname;
18
19static void usage(char *error) {
20 fprintf(stderr, "Error: %s\n", error);
21 fprintf(stderr,
22 "Usage:\n"
23 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
24 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
25 " rt_spin -l\n"
26 "\n"
27 "COMMON-OPTS = [-w] [-s SCALE]\n"
28 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
29 " [-X LOCKING-PROTOCOL] [-L CRITICAL SECTION LENGTH] [-Q RESOURCE-ID]\n"
30 "\n"
31 "WCET and PERIOD are milliseconds, DURATION is seconds.\n"
32 "CRITICAL SECTION LENGTH is in milliseconds.\n");
33 exit(EXIT_FAILURE);
34}
35
36static int job(double exec_time, double program_end, int lock_od, double cs_length)
37{
38 if (wctime() > program_end)
39 return 0;
40 else {
41 main_job();
42 sleep_next_period();
43 return 1;
44 }
45}
46
47#define OPTSTR "p:c:wves:q:X:L:Q:vh:m:i:b:"
48int main(int argc, char** argv)
49{
50 int ret;
51 lt_t wcet;
52 lt_t period;
53 lt_t hyperperiod;
54 lt_t budget;
55 double wcet_ms, period_ms, hyperperiod_ms, budget_ms;
56 unsigned int priority = LITMUS_NO_PRIORITY;
57 int migrate = 0;
58 int cluster = 0;
59 int opt;
60 int wait = 0;
61 int want_enforcement = 0;
62 double duration = 0, start = 0;
63 double scale = 1.0;
64 task_class_t class = RT_CLASS_HARD;
65 struct rt_task param;
66 struct mc2_task mc2_param;
67 struct reservation_config config;
68 int res_type = PERIODIC_POLLING;
69
70 int verbose = 0;
71 unsigned int job_no;
72
73 /* locking */
74 int lock_od = -1;
75 int resource_id = 0;
76 const char *lock_namespace = "./rtspin-locks";
77 int protocol = -1;
78 double cs_length = 1; /* millisecond */
79
80 progname = argv[0];
81
82 /* default for reservation */
83 config.id = 0;
84 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
85 config.cpu = -1;
86
87 mc2_param.crit = CRIT_LEVEL_C;
88
89 hyperperiod_ms = 1000;
90 budget_ms = 10;
91
92 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
93 switch (opt) {
94 case 'w':
95 wait = 1;
96 break;
97 case 'p':
98 cluster = atoi(optarg);
99 migrate = 1;
100 config.cpu = cluster;
101 break;
102 case 'q':
103 priority = atoi(optarg);
104 if (!litmus_is_valid_fixed_prio(priority))
105 usage("Invalid priority.");
106 break;
107 case 'c':
108 class = str2class(optarg);
109 if (class == -1)
110 usage("Unknown task class.");
111 break;
112 case 'e':
113 want_enforcement = 1;
114 break;
115 case 's':
116 scale = atof(optarg);
117 break;
118 case 'X':
119 protocol = lock_protocol_for_name(optarg);
120 if (protocol < 0)
121 usage("Unknown locking protocol specified.");
122 break;
123 case 'L':
124 cs_length = atof(optarg);
125 if (cs_length <= 0)
126 usage("Invalid critical section length.");
127 break;
128 case 'Q':
129 resource_id = atoi(optarg);
130 if (resource_id <= 0 && strcmp(optarg, "0"))
131 usage("Invalid resource ID.");
132 break;
133 case 'v':
134 verbose = 1;
135 break;
136 case 'm':
137 mc2_param.crit = atoi(optarg);
138 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
139 usage("Invalid criticality level.");
140 }
141 res_type = PERIODIC_POLLING;
142 break;
143 case 'h':
144 hyperperiod_ms = atof(optarg);
145 break;
146 case 'b':
147 budget_ms = atof(optarg);
148 break;
149 case 'i':
150 config.priority = atoi(optarg);
151 break;
152 case ':':
153 usage("Argument missing.");
154 break;
155 case '?':
156 default:
157 usage("Bad argument.");
158 break;
159 }
160 }
161
162 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
163 usage("Bad criticailty level or priority");
164
165 if (argc - optind < 3)
166 usage("Arguments missing.");
167
168 wcet_ms = atof(argv[optind + 0]);
169 period_ms = atof(argv[optind + 1]);
170
171 wcet = ms2ns(wcet_ms);
172 period = ms2ns(period_ms);
173 budget = ms2ns(budget_ms);
174 hyperperiod = ms2ns(hyperperiod_ms);
175
176 if (wcet <= 0)
177 usage("The worst-case execution time must be a "
178 "positive number.");
179 if (period <= 0)
180 usage("The period must be a positive number.");
181 if (wcet > period) {
182 usage("The worst-case execution time must not "
183 "exceed the period.");
184 }
185
186 duration = atof(argv[optind + 2]);
187
188 if (migrate) {
189 ret = be_migrate_to_domain(cluster);
190 if (ret < 0)
191 bail_out("could not migrate to target partition or cluster.");
192 }
193
194 /* reservation config */
195 config.id = gettid();
196
197 if (hyperperiod%period != 0 ) {
198 ;//bail_out("hyperperiod must be multiple of period");
199 }
200
201 config.polling_params.budget = budget;
202 config.polling_params.period = period;
203 config.polling_params.offset = 0;
204 config.polling_params.relative_deadline = 0;
205 if (config.polling_params.budget > config.polling_params.period) {
206 usage("The budget must not exceed the period.");
207 }
208
209 /* create a reservation */
210 ret = reservation_create(res_type, &config);
211 if (ret < 0) {
212 bail_out("failed to create reservation.");
213 }
214
215 init_rt_task_param(&param);
216 param.exec_cost = wcet;
217 param.period = period;
218 param.priority = priority;
219 param.cls = class;
220 param.release_policy = TASK_PERIODIC;
221 param.budget_policy = (want_enforcement) ?
222 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
223 if (migrate) {
224 param.cpu = gettid();
225 }
226 ret = set_rt_task_param(gettid(), &param);
227
228 if (ret < 0)
229 bail_out("could not setup rt task params");
230
231 mc2_param.res_id = gettid();
232 ret = set_mc2_task_param(gettid(), &mc2_param);
233//printf("SET_MC2_TASK\n");
234 if (ret < 0)
235 bail_out("could not setup mc2 task params");
236
237 init_litmus();
238//printf("CALL\n");
239 set_page_color(config.cpu);
240//printf("CALL\n");
241
242//printf("INIT_LITMUS\n");
243 start = wctime();
244 ret = task_mode(LITMUS_RT_TASK);
245//printf("TASK_MODE\n");
246 if (ret != 0)
247 bail_out("could not become RT task");
248
249 if (protocol >= 0) {
250 lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cluster);
251 if (lock_od < 0) {
252 perror("litmus_open_lock");
253 usage("Could not open lock.");
254 }
255 }
256
257
258 if (wait) {
259//printf("BEFORE WAIT\n");
260 ret = wait_for_ts_release();
261 if (ret != 0)
262 bail_out("wait_for_ts_release()");
263 start = wctime();
264 }
265
266 do {
267 if (verbose) {
268 get_job_no(&job_no);
269 printf("rtspin/%d:%u @ %.4fms\n", gettid(),
270 job_no, (wctime() - start) * 1000);
271 }
272 } while (job(wcet_ms * 0.001 * scale, start + duration,
273 lock_od, cs_length * 0.001));
274
275 ret = task_mode(BACKGROUND_TASK);
276 if (ret != 0)
277 bail_out("could not become regular task (huh?)");
278
279 reservation_destroy(gettid(), config.cpu);
280printf("%s/%d finished.\n",progname, gettid());
281 return 0;
282}