aboutsummaryrefslogtreecommitdiffstats
path: root/bin/mode_skeleton.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/mode_skeleton.c')
-rw-r--r--bin/mode_skeleton.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/bin/mode_skeleton.c b/bin/mode_skeleton.c
new file mode 100644
index 0000000..cae5851
--- /dev/null
+++ b/bin/mode_skeleton.c
@@ -0,0 +1,256 @@
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);
17
18static char* progname;
19int loops = 10;
20//struct timeval t1, t2;
21
22static void usage(char *error) {
23 fprintf(stderr, "Error: %s\n", error);
24 fprintf(stderr,
25 "Usage:\n"
26 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
27 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
28 " rt_spin -l\n"
29 "\n"
30 "COMMON-OPTS = [-w] [-s SCALE]\n"
31 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
32 "\n"
33 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
34 exit(EXIT_FAILURE);
35}
36
37inline unsigned long get_cyclecount (void)
38{
39 unsigned long value;
40 // Read CCNT Register
41 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
42 return value;
43}
44
45static int job(double exec_time, double program_end)
46{
47 if (wctime() > program_end)
48 return 0;
49 else {
50 register int iter = 0;
51 //register unsigned long t;
52 //t = get_cyclecount();
53 //gettimeofday(&t1, NULL);
54 while (iter++ < loops) {
55 main_job();
56 }
57 //t = get_cyclecount() - t;
58 //printf("%ld cycles\n", t);
59 //gettimeofday(&t2, NULL);
60 //printf("%ld us\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
61 sleep_next_period();
62 return 1;
63 }
64}
65
66#define OPTSTR "p:wves:l:m:i:b:k:"
67int main(int argc, char** argv)
68{
69 int ret;
70 lt_t wcet;
71 lt_t period;
72 lt_t budget;
73 double wcet_us, period_us, budget_us;
74 unsigned int priority = LITMUS_NO_PRIORITY;
75 int migrate = 0;
76 int cluster = 0;
77 int opt;
78 int wait = 0;
79 int want_enforcement = 0;
80 double duration = 0, start = 0;
81 double scale = 1.0;
82 task_class_t class = RT_CLASS_HARD;
83 struct rt_task param;
84 struct mc2_task mc2_param;
85 struct reservation_config config;
86 int res_type = PERIODIC_POLLING;
87 uint32_t mode_mask = (1 << 0);
88 int i;
89 unsigned int job_no;
90
91
92 progname = argv[0];
93
94 /* default for reservation */
95 config.id = 0;
96 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
97 config.cpu = -1;
98
99 mc2_param.crit = CRIT_LEVEL_C;
100
101 budget_us = 10000;
102
103 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
104 switch (opt) {
105 case 'w':
106 wait = 1;
107 break;
108 case 'p':
109 cluster = atoi(optarg);
110 migrate = 1;
111 config.cpu = cluster;
112 break;
113 case 'e':
114 want_enforcement = 1;
115 break;
116 case 's':
117 scale = atof(optarg);
118 break;
119 case 'l':
120 loops = atoi(optarg);
121 break;
122 case 'm':
123 mc2_param.crit = atoi(optarg);
124 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
125 usage("Invalid criticality level.");
126 }
127 res_type = PERIODIC_POLLING;
128 break;
129 case 'b':
130 budget_us = atof(optarg);
131 break;
132 case 'i':
133 config.priority = atoi(optarg);
134 break;
135 case 'k':
136 mode_mask = atoi(optarg);
137 case ':':
138 usage("Argument missing.");
139 break;
140 case '?':
141 default:
142 usage("Bad argument.");
143 break;
144 }
145 }
146
147 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
148 usage("Bad criticailty level or priority");
149
150 if (argc - optind < 3)
151 usage("Arguments missing.");
152
153 wcet_us = atof(argv[optind + 0]);
154 period_us = atof(argv[optind + 1]);
155
156 wcet = us2ns(wcet_us);
157 period = us2ns(period_us);
158 budget = us2ns(budget_us);
159
160 if (wcet <= 0)
161 usage("The worst-case execution time must be a "
162 "positive number.");
163 if (period <= 0)
164 usage("The period must be a positive number.");
165 if (wcet > period) {
166 usage("The worst-case execution time must not "
167 "exceed the period.");
168 }
169
170 duration = atof(argv[optind + 2]);
171
172 if (migrate) {
173 ret = be_migrate_to_domain(cluster);
174 if (ret < 0)
175 bail_out("could not migrate to target partition or cluster.");
176 }
177
178 /* reservation config */
179 config.id = gettid();
180
181 config.polling_params.budget = budget;
182 config.polling_params.period = period;
183 config.polling_params.offset = 0;
184 config.polling_params.relative_deadline = 0;
185 if (config.polling_params.budget > config.polling_params.period) {
186 usage("The budget must not exceed the period.");
187 }
188
189 /* create reservations */
190 for(i = 0; i < 32; i++){
191 if ( !((1 << i) & mode_mask ) )
192 continue;
193 config.mode = i;
194 ret = reservation_create(res_type, &config);
195 if (ret < 0) {
196 bail_out("failed to create reservation.");
197 }
198 }
199
200 init_rt_task_param(&param);
201 param.exec_cost = wcet;
202 param.period = period;
203 param.priority = priority;
204 param.cls = class;
205 param.release_policy = TASK_PERIODIC;
206 param.budget_policy = (want_enforcement) ?
207 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
208 if (migrate) {
209 param.cpu = gettid();
210 }
211 ret = set_rt_task_param(gettid(), &param);
212
213 if (ret < 0)
214 bail_out("could not setup rt task params");
215
216 mc2_param.res_id = gettid();
217 mc2_param.mode_mask = mode_mask;
218 ret = set_mc2_task_param(gettid(), &mc2_param);
219//printf("SET_MC2_TASK\n");
220 if (ret < 0)
221 bail_out("could not setup mc2 task params");
222
223 init_litmus();
224//printf("CALL\n");
225 if (mc2_param.crit == CRIT_LEVEL_C)
226 set_page_color(8);
227 else if (mc2_param.crit < CRIT_LEVEL_C)
228 set_page_color(config.cpu*2 + mc2_param.crit);
229//printf("CALL\n");
230
231//printf("INIT_LITMUS\n");
232 start = wctime();
233 ret = task_mode(LITMUS_RT_TASK);
234//printf("TASK_MODE\n");
235 if (ret != 0)
236 bail_out("could not become RT task");
237
238
239 if (wait) {
240//printf("BEFORE WAIT\n");
241 ret = wait_for_ts_release();
242 if (ret != 0)
243 bail_out("wait_for_ts_release()");
244 start = wctime();
245 }
246
247 while (job(wcet_us * 0.000001 * scale, start + duration)) {};
248
249 ret = task_mode(BACKGROUND_TASK);
250 if (ret != 0)
251 bail_out("could not become regular task (huh?)");
252
253 reservation_destroy(gettid(), config.cpu);
254 printf("%s/%d finished.\n",progname, gettid());
255 return 0;
256}