aboutsummaryrefslogtreecommitdiffstats
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
parent1ae58b9a30fbacd3ba5a1a62f40cb669cc51559a (diff)
Added benchmarks and user tasks
-rw-r--r--bin/mode_request.c13
-rw-r--r--bin/rt_compress.c283
-rw-r--r--bin/rt_field.c379
-rw-r--r--bin/rt_field_spin.c385
-rw-r--r--bin/rt_matrix.c851
-rw-r--r--bin/rt_matrix_spin.c833
-rw-r--r--bin/rt_mode_poll.c235
-rw-r--r--bin/rt_neighborhood.c381
-rw-r--r--bin/rt_neighborhood_spin.c337
-rw-r--r--bin/rt_pointer.c430
-rw-r--r--bin/rt_pointer_spin.c439
-rw-r--r--bin/rt_skeleton.c247
-rw-r--r--bin/rt_skeleton_ms.c282
-rw-r--r--bin/rt_skeleton_us.c282
-rw-r--r--bin/rt_transitive.c362
-rw-r--r--bin/rt_update.c387
-rw-r--r--bin/rt_update_spin.c398
17 files changed, 6524 insertions, 0 deletions
diff --git a/bin/mode_request.c b/bin/mode_request.c
new file mode 100644
index 0000000..a0b3226
--- /dev/null
+++ b/bin/mode_request.c
@@ -0,0 +1,13 @@
1#include "litmus.h"
2
3#define __NR_request_mode 408
4
5int main(int argc, char* argv){
6 int ret, req_mode;
7 if (argc < 2){
8 return -EINVAL;
9 }
10 req_mode = atoi(argv[1]);
11 ret = syscall(__NR_request_mode, req_mode);
12 return ret;
13}
diff --git a/bin/rt_compress.c b/bin/rt_compress.c
new file mode 100644
index 0000000..9647854
--- /dev/null
+++ b/bin/rt_compress.c
@@ -0,0 +1,283 @@
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
275printf("BEFORE BACK_TASK\n");
276 ret = task_mode(BACKGROUND_TASK);
277 if (ret != 0)
278 bail_out("could not become regular task (huh?)");
279
280 reservation_destroy(gettid(), config.cpu);
281
282 return 0;
283}
diff --git a/bin/rt_field.c b/bin/rt_field.c
new file mode 100644
index 0000000..ac79020
--- /dev/null
+++ b/bin/rt_field.c
@@ -0,0 +1,379 @@
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#include "litmus.h"
13#include "common.h"
14#include "DISstressmarkRNG.h"
15
16#define MIN_FIELD_SIZE 16
17#define MAX_FIELD_SIZE 16777216
18#define MIN_SEED -2147483647
19#define MAX_SEED -1
20#define MIN_MOD_OFFSET 0
21#define MAX_MOD_OFFSET 65535
22#define MIN_TOKENS 1
23#define MAX_TOKENS 256
24#define MIN_TOKEN_LENGTH 1
25#define MAX_TOKEN_LENGTH 8
26#define MIN_TOKEN_VALUE 0
27#define MAX_TOKEN_VALUE 255
28#define MAX_SUBFIELDS 256
29
30static char* progname;
31int loops = 1;
32
33struct timeval t1, t2;
34
35struct tokenS{
36 unsigned char delimiter[MAX_TOKEN_LENGTH];
37 unsigned char length;
38 struct statisticS{
39 unsigned int count;
40 unsigned char min;
41 unsigned char sum;
42 } stat[MAX_SUBFIELDS];
43 unsigned char subfields;
44} token[MAX_TOKENS];
45
46unsigned char *field;
47unsigned int f_max;
48int seed;
49int mod_offset;
50unsigned int n_max;
51
52unsigned char input_token[8] = {0x1, 0x1, 0x22, 0x1, 0xc2, 0x1, 0x2d, 0x0};
53
54int init_job(){
55 //fscanf(stdin, "%d %d %d %d", &f, &seed, &mod_offset, &n);
56 f_max = 262144;
57 seed = -2;
58 n_max = 128;
59
60 assert((seed >= MIN_SEED) && (seed <= MAX_SEED));
61
62 if ((field = (unsigned char*)malloc(f_max*sizeof(unsigned char))) == NULL)
63 return (-1);
64
65 randInit(seed);
66
67 return 0;
68}
69
70int main_job() {
71 unsigned int l, f, n;
72
73 /* for online */
74/* f = randInt(65536, f_max);
75 mod_offset = randInt(128, 8192);
76 n = 20; //randInt(64, n_max);
77*/
78
79 /* for case */
80
81 f = randInt(64, 18000);
82 mod_offset = randInt(128, 8192);
83 n = 1; //randInt(64, n_max);
84
85
86 assert((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE));
87 assert((mod_offset >= MIN_MOD_OFFSET) && (mod_offset <= MAX_MOD_OFFSET));
88 assert((n >= MIN_TOKENS) && (n <= MAX_TOKENS));
89
90 for (l=0; l<n; l++){
91 int index;
92 for (index = 0; index<MAX_TOKEN_LENGTH; index++) {
93 unsigned char x = input_token[index];
94 assert((x >= MIN_TOKEN_VALUE) && (x <= MAX_TOKEN_VALUE));
95 token[l].delimiter[index] = (unsigned char )x;
96 }
97 token[l].length = index;
98 }
99
100 for (l =0; l<f; l++){
101 field[l] = randInt(MIN_TOKEN_VALUE, MAX_TOKEN_VALUE);
102 }
103
104 for (l =0; l<n; l++){
105 unsigned int index;
106
107 token[l].subfields = 0;
108 token[l].stat[0].count = 0;
109 token[l].stat[0].sum = 0;
110 token[l].stat[0].min = MAX_TOKEN_VALUE;
111
112 index = 0;
113 while ((index < f) && (token[l].subfields < MAX_SUBFIELDS)){
114 unsigned char offset;
115 offset = 0;
116 while ((field[index+offset] == token[l].delimiter[offset]) &&
117 (offset < token[l].length)){
118 offset++;
119 }
120
121 if (offset == token[l].length){
122 for (offset=0; offset<token[l].length; offset++){
123 field[index+offset] = (field[index+offset] +
124 field[(index+offset+mod_offset) % f])
125 %(MAX_TOKEN_VALUE+1);
126 }
127 index += token[l].length-1;
128 token[l].subfields++;
129 token[l].stat[token[l].subfields].count = 0;
130 token[l].stat[token[l].subfields].sum = 0;
131 token[l].stat[token[l].subfields].min = MAX_TOKEN_VALUE;
132 }
133 else {
134 token[l].stat[token[l].subfields].count++;
135 token[l].stat[token[l].subfields].sum += field[index];
136 if (token[l].stat[token[l].subfields].min > field[index])
137 token[l].stat[token[l].subfields].min = field[index];
138 }
139 index++;
140 }
141 }
142
143 return 0;
144}
145
146int post_job() {
147 if (field) {
148 free(field);
149 field = NULL;
150 }
151
152 return(0);
153}
154
155static void usage(char *error) {
156 fprintf(stderr, "Error: %s\n", error);
157 fprintf(stderr,
158 "Usage:\n"
159 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
160 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
161 " rt_spin -l\n"
162 "\n"
163 "COMMON-OPTS = [-w] [-s SCALE]\n"
164 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
165 "\n"
166 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
167 exit(EXIT_FAILURE);
168}
169
170inline unsigned long get_cyclecount (void)
171{
172 unsigned long value;
173 // Read CCNT Register
174 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
175 return value;
176}
177
178static int job(double exec_time, double program_end)
179{
180 if (wctime() > program_end)
181 return 0;
182 else {
183 register int iter = 0;
184 //register unsigned long t;
185 //t = get_cyclecount();
186 //gettimeofday(&t1, NULL);
187 while (iter++ < loops) {
188 main_job();
189 }
190 //t = get_cyclecount() - t;
191 //printf("%ld cycles\n", t);
192 //gettimeofday(&t2, NULL);
193 //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
194 sleep_next_period();
195 return 1;
196 }
197}
198
199#define OPTSTR "p:wves:l:m:i:b:"
200int main(int argc, char** argv)
201{
202 int ret;
203 lt_t wcet;
204 lt_t period;
205 lt_t budget;
206 double wcet_ms, period_ms, budget_ms;
207 unsigned int priority = LITMUS_NO_PRIORITY;
208 int migrate = 0;
209 int cluster = 0;
210 int opt;
211 int wait = 0;
212 int want_enforcement = 0;
213 double duration = 0, start = 0;
214 double scale = 1.0;
215 task_class_t class = RT_CLASS_HARD;
216 struct rt_task param;
217 struct mc2_task mc2_param;
218 struct reservation_config config;
219 int res_type = PERIODIC_POLLING;
220
221 progname = argv[0];
222
223 /* default for reservation */
224 config.id = 0;
225 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
226 config.cpu = -1;
227
228 mc2_param.crit = CRIT_LEVEL_C;
229
230 budget_ms = 10;
231
232 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
233 switch (opt) {
234 case 'w':
235 wait = 1;
236 break;
237 case 'p':
238 cluster = atoi(optarg);
239 migrate = 1;
240 config.cpu = cluster;
241 break;
242 case 'e':
243 want_enforcement = 1;
244 break;
245 case 's':
246 scale = atof(optarg);
247 break;
248 case 'l':
249 loops = atoi(optarg);
250 break;
251 case 'm':
252 mc2_param.crit = atoi(optarg);
253 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
254 usage("Invalid criticality level.");
255 }
256 res_type = PERIODIC_POLLING;
257 break;
258 case 'b':
259 budget_ms = atof(optarg);
260 break;
261 case 'i':
262 config.priority = atoi(optarg);
263 break;
264 case ':':
265 usage("Argument missing.");
266 break;
267 case '?':
268 default:
269 usage("Bad argument.");
270 break;
271 }
272 }
273
274 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
275 usage("Bad criticailty level or priority");
276
277 if (argc - optind < 3)
278 usage("Arguments missing.");
279
280 wcet_ms = atof(argv[optind + 0]);
281 period_ms = atof(argv[optind + 1]);
282
283 wcet = ms2ns(wcet_ms);
284 period = ms2ns(period_ms);
285 budget = ms2ns(budget_ms);
286
287 if (wcet <= 0)
288 usage("The worst-case execution time must be a "
289 "positive number.");
290 if (period <= 0)
291 usage("The period must be a positive number.");
292 if (wcet > period) {
293 usage("The worst-case execution time must not "
294 "exceed the period.");
295 }
296
297 duration = atof(argv[optind + 2]);
298
299 if (migrate) {
300 ret = be_migrate_to_domain(cluster);
301 if (ret < 0)
302 bail_out("could not migrate to target partition or cluster.");
303 }
304
305 /* reservation config */
306 config.id = gettid();
307
308 config.polling_params.budget = budget;
309 config.polling_params.period = period;
310 config.polling_params.offset = 0;
311 config.polling_params.relative_deadline = 0;
312 if (config.polling_params.budget > config.polling_params.period) {
313 usage("The budget must not exceed the period.");
314 }
315
316 /* create a reservation */
317 ret = reservation_create(res_type, &config);
318 if (ret < 0) {
319 bail_out("failed to create reservation.");
320 }
321 init_job();
322
323 init_rt_task_param(&param);
324 param.exec_cost = wcet;
325 param.period = period;
326 param.priority = priority;
327 param.cls = class;
328 param.release_policy = TASK_PERIODIC;
329 param.budget_policy = (want_enforcement) ?
330 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
331 if (migrate) {
332 param.cpu = gettid();
333 }
334 ret = set_rt_task_param(gettid(), &param);
335
336 if (ret < 0)
337 bail_out("could not setup rt task params");
338
339 mc2_param.res_id = gettid();
340 ret = set_mc2_task_param(gettid(), &mc2_param);
341//printf("SET_MC2_TASK\n");
342 if (ret < 0)
343 bail_out("could not setup mc2 task params");
344
345 init_litmus();
346//printf("CALL\n");
347 if (mc2_param.crit == CRIT_LEVEL_C)
348 set_page_color(-1);
349 else if (mc2_param.crit < CRIT_LEVEL_C)
350 set_page_color(config.cpu);
351//printf("CALL\n");
352
353//printf("INIT_LITMUS\n");
354 start = wctime();
355 ret = task_mode(LITMUS_RT_TASK);
356//printf("TASK_MODE\n");
357 if (ret != 0)
358 bail_out("could not become RT task");
359
360
361 if (wait) {
362//printf("BEFORE WAIT\n");
363 ret = wait_for_ts_release();
364 if (ret != 0)
365 bail_out("wait_for_ts_release()");
366 start = wctime();
367 }
368
369 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
370
371 ret = task_mode(BACKGROUND_TASK);
372 if (ret != 0)
373 bail_out("could not become regular task (huh?)");
374
375 reservation_destroy(gettid(), config.cpu);
376 post_job();
377 printf("%s/%d finished.\n",progname, gettid());
378 return 0;
379}
diff --git a/bin/rt_field_spin.c b/bin/rt_field_spin.c
new file mode 100644
index 0000000..06cabd4
--- /dev/null
+++ b/bin/rt_field_spin.c
@@ -0,0 +1,385 @@
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#include "litmus.h"
13#include "common.h"
14#include "DISstressmarkRNG.h"
15
16#define MIN_FIELD_SIZE 16
17#define MAX_FIELD_SIZE 16777216
18#define MIN_SEED -2147483647
19#define MAX_SEED -1
20#define MIN_MOD_OFFSET 0
21#define MAX_MOD_OFFSET 65535
22#define MIN_TOKENS 1
23#define MAX_TOKENS 256
24#define MIN_TOKEN_LENGTH 1
25#define MAX_TOKEN_LENGTH 8
26#define MIN_TOKEN_VALUE 0
27#define MAX_TOKEN_VALUE 255
28#define MAX_SUBFIELDS 256
29
30static char* progname;
31int loops = 1;
32
33struct timeval t1, t2;
34
35struct tokenS{
36 unsigned char delimiter[MAX_TOKEN_LENGTH];
37 unsigned char length;
38 struct statisticS{
39 unsigned int count;
40 unsigned char min;
41 unsigned char sum;
42 } stat[MAX_SUBFIELDS];
43 unsigned char subfields;
44} token[MAX_TOKENS];
45
46unsigned char *field;
47unsigned int f_max;
48int seed;
49int mod_offset;
50unsigned int n_max;
51
52unsigned char input_token[8] = {0x1, 0x1, 0x22, 0x1, 0xc2, 0x1, 0x2d, 0x0};
53
54int init_job(){
55 //fscanf(stdin, "%d %d %d %d", &f, &seed, &mod_offset, &n);
56 f_max = 262144;
57 seed = -1;
58 n_max = 1;
59
60 assert((seed >= MIN_SEED) && (seed <= MAX_SEED));
61
62 if ((field = (unsigned char*)malloc(f_max*sizeof(unsigned char))) == NULL)
63 return (-1);
64
65 randInit(seed);
66
67 return 0;
68}
69
70int main_job() {
71 unsigned int l, f, n;
72
73 f = randInt(16384, f_max);
74 mod_offset = randInt(128, 8192);
75 n = n_max; //randInt(128,n_max);
76
77 assert((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE));
78 assert((mod_offset >= MIN_MOD_OFFSET) && (mod_offset <= MAX_MOD_OFFSET));
79 assert((n >= MIN_TOKENS) && (n <= MAX_TOKENS));
80
81 for (l=0; l<n; l++){
82 int index;
83 for (index = 0; index<MAX_TOKEN_LENGTH; index++) {
84 unsigned char x = input_token[index];
85 assert((x >= MIN_TOKEN_VALUE) && (x <= MAX_TOKEN_VALUE));
86 token[l].delimiter[index] = (unsigned char )x;
87 }
88 token[l].length = index;
89 }
90
91 for (l =0; l<f; l++){
92 field[l] = randInt(MIN_TOKEN_VALUE, MAX_TOKEN_VALUE);
93 }
94
95 for (l =0; l<n; l++){
96 unsigned int index;
97
98 token[l].subfields = 0;
99 token[l].stat[0].count = 0;
100 token[l].stat[0].sum = 0;
101 token[l].stat[0].min = MAX_TOKEN_VALUE;
102
103 index = 0;
104 while ((index < f) && (token[l].subfields < MAX_SUBFIELDS)){
105 unsigned char offset;
106 offset = 0;
107 while ((field[index+offset] == token[l].delimiter[offset]) &&
108 (offset < token[l].length)){
109 offset++;
110 }
111
112 if (offset == token[l].length){
113 for (offset=0; offset<token[l].length; offset++){
114 field[index+offset] = (field[index+offset] +
115 field[(index+offset+mod_offset) % f])
116 %(MAX_TOKEN_VALUE+1);
117 }
118 index += token[l].length-1;
119 token[l].subfields++;
120 token[l].stat[token[l].subfields].count = 0;
121 token[l].stat[token[l].subfields].sum = 0;
122 token[l].stat[token[l].subfields].min = MAX_TOKEN_VALUE;
123 }
124 else {
125 token[l].stat[token[l].subfields].count++;
126 token[l].stat[token[l].subfields].sum += field[index];
127 if (token[l].stat[token[l].subfields].min > field[index])
128 token[l].stat[token[l].subfields].min = field[index];
129 }
130 index++;
131 }
132 }
133
134 return 0;
135}
136
137int post_job() {
138 if (field) {
139 free(field);
140 field = NULL;
141 }
142
143 return(0);
144}
145
146static void usage(char *error) {
147 fprintf(stderr, "Error: %s\n", error);
148 fprintf(stderr,
149 "Usage:\n"
150 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
151 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
152 " rt_spin -l\n"
153 "\n"
154 "COMMON-OPTS = [-w] [-s SCALE]\n"
155 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
156 "\n"
157 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
158 exit(EXIT_FAILURE);
159}
160
161inline unsigned long get_cyclecount (void)
162{
163 unsigned long value;
164 // Read CCNT Register
165 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
166 return value;
167}
168
169static int loop_main(double exec_time, double emergency_exit)
170{
171 double last_loop = 0, loop_start;
172 int tmp = 0;
173
174 double start = cputime();
175 double now = cputime();
176
177 while (now + last_loop < start + exec_time) {
178 loop_start = now;
179 tmp += main_job();
180 now = cputime();
181 last_loop = now - loop_start;
182 if (emergency_exit && wctime() > emergency_exit) {
183 /* Oops --- this should only be possible if the execution time tracking
184 * is broken in the LITMUS^RT kernel. */
185 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid());
186 fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n");
187 break;
188 }
189 }
190
191 return tmp;
192}
193
194static int job(double exec_time, double program_end)
195{
196 if (wctime() > program_end)
197 return 0;
198 else {
199 loop_main(exec_time, program_end + 1);
200 sleep_next_period();
201 return 1;
202 }
203}
204
205#define OPTSTR "p:wves:l:m:i:b:"
206int main(int argc, char** argv)
207{
208 int ret;
209 lt_t wcet;
210 lt_t period;
211 lt_t budget;
212 double wcet_ms, period_ms, budget_ms;
213 unsigned int priority = LITMUS_NO_PRIORITY;
214 int migrate = 0;
215 int cluster = 0;
216 int opt;
217 int wait = 0;
218 int want_enforcement = 0;
219 double duration = 0, start = 0;
220 double scale = 1.0;
221 task_class_t class = RT_CLASS_HARD;
222 struct rt_task param;
223 struct mc2_task mc2_param;
224 struct reservation_config config;
225 int res_type = PERIODIC_POLLING;
226
227 progname = argv[0];
228
229 /* default for reservation */
230 config.id = 0;
231 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
232 config.cpu = -1;
233
234 mc2_param.crit = CRIT_LEVEL_C;
235
236 budget_ms = 10;
237
238 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
239 switch (opt) {
240 case 'w':
241 wait = 1;
242 break;
243 case 'p':
244 cluster = atoi(optarg);
245 migrate = 1;
246 config.cpu = cluster;
247 break;
248 case 'e':
249 want_enforcement = 1;
250 break;
251 case 's':
252 scale = atof(optarg);
253 break;
254 case 'l':
255 loops = atoi(optarg);
256 break;
257 case 'm':
258 mc2_param.crit = atoi(optarg);
259 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
260 usage("Invalid criticality level.");
261 }
262 res_type = PERIODIC_POLLING;
263 break;
264 case 'b':
265 budget_ms = atof(optarg);
266 break;
267 case 'i':
268 config.priority = atoi(optarg);
269 break;
270 case ':':
271 usage("Argument missing.");
272 break;
273 case '?':
274 default:
275 usage("Bad argument.");
276 break;
277 }
278 }
279
280 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
281 usage("Bad criticailty level or priority");
282
283 if (argc - optind < 3)
284 usage("Arguments missing.");
285
286 wcet_ms = atof(argv[optind + 0]);
287 period_ms = atof(argv[optind + 1]);
288
289 wcet = ms2ns(wcet_ms);
290 period = ms2ns(period_ms);
291 budget = ms2ns(budget_ms);
292
293 if (wcet <= 0)
294 usage("The worst-case execution time must be a "
295 "positive number.");
296 if (period <= 0)
297 usage("The period must be a positive number.");
298 if (wcet > period) {
299 usage("The worst-case execution time must not "
300 "exceed the period.");
301 }
302
303 duration = atof(argv[optind + 2]);
304
305 if (migrate) {
306 ret = be_migrate_to_domain(cluster);
307 if (ret < 0)
308 bail_out("could not migrate to target partition or cluster.");
309 }
310
311 /* reservation config */
312 config.id = gettid();
313
314 config.polling_params.budget = budget;
315 config.polling_params.period = period;
316 config.polling_params.offset = 0;
317 config.polling_params.relative_deadline = 0;
318 if (config.polling_params.budget > config.polling_params.period) {
319 usage("The budget must not exceed the period.");
320 }
321
322 /* create a reservation */
323 ret = reservation_create(res_type, &config);
324 if (ret < 0) {
325 bail_out("failed to create reservation.");
326 }
327 init_job();
328
329 init_rt_task_param(&param);
330 param.exec_cost = wcet;
331 param.period = period;
332 param.priority = priority;
333 param.cls = class;
334 param.release_policy = TASK_PERIODIC;
335 param.budget_policy = (want_enforcement) ?
336 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
337 if (migrate) {
338 param.cpu = gettid();
339 }
340 ret = set_rt_task_param(gettid(), &param);
341
342 if (ret < 0)
343 bail_out("could not setup rt task params");
344
345 mc2_param.res_id = gettid();
346 ret = set_mc2_task_param(gettid(), &mc2_param);
347//printf("SET_MC2_TASK\n");
348 if (ret < 0)
349 bail_out("could not setup mc2 task params");
350
351 init_litmus();
352//printf("CALL\n");
353 if (mc2_param.crit == CRIT_LEVEL_C)
354 set_page_color(-1);
355 else if (mc2_param.crit < CRIT_LEVEL_C)
356 set_page_color(config.cpu);
357//printf("CALL\n");
358
359//printf("INIT_LITMUS\n");
360 start = wctime();
361 ret = task_mode(LITMUS_RT_TASK);
362//printf("TASK_MODE\n");
363 if (ret != 0)
364 bail_out("could not become RT task");
365
366
367 if (wait) {
368//printf("BEFORE WAIT\n");
369 ret = wait_for_ts_release();
370 if (ret != 0)
371 bail_out("wait_for_ts_release()");
372 start = wctime();
373 }
374
375 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
376
377 ret = task_mode(BACKGROUND_TASK);
378 if (ret != 0)
379 bail_out("could not become regular task (huh?)");
380
381 reservation_destroy(gettid(), config.cpu);
382 post_job();
383 //printf("%s/%d finished.\n",progname, gettid());
384 return 0;
385}
diff --git a/bin/rt_matrix.c b/bin/rt_matrix.c
new file mode 100644
index 0000000..d3fa62c
--- /dev/null
+++ b/bin/rt_matrix.c
@@ -0,0 +1,851 @@
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#include "DISstressmarkRNG.h"
16
17#define MIN_SEED -2147483647
18#define MAX_SEED -1
19#define MIN_DIM 1
20#define MAX_DIM 32768
21#define MAX_ITERATIONS 65536
22#define MIN_TOLERANCE 0.000007
23#define MAX_TOLERANCE 0.5
24#define MIN_NUMBER -3.4e10/dim
25#define MAX_NUMBER 3.4e10/dim
26#define EPSI 1.0e-10
27#define MIN_DIG_NUMBER 1.0e-10
28#define MAX_DIG_NUMBER 3.4e10
29
30static char* progname;
31int loops = 1;
32struct timeval t1, t2;
33
34/*
35 * External variable, dimension
36 */
37
38int max_dim;
39double *vectorP, *vectorR, *nextVectorR;
40double *matrixA = NULL;
41double *vectorB = NULL;
42double *vectorX = NULL;
43double *value = NULL;
44int *col_ind = NULL;
45int *row_start = NULL;
46double *tmpVector1, *tmpVector2, *tmpVector3;
47
48/*
49 * matrix * vector
50 */
51
52void matrixMulvector(double *value,
53 int *col_ind,
54 int *row_start,
55 double *vector,
56 double *out,
57 int dim)
58{
59 int l, ll;
60 int tmp_rs, tmp_re;
61
62 for (l=0; l<dim; l++){
63 *(out + l) = 0;
64 tmp_rs = row_start[l];
65
66 if (tmp_rs != -1){
67 tmp_re = row_start[l+1]; /*
68 *get the start and ending elements of
69 * each row
70 */
71 for (ll=tmp_rs; ll<tmp_re; ll++){
72 *(out + l) += value[ll]*vector[col_ind[ll]];
73 }
74 }
75 }
76 return;
77}
78
79
80/*
81 * vector1 - vector2
82 */
83
84void vectorSub(double *vector1, double *vector2, double *vector, int dim){
85
86 int l;
87
88 for (l=0; l<dim; l++){
89 *(vector + l) = *(vector1 + l) - *(vector2 + l);
90 }
91 return;
92}
93
94
95/*
96 * vector1 + vector2
97 */
98
99void vectorAdd(double *vector1, double *vector2, double *vector, int dim){
100
101 int l;
102
103 for (l=0; l<dim; l++){
104 *(vector + l) = *(vector1 + l) + *(vector2 + l);
105 }
106 return;
107}
108
109/*
110 * vector1 * vector2
111 */
112
113double vectorMul(double *vector1, double *vector2, int dim){
114
115 int l;
116 double product;
117
118 product = 0;
119
120 for (l=0; l<dim; l++){
121 product += (*(vector1 + l))*(*(vector2 + l));
122
123 }
124 return product;
125}
126
127/*
128 * /vector/
129 */
130
131double vectorValue(double *vector, int dim){
132
133 double value;
134 int l;
135
136 value = 0;
137
138 for (l=0; l<dim; l++){
139 value += (*(vector + l)) * (*(vector + l));
140 }
141
142 return (sqrt(value));
143}
144
145/*
146 * transpose(vector)
147 * In fact, we return the original vector here
148 */
149
150void transpose(double *vector, double *vect){
151
152 int l;
153
154 for (l=0; l<max_dim; l++){
155 *(vect+l) = *(vector+l);
156 }
157 return;
158}
159
160/*
161 * value * <vector>
162 */
163void valueMulvector(double value, double *vector, double *vect){
164
165 int l;
166
167 for (l=0; l<max_dim; l++){
168 *(vect + l) = *(vector + l) * value;
169 }
170 return;
171}
172
173/*
174 * generate the data distributed sparsely in matrix
175 */
176
177void initMatrix(double *matrix, int dim, int numberNonzero){
178
179 int k, l, ll;
180 int i, j;
181
182 int lll;
183 double sum;
184
185 for (k=0; k< dim*dim; k++){
186 *(matrix + k) = 0;
187 }
188
189 for (l=0; l<numberNonzero/2; l++){
190
191 i = randomUInt(1, dim-1);
192 j = randomUInt(0, i-1);
193
194 while (*(matrix + i*dim + j) != 0){
195
196 i++;
197 if (i == dim){
198 j++;
199 if (j == dim-1){
200 j = 0;
201 i = 1;
202 }
203 else{
204 i = j+1;
205 }
206 }
207 }
208
209 if (*(matrix + i*dim + j) == 0){
210 *(matrix + i*dim + j) = (double )randomNonZeroFloat(MIN_NUMBER,
211 MAX_NUMBER,
212 EPSI);
213 *(matrix + j*dim + i) = *(matrix + i*dim + j);
214 }
215 }
216
217 for (ll=0; ll<dim; ll++){
218
219
220
221 *(matrix + ll*dim + ll) = (double )randomNonZeroFloat(-MAX_DIG_NUMBER,
222 MAX_DIG_NUMBER,
223 MIN_DIG_NUMBER);
224
225 sum = 0;
226
227 for (lll=0; lll<dim; lll++){
228 if (lll != ll){
229 sum += *(matrix + lll*dim + ll);
230 }
231 }
232
233 if (*(matrix + ll*dim + ll) < sum ){
234 *(matrix + ll*dim + ll) += sum;
235 }
236 }
237
238 return;
239}
240
241/*
242 * generate the data value in the vectors
243 */
244
245void initVector(double *vector, int dim){
246
247 int l;
248
249 for (l=0; l<dim; l++){
250 *(vector + l) = (double )randomFloat (MIN_NUMBER, MAX_NUMBER);
251 }
252
253 return;
254}
255
256/*
257 * make a vector contains value of zero
258 */
259
260void zeroVector(double *vector, int dim){
261 int l;
262
263 for (l=0; l<dim; l++){
264 *(vector + l) = 0;
265 }
266 return;
267}
268
269/*
270 * return a vector which is the copy of the vect
271 */
272
273void equalVector(double *vect, double *vect1){
274
275 int l;
276
277 for (l=0; l<max_dim; l++){
278 *(vect1+l) = *(vect+l);
279 }
280 return;
281}
282
283
284
285void biConjugateGradient(double *value,
286 int *col_ind,
287 int *row_start,
288 double *vectorB,
289 double *vectorX,
290 double errorTolerance,
291 int maxIterations,
292 double *actualError,
293 int *actualIteration,
294 int dim)
295 /*
296 * in the code, we use a lot of temparary vectors and variables
297 * this is just for simple and clear
298 * you can optimize these temporary variables and vectors
299 * based on your need
300 *
301 */
302{
303 double error;
304 int iteration;
305 double alpha, beta;
306
307 double tmpValue1, tmpValue2;
308 int l;
309 int ll;
310
311 alpha = 0;
312 beta = 0;
313
314 /*
315 * vectorR = vectorB - matrixA*vectorX
316 */
317 matrixMulvector(value,col_ind, row_start, vectorX, tmpVector1, dim);
318
319 vectorSub(vectorB, tmpVector1, vectorR, dim);
320
321 /*
322 * vectorP = vectorR
323 */
324
325 equalVector(vectorR, vectorP);
326
327 /*
328 * error = |matrixA * vectorX - vectorB| / |vectorB|
329 */
330 vectorSub(tmpVector1, vectorB, tmpVector1, dim);
331
332 error = vectorValue(tmpVector1,dim)/vectorValue(vectorB,dim);
333
334 iteration = 0;
335
336 while ((iteration < maxIterations) && (error > errorTolerance)){
337
338 /*
339 * alpha = (transpose(vectorR) * vectorR) /
340 * (transpose(vectorP) * (matrixA * vectorP)
341 */
342
343 matrixMulvector(value, col_ind, row_start, vectorP, tmpVector1, dim);
344 transpose(vectorR, tmpVector2);
345 transpose(vectorP, tmpVector3);
346 tmpValue1 = vectorMul(tmpVector3, tmpVector1, dim);
347 tmpValue2 = vectorMul(tmpVector2, vectorR, dim);
348 alpha = tmpValue2/tmpValue1;
349
350 /*
351 * nextVectorR = vectorR - alpha*(matrixA * vectorP)
352 */
353
354 valueMulvector(alpha, tmpVector1, tmpVector2);
355 vectorSub(vectorR, tmpVector2, tmpVector1, dim);
356 equalVector(tmpVector1, nextVectorR);
357
358 /*
359 * beta = (transpose(nextVectorR) * nextVectorR) /
360 * (transpose(vectorR) * vectorR)
361 */
362
363 transpose(nextVectorR, tmpVector3);
364 tmpValue1 = vectorMul(tmpVector3, nextVectorR, dim);
365 transpose(vectorR, tmpVector2);
366 tmpValue2 = vectorMul(tmpVector2, vectorR, dim);
367 beta = tmpValue1/tmpValue2;
368
369 /*
370 * vectorX = vectorX + alpha * vectorP
371 */
372 valueMulvector(alpha, vectorP, tmpVector1);
373 vectorAdd(vectorX,tmpVector1, vectorX, dim);
374
375 /*
376 *vectorP = nextVectorR + beta*vectorP
377 */
378 valueMulvector(beta, vectorP, tmpVector1);
379 vectorAdd(nextVectorR, tmpVector1, tmpVector1, dim);
380
381 for (ll=0; ll<dim; ll++){
382 *(vectorP + ll) = *(tmpVector1 + ll);
383 }
384
385 /*
386 * vectorR = nextVectorR
387 */
388
389 for (l=0; l<dim; l++){
390 *(vectorR+l) = *(nextVectorR+l);
391 }
392
393 /*
394 * error = |matrixA * vectorX - vectorB| / |vectorB|
395 */
396 matrixMulvector(value, col_ind,row_start, vectorX, tmpVector1, dim);
397 vectorSub(tmpVector1,vectorB,tmpVector1,dim);
398 error = vectorValue(tmpVector1,dim)/vectorValue(vectorB,dim);
399
400 iteration++;
401 }
402
403 *actualError = error;
404 *actualIteration = iteration;
405
406
407 return;
408}
409
410/*
411 * This is the function to transfer the data from the matrix of dense storage
412 * to Compact Row Storage
413 */
414void create_CRS(double *matrixA,
415 double *value,
416 int *col_ind,
417 int *row_start,
418 int dim,
419 int numberNonzero)
420{
421
422 int i, j, k;
423 int cnt;
424 double tmp;
425
426 /*
427 *initialize the row_start
428 */
429
430 for(k=0; k<dim; k++){
431 row_start[k] = -1;
432 }
433
434 /*
435 * make the end of the last row to be numberNonzero + dim.
436 */
437
438 row_start[dim] = numberNonzero+dim;
439
440 /*
441 * initialize the col_ind
442 */
443
444 for (k=0; k<numberNonzero+dim; k++){
445 col_ind[k] = -1;
446 }
447
448
449 cnt = 0;
450
451 for (i=0; (cnt<numberNonzero+dim)&&(i<dim); i++){
452 for (j=0; (cnt<numberNonzero+dim)&&(j<dim); j++){
453
454 tmp = *(matrixA + i*dim + j);
455
456 if (tmp!=0){
457
458 value[cnt] = tmp;
459 col_ind[cnt] = j;
460
461 if (row_start[i] == -1)
462 row_start[i] = cnt;
463
464 cnt += 1;
465 }
466 }
467 }
468 row_start[i] = cnt;
469
470 return;
471}
472
473 int seed;
474 int max_numberNonzero;
475 int maxIterations;
476 float errorTolerance;
477 int k;
478
479 //fscanf(stdin, "%d %d %d %d %f",
480// &seed, &dim, &numberNonzero,&maxIterations,&errorTolerance);
481int init_job() {
482 //seed = -2;
483 //randInit(seed);
484
485 max_dim = 300;
486 //max_dim = 100;
487 max_numberNonzero = max_dim*max_dim/2+1;
488
489//maxIterations = 65535;
490
491 //dim = randInt(100, 500);
492 //numberNonzero = randInt(dim+1, dim*dim/2);
493 //maxIterations = randInt(10240, 32768);
494
495 errorTolerance = 0.02734;
496
497 //printf("%d %d %d\n",dim,numberNonzero,maxIterations);
498 //assert((seed > MIN_SEED) && (seed < MAX_SEED));
499 assert((max_dim > MIN_DIM) && (max_dim < MAX_DIM));
500 assert((max_numberNonzero > max_dim) && (max_numberNonzero < max_dim*max_dim));
501 //assert((maxIterations > 0) && (maxIterations < MAX_ITERATIONS));
502 assert((errorTolerance > MIN_TOLERANCE) && (errorTolerance < MAX_TOLERANCE));
503
504 matrixA = (double *)malloc(max_dim*max_dim*sizeof(double ));
505 vectorB = (double *)malloc(max_dim*sizeof(double));
506 vectorX = (double *)malloc(max_dim*sizeof(double));
507
508 value = (double *)malloc((max_numberNonzero+max_dim)*sizeof(double));
509 col_ind = (int *)malloc((max_numberNonzero+max_dim)*sizeof(int));
510 row_start = (int *)malloc((max_dim+1)*sizeof(int));
511
512
513 //initMatrix(matrixA, dim, numberNonzero);
514
515 //create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero);
516
517 //initVector(vectorB, dim);
518 //zeroVector(vectorX, dim);
519
520 vectorP = (double *)malloc(max_dim*sizeof(double));
521 vectorR = (double *)malloc(max_dim*sizeof(double));
522 nextVectorR = (double *)malloc(max_dim*sizeof(double));
523
524 tmpVector1 = (double *)malloc(max_dim*sizeof(double));
525 tmpVector2 = (double *)malloc(max_dim*sizeof(double));
526 tmpVector3 = (double *)malloc(max_dim*sizeof(double));
527
528 return 0;
529}
530
531int main_job() {
532 int sum, dim, numberNonzero;
533 double actualError;
534 int actualIteration;
535
536 /* for online */
537/* dim = randInt(100, max_dim);
538 numberNonzero = randInt(dim+1, dim*dim/2);
539 maxIterations = randInt(1024, 8192);
540*/
541
542 /* for case */
543 dim = randInt(4, 50);
544 numberNonzero = randInt(dim+1, dim*dim/2);
545 maxIterations = randInt(1, 10); //randInt(32, 512);
546
547
548 initMatrix(matrixA, dim, numberNonzero);
549 create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero);
550
551 initVector(vectorB, dim);
552 zeroVector(vectorX, dim);
553
554 actualError = 0;
555 actualIteration = 0;
556
557 biConjugateGradient(value, col_ind, row_start, vectorB, vectorX, errorTolerance,
558 maxIterations,
559 &actualError, &actualIteration, dim);
560
561 sum = 0;
562 for (k=1; k<dim; k++){
563 sum += sum + *(vectorX + k);
564 }
565
566 //fprintf(stdout, "sum = %d, actualError = %e, actualIteration = %d\n", sum, actualError, actualIteration);
567 //fprintf(stdout, "total time = %u sec. \n", (unsigned int)endTime);
568
569 return(0);
570}
571
572int post_job() {
573 if (matrixA) {
574 free(matrixA);
575 matrixA = NULL;
576 }
577 if (vectorB) {
578 free(vectorB);
579 vectorB = NULL;
580 }
581 if (vectorX) {
582 free(vectorX);
583 vectorX = NULL;
584 }
585 if (value) {
586 free(value);
587 value = NULL;
588 }
589 if (col_ind) {
590 free(col_ind);
591 col_ind = NULL;
592 }
593 if (row_start) {
594 free(row_start);
595 row_start = NULL;
596 }
597 if (vectorP) {
598 free(vectorP);
599 vectorP = NULL;
600 }
601 if (vectorR) {
602 free(vectorR);
603 vectorR = NULL;
604 }
605 if (nextVectorR) {
606 free(nextVectorR);
607 nextVectorR = NULL;
608 }
609 if (tmpVector1) {
610 free(tmpVector1);
611 tmpVector1 = NULL;
612 }
613 if (tmpVector2) {
614 free(tmpVector2);
615 tmpVector2 = NULL;
616 }
617 if (tmpVector3) {
618 free(tmpVector3);
619 tmpVector3 = NULL;
620 }
621
622 return 0;
623}
624
625static void usage(char *error) {
626 fprintf(stderr, "Error: %s\n", error);
627 fprintf(stderr,
628 "Usage:\n"
629 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
630 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
631 " rt_spin -l\n"
632 "\n"
633 "COMMON-OPTS = [-w] [-s SCALE]\n"
634 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
635 "\n"
636 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
637 exit(EXIT_FAILURE);
638}
639
640inline unsigned long get_cyclecount (void)
641{
642 unsigned long value;
643 // Read CCNT Register
644 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
645 return value;
646}
647
648static int job(double exec_time, double program_end)
649{
650 if (wctime() > program_end)
651 return 0;
652 else {
653 //register int iter = 0;
654 //register unsigned long t;
655 //t = get_cyclecount();
656 //gettimeofday(&t1, NULL);
657 //while (iter++ < loops) {
658 main_job();
659 //}
660 //t = get_cyclecount() - t;
661 //printf("%ld cycles\n", t);
662 //gettimeofday(&t2, NULL);
663 //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
664 sleep_next_period();
665 return 1;
666 }
667}
668
669#define OPTSTR "p:wves:l:m:i:b:"
670int main(int argc, char** argv)
671{
672 int ret;
673 lt_t wcet;
674 lt_t period;
675 lt_t budget;
676 double wcet_ms, period_ms, budget_ms;
677 unsigned int priority = LITMUS_NO_PRIORITY;
678 int migrate = 0;
679 int cluster = 0;
680 int opt;
681 int wait = 0;
682 int want_enforcement = 0;
683 double duration = 0, start = 0;
684 double scale = 1.0;
685 task_class_t class = RT_CLASS_HARD;
686 struct rt_task param;
687 struct mc2_task mc2_param;
688 struct reservation_config config;
689 int res_type = PERIODIC_POLLING;
690
691 progname = argv[0];
692
693 /* default for reservation */
694 config.id = 0;
695 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
696 config.cpu = -1;
697
698 mc2_param.crit = CRIT_LEVEL_C;
699
700 budget_ms = 10;
701
702 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
703 switch (opt) {
704 case 'w':
705 wait = 1;
706 break;
707 case 'p':
708 cluster = atoi(optarg);
709 migrate = 1;
710 config.cpu = cluster;
711 break;
712 case 'e':
713 want_enforcement = 1;
714 break;
715 case 's':
716 scale = atof(optarg);
717 break;
718 case 'l':
719 loops = atoi(optarg);
720 break;
721 case 'm':
722 mc2_param.crit = atoi(optarg);
723 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
724 usage("Invalid criticality level.");
725 }
726 res_type = PERIODIC_POLLING;
727 break;
728 case 'b':
729 budget_ms = atof(optarg);
730 break;
731 case 'i':
732 config.priority = atoi(optarg);
733 break;
734 case ':':
735 usage("Argument missing.");
736 break;
737 case '?':
738 default:
739 usage("Bad argument.");
740 break;
741 }
742 }
743
744 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
745 usage("Bad criticailty level or priority");
746
747 if (argc - optind < 3)
748 usage("Arguments missing.");
749
750 wcet_ms = atof(argv[optind + 0]);
751 period_ms = atof(argv[optind + 1]);
752
753 wcet = ms2ns(wcet_ms);
754 period = ms2ns(period_ms);
755 budget = ms2ns(budget_ms);
756
757 if (wcet <= 0)
758 usage("The worst-case execution time must be a "
759 "positive number.");
760 if (period <= 0)
761 usage("The period must be a positive number.");
762 if (wcet > period) {
763 usage("The worst-case execution time must not "
764 "exceed the period.");
765 }
766
767 duration = atof(argv[optind + 2]);
768
769 if (migrate) {
770 ret = be_migrate_to_domain(cluster);
771 if (ret < 0)
772 bail_out("could not migrate to target partition or cluster.");
773 }
774
775 /* reservation config */
776 config.id = gettid();
777
778 config.polling_params.budget = budget;
779 config.polling_params.period = period;
780 config.polling_params.offset = 0;
781 config.polling_params.relative_deadline = 0;
782 if (config.polling_params.budget > config.polling_params.period) {
783 usage("The budget must not exceed the period.");
784 }
785
786 /* create a reservation */
787 ret = reservation_create(res_type, &config);
788 if (ret < 0) {
789 bail_out("failed to create reservation.");
790 }
791 //srand (time(NULL));
792
793 seed = -2;
794 randInit(seed);
795
796 init_job();
797
798 init_rt_task_param(&param);
799 param.exec_cost = wcet;
800 param.period = period;
801 param.priority = priority;
802 param.cls = class;
803 param.release_policy = TASK_PERIODIC;
804 param.budget_policy = (want_enforcement) ?
805 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
806 if (migrate) {
807 param.cpu = gettid();
808 }
809 ret = set_rt_task_param(gettid(), &param);
810
811 if (ret < 0)
812 bail_out("could not setup rt task params");
813
814 mc2_param.res_id = gettid();
815 ret = set_mc2_task_param(gettid(), &mc2_param);
816
817 if (ret < 0)
818 bail_out("could not setup mc2 task params");
819
820 init_litmus();
821
822 if (mc2_param.crit == CRIT_LEVEL_C)
823 set_page_color(-1);
824 else if (mc2_param.crit < CRIT_LEVEL_C)
825 set_page_color(config.cpu);
826
827 start = wctime();
828 ret = task_mode(LITMUS_RT_TASK);
829
830 if (ret != 0)
831 bail_out("could not become RT task");
832
833
834 if (wait) {
835 ret = wait_for_ts_release();
836 if (ret != 0)
837 bail_out("wait_for_ts_release()");
838 start = wctime();
839 }
840
841 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
842
843 ret = task_mode(BACKGROUND_TASK);
844 if (ret != 0)
845 bail_out("could not become regular task (huh?)");
846
847 reservation_destroy(gettid(), config.cpu);
848 post_job();
849 printf("%s/%d finished.\n",progname, gettid());
850 return 0;
851}
diff --git a/bin/rt_matrix_spin.c b/bin/rt_matrix_spin.c
new file mode 100644
index 0000000..142576c
--- /dev/null
+++ b/bin/rt_matrix_spin.c
@@ -0,0 +1,833 @@
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#include "DISstressmarkRNG.h"
16
17#define MIN_SEED -2147483647
18#define MAX_SEED -1
19#define MIN_DIM 1
20#define MAX_DIM 32768
21#define MAX_ITERATIONS 65536
22#define MIN_TOLERANCE 0.000007
23#define MAX_TOLERANCE 0.5
24#define MIN_NUMBER -3.4e10/dim
25#define MAX_NUMBER 3.4e10/dim
26#define EPSI 1.0e-10
27#define MIN_DIG_NUMBER 1.0e-10
28#define MAX_DIG_NUMBER 3.4e10
29
30static char* progname;
31int loops = 1;
32//struct timeval t1, t2;
33
34/*
35 * External variable, dimension
36 */
37
38static int dim;
39
40/*
41 * matrix * vector
42 */
43
44void matrixMulvector(double *value,
45 int *col_ind,
46 int *row_start,
47 double *vector,
48 double *out)
49{
50 int l, ll;
51 double sum;
52 int tmp_rs, tmp_re;
53
54 for (l=0; l<dim; l++){
55 *(out + l) = 0;
56 tmp_rs = row_start[l];
57
58 if (tmp_rs != -1){
59 tmp_re = row_start[l+1]; /*
60 *get the start and ending elements of
61 * each row
62 */
63 for (ll=tmp_rs; ll<tmp_re; ll++){
64 *(out + l) += value[ll]*vector[col_ind[ll]];
65 }
66 }
67 }
68 return;
69}
70
71
72/*
73 * vector1 - vector2
74 */
75
76void vectorSub(double *vector1, double *vector2, double *vector){
77
78 int l;
79
80 for (l=0; l<dim; l++){
81 *(vector + l) = *(vector1 + l) - *(vector2 + l);
82 }
83 return;
84}
85
86
87/*
88 * vector1 + vector2
89 */
90
91void vectorAdd(double *vector1, double *vector2, double *vector){
92
93 int l;
94
95 for (l=0; l<dim; l++){
96 *(vector + l) = *(vector1 + l) + *(vector2 + l);
97 }
98 return;
99}
100
101/*
102 * vector1 * vector2
103 */
104
105double vectorMul(double *vector1, double *vector2){
106
107 int l;
108 double product;
109
110 product = 0;
111
112 for (l=0; l<dim; l++){
113 product += (*(vector1 + l))*(*(vector2 + l));
114
115 }
116 return product;
117}
118
119/*
120 * /vector/
121 */
122
123double vectorValue(double *vector){
124
125 double value;
126 int l;
127
128 value = 0;
129
130 for (l=0; l<dim; l++){
131 value += (*(vector + l)) * (*(vector + l));
132 }
133
134 return (sqrt(value));
135}
136
137/*
138 * transpose(vector)
139 * In fact, we return the original vector here
140 */
141
142void transpose(double *vector, double *vect){
143
144 int l;
145
146 for (l=0; l<dim; l++){
147 *(vect+l) = *(vector+l);
148 }
149 return;
150}
151
152/*
153 * value * <vector>
154 */
155void valueMulvector(double value, double *vector, double *vect){
156
157 int l;
158 int lll, i;
159 double tmp;
160
161 for (l=0; l<dim; l++){
162 *(vect + l) = *(vector + l) * value;
163 }
164 return;
165}
166
167/*
168 * generate the data distributed sparsely in matrix
169 */
170
171void initMatrix(double *matrix, int dim, int numberNonzero){
172
173 int k, l, ll;
174 int i, j;
175
176 int lll;
177 double sum;
178
179 for (k=0; k< dim*dim; k++){
180 *(matrix + k) = 0;
181 }
182
183 for (l=0; l<numberNonzero/2; l++){
184
185 i = randomUInt(1, dim-1);
186 j = randomUInt(0, i-1);
187
188 while (*(matrix + i*dim + j) != 0){
189
190 i++;
191 if (i == dim){
192 j++;
193 if (j == dim-1){
194 j = 0;
195 i = 1;
196 }
197 else{
198 i = j+1;
199 }
200 }
201 }
202
203 if (*(matrix + i*dim + j) == 0){
204 *(matrix + i*dim + j) = (double )randomNonZeroFloat(MIN_NUMBER,
205 MAX_NUMBER,
206 EPSI);
207 *(matrix + j*dim + i) = *(matrix + i*dim + j);
208 }
209 }
210
211 for (ll=0; ll<dim; ll++){
212
213
214
215 *(matrix + ll*dim + ll) = (double )randomNonZeroFloat(-MAX_DIG_NUMBER,
216 MAX_DIG_NUMBER,
217 MIN_DIG_NUMBER);
218
219 sum = 0;
220
221 for (lll=0; lll<dim; lll++){
222 if (lll != ll){
223 sum += *(matrix + lll*dim + ll);
224 }
225 }
226
227 if (*(matrix + ll*dim + ll) < sum ){
228 *(matrix + ll*dim + ll) += sum;
229 }
230 }
231
232 return;
233}
234
235/*
236 * generate the data value in the vectors
237 */
238
239void initVector(double *vector, int dim){
240
241 int l;
242
243 for (l=0; l<dim; l++){
244 *(vector + l) = (double )randomFloat (MIN_NUMBER, MAX_NUMBER);
245 }
246
247 return;
248}
249
250/*
251 * make a vector contains value of zero
252 */
253
254void zeroVector(double *vector, int dim){
255 int l;
256
257 for (l=0; l<dim; l++){
258 *(vector + l) = 0;
259 }
260 return;
261}
262
263/*
264 * return a vector which is the copy of the vect
265 */
266
267void equalVector(double *vect, double *vect1){
268
269 int l;
270
271 for (l=0; l<dim; l++){
272 *(vect1+l) = *(vect+l);
273 }
274 return;
275}
276
277
278
279void biConjugateGradient(double *value,
280 int *col_ind,
281 int *row_start,
282 double *vectorB,
283 double *vectorX,
284 double errorTolerance,
285 int maxIterations,
286 double *actualError,
287 int *actualIteration,
288 int dim)
289 /*
290 * in the code, we use a lot of temparary vectors and variables
291 * this is just for simple and clear
292 * you can optimize these temporary variables and vectors
293 * based on your need
294 *
295 */
296{
297 double *vectorR;
298 double *vectorP, *matrixAvectorP, *nextVectorR;
299 double error;
300 int iteration;
301 double alpha, beta;
302
303 double *tmpVector1, *tmpVector2, *tmpVector3;
304 double tmpValue1, tmpValue2;
305 int i;
306 int l;
307 int ll;
308
309 alpha = 0;
310 beta = 0;
311
312 vectorP = (double *)malloc(dim*sizeof(double));
313 vectorR = (double *)malloc(dim*sizeof(double));
314 nextVectorR = (double *)malloc(dim*sizeof(double));
315 vectorX = (double *)malloc(dim*sizeof(double));
316
317 tmpVector1 = (double *)malloc(dim*sizeof(double));
318 tmpVector2 = (double *)malloc(dim*sizeof(double));
319 tmpVector3 = (double *)malloc(dim*sizeof(double));
320
321 /*
322 * vectorR = vectorB - matrixA*vectorX
323 */
324 matrixMulvector(value,col_ind, row_start, vectorX, tmpVector1);
325
326 vectorSub(vectorB, tmpVector1, vectorR);
327
328 /*
329 * vectorP = vectorR
330 */
331
332 equalVector(vectorR, vectorP);
333
334 /*
335 * error = |matrixA * vectorX - vectorB| / |vectorB|
336 */
337 vectorSub(tmpVector1, vectorB, tmpVector1);
338
339 error = vectorValue(tmpVector1)/vectorValue(vectorB);
340
341 iteration = 0;
342
343 while ((iteration < maxIterations) && (error > errorTolerance)){
344
345 /*
346 * alpha = (transpose(vectorR) * vectorR) /
347 * (transpose(vectorP) * (matrixA * vectorP)
348 */
349
350 matrixMulvector(value, col_ind, row_start, vectorP, tmpVector1);
351 transpose(vectorR, tmpVector2);
352 transpose(vectorP, tmpVector3);
353 tmpValue1 = vectorMul(tmpVector3, tmpVector1);
354 tmpValue2 = vectorMul(tmpVector2, vectorR);
355 alpha = tmpValue2/tmpValue1;
356
357 /*
358 * nextVectorR = vectorR - alpha*(matrixA * vectorP)
359 */
360
361 valueMulvector(alpha, tmpVector1, tmpVector2);
362 vectorSub(vectorR, tmpVector2, tmpVector1);
363 equalVector(tmpVector1, nextVectorR);
364
365 /*
366 * beta = (transpose(nextVectorR) * nextVectorR) /
367 * (transpose(vectorR) * vectorR)
368 */
369
370 transpose(nextVectorR, tmpVector3);
371 tmpValue1 = vectorMul(tmpVector3, nextVectorR);
372 transpose(vectorR, tmpVector2);
373 tmpValue2 = vectorMul(tmpVector2, vectorR);
374 beta = tmpValue1/tmpValue2;
375
376 /*
377 * vectorX = vectorX + alpha * vectorP
378 */
379 valueMulvector(alpha, vectorP, tmpVector1);
380 vectorAdd(vectorX,tmpVector1, vectorX);
381
382 /*
383 *vectorP = nextVectorR + beta*vectorP
384 */
385 valueMulvector(beta, vectorP, tmpVector1);
386 vectorAdd(nextVectorR, tmpVector1, tmpVector1);
387
388 for (ll=0; ll<dim; ll++){
389 *(vectorP + ll) = *(tmpVector1 + ll);
390 }
391
392 /*
393 * vectorR = nextVectorR
394 */
395
396 for (l=0; l<dim; l++){
397 *(vectorR+l) = *(nextVectorR+l);
398 }
399
400 /*
401 * error = |matrixA * vectorX - vectorB| / |vectorB|
402 */
403 matrixMulvector(value, col_ind,row_start, vectorX, tmpVector1);
404 vectorSub(tmpVector1,vectorB,tmpVector1);
405 error = vectorValue(tmpVector1)/vectorValue(vectorB);
406
407 iteration++;
408 }
409
410 *actualError = error;
411 *actualIteration = iteration;
412
413 free(tmpVector1);
414 free(tmpVector2);
415 free(tmpVector3);
416
417 free(vectorR);
418 free(vectorP);
419
420 return;
421}
422
423/*
424 * This is the function to transfer the data from the matrix of dense storage
425 * to Compact Row Storage
426 */
427void create_CRS(double *matrixA,
428 double *value,
429 int *col_ind,
430 int *row_start,
431 int dim,
432 int numberNonzero)
433{
434
435 int i, j, k;
436 int cnt;
437 double tmp;
438
439 /*
440 *initialize the row_start
441 */
442
443 for(k=0; k<dim; k++){
444 row_start[k] = -1;
445 }
446
447 /*
448 * make the end of the last row to be numberNonzero + dim.
449 */
450
451 row_start[dim] = numberNonzero+dim;
452
453 /*
454 * initialize the col_ind
455 */
456
457 for (k=0; k<numberNonzero+dim; k++){
458 col_ind[k] = -1;
459 }
460
461
462 cnt = 0;
463
464 for (i=0; (cnt<numberNonzero+dim)&&(i<dim); i++){
465 for (j=0; (cnt<numberNonzero+dim)&&(j<dim); j++){
466
467 tmp = *(matrixA + i*dim + j);
468
469 if (tmp!=0){
470
471 value[cnt] = tmp;
472 col_ind[cnt] = j;
473
474 if (row_start[i] == -1)
475 row_start[i] = cnt;
476
477 cnt += 1;
478 }
479 }
480 }
481 row_start[i] = cnt;
482
483 return;
484}
485
486 int seed;
487 int numberNonzero;
488 int maxIterations;
489 float errorTolerance;
490 double actualError;
491 int actualIteration;
492
493
494 double *matrixA;
495 double *vectorB;
496 double *vectorX;
497
498 double *value;
499 int *col_ind;
500 int *row_start;
501 int sum;
502 int k;
503
504 //fscanf(stdin, "%d %d %d %d %f",
505// &seed, &dim, &numberNonzero,&maxIterations,&errorTolerance);
506int init_job() {
507
508 seed = -2;
509 //dim = 500;
510 //numberNonzero = 20000;
511 dim = randInt(100,300);
512 numberNonzero = randInt(dim+1, dim*dim/4);
513 maxIterations = 32;
514 errorTolerance = 0.002734;
515
516 assert((seed > MIN_SEED) && (seed < MAX_SEED));
517 assert((dim > MIN_DIM) && (dim < MAX_DIM));
518 assert((numberNonzero > dim) && (numberNonzero < dim*dim));
519 assert((maxIterations > 0) && (maxIterations < MAX_ITERATIONS));
520 assert((errorTolerance > MIN_TOLERANCE) && (errorTolerance < MAX_TOLERANCE));
521
522 matrixA = (double *)malloc(dim*dim*sizeof(double ));
523 vectorB = (double *)malloc(dim*sizeof(double));
524 vectorX = (double *)malloc(dim*sizeof(double));
525
526 value = (double *)malloc((numberNonzero+dim)*sizeof(double));
527 col_ind = (int *)malloc((numberNonzero+dim)*sizeof(int));
528 row_start = (int *)malloc((dim+1)*sizeof(int));
529
530 //randInit(seed);
531
532 initMatrix(matrixA, dim, numberNonzero);
533
534 create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero);
535
536 initVector(vectorB, dim);
537 zeroVector(vectorX, dim);
538
539 return 0;
540}
541
542int main_job() {
543 initVector(vectorB, dim);
544 zeroVector(vectorX, dim);
545
546 actualError = 0;
547 actualIteration = 0;
548
549 biConjugateGradient(value, col_ind, row_start, vectorB, vectorX, errorTolerance,
550 maxIterations,
551 &actualError, &actualIteration, dim);
552
553 sum = 0;
554 for (k=1; k<dim; k++){
555 sum += sum + *(vectorX + k);
556 }
557
558 //fprintf(stdout, "sum = %d, actualError = %e, actualIteration = %d\n", sum, actualError, actualIteration);
559 //fprintf(stdout, "total time = %u sec. \n", (unsigned int)endTime);
560
561 return(0);
562}
563
564int post_job() {
565 free(matrixA);
566 free(vectorB);
567 free(vectorX);
568 free(value);
569 free(col_ind);
570 free(row_start);
571 return 0;
572}
573
574static void usage(char *error) {
575 fprintf(stderr, "Error: %s\n", error);
576 fprintf(stderr,
577 "Usage:\n"
578 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
579 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
580 " rt_spin -l\n"
581 "\n"
582 "COMMON-OPTS = [-w] [-s SCALE]\n"
583 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
584 "\n"
585 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
586 exit(EXIT_FAILURE);
587}
588
589inline unsigned long get_cyclecount (void)
590{
591 unsigned long value;
592 // Read CCNT Register
593 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
594 return value;
595}
596
597static int loop_main(double exec_time, double emergency_exit)
598{
599 double last_loop = 0, loop_start;
600 int tmp = 0;
601
602 double start = cputime();
603 double now = cputime();
604
605 while (now + last_loop < start + exec_time) {
606 loop_start = now;
607 init_job();
608 tmp += main_job();
609 post_job();
610 now = cputime();
611 last_loop = now - loop_start;
612 if (emergency_exit && wctime() > emergency_exit) {
613 /* Oops --- this should only be possible if the execution time tracking
614 * is broken in the LITMUS^RT kernel. */
615 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid());
616 fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n");
617 break;
618 }
619 }
620
621 return tmp;
622}
623
624static int job(double exec_time, double program_end)
625{
626 if (wctime() > program_end)
627 return 0;
628 else {
629 register int iter = 0;
630 //register unsigned long t;
631 //t = get_cyclecount();
632 //gettimeofday(&t1, NULL);
633 //while (iter++ < loops) {
634 loop_main(exec_time, program_end + 1);
635 //}
636 //t = get_cyclecount() - t;
637 //printf("%ld cycles\n", t);
638 //gettimeofday(&t2, NULL);
639 //printf("%ld us\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
640 sleep_next_period();
641 return 1;
642 }
643}
644
645#define OPTSTR "p:wves:l:m:i:b:"
646int main(int argc, char** argv)
647{
648 int ret;
649 lt_t wcet;
650 lt_t period;
651 lt_t budget;
652 double wcet_ms, period_ms, budget_ms;
653 unsigned int priority = LITMUS_NO_PRIORITY;
654 int migrate = 0;
655 int cluster = 0;
656 int opt;
657 int wait = 0;
658 int want_enforcement = 0;
659 double duration = 0, start = 0;
660 double scale = 1.0;
661 task_class_t class = RT_CLASS_HARD;
662 struct rt_task param;
663 struct mc2_task mc2_param;
664 struct reservation_config config;
665 int res_type = PERIODIC_POLLING;
666
667 unsigned int job_no;
668
669
670 progname = argv[0];
671
672 /* default for reservation */
673 config.id = 0;
674 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
675 config.cpu = -1;
676
677 mc2_param.crit = CRIT_LEVEL_C;
678
679 budget_ms = 0;
680
681 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
682 switch (opt) {
683 case 'w':
684 wait = 1;
685 break;
686 case 'p':
687 cluster = atoi(optarg);
688 migrate = 1;
689 config.cpu = cluster;
690 break;
691 case 'e':
692 want_enforcement = 1;
693 break;
694 case 's':
695 scale = atof(optarg);
696 break;
697 case 'l':
698 loops = atoi(optarg);
699 break;
700 case 'm':
701 mc2_param.crit = atoi(optarg);
702 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
703 usage("Invalid criticality level.");
704 }
705 res_type = PERIODIC_POLLING;
706 break;
707 case 'b':
708 budget_ms = atof(optarg);
709 break;
710 case 'i':
711 config.priority = atoi(optarg);
712 break;
713 case ':':
714 usage("Argument missing.");
715 break;
716 case '?':
717 default:
718 usage("Bad argument.");
719 break;
720 }
721 }
722
723 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
724 usage("Bad criticailty level or priority");
725
726 if (argc - optind < 3)
727 usage("Arguments missing.");
728
729 wcet_ms = atof(argv[optind + 0]);
730 period_ms = atof(argv[optind + 1]);
731
732 wcet = ms2ns(wcet_ms);
733 period = ms2ns(period_ms);
734 if (budget_ms == 0)
735 budget_ms = wcet_ms;
736 budget = ms2ns(budget_ms);
737
738 if (wcet <= 0)
739 usage("The worst-case execution time must be a "
740 "positive number.");
741 if (period <= 0)
742 usage("The period must be a positive number.");
743 if (wcet > period) {
744 usage("The worst-case execution time must not "
745 "exceed the period.");
746 }
747
748 duration = atof(argv[optind + 2]);
749
750 if (migrate) {
751 ret = be_migrate_to_domain(cluster);
752 if (ret < 0)
753 bail_out("could not migrate to target partition or cluster.");
754 }
755
756 /* reservation config */
757 config.id = gettid();
758
759 config.polling_params.budget = budget;
760 config.polling_params.period = period;
761 config.polling_params.offset = 0;
762 config.polling_params.relative_deadline = 0;
763 if (config.polling_params.budget > config.polling_params.period) {
764 usage("The budget must not exceed the period.");
765 }
766
767 /* create a reservation */
768 ret = reservation_create(res_type, &config);
769 if (ret < 0) {
770 bail_out("failed to create reservation.");
771 }
772 //init_job();
773 srand (time(NULL));
774 randInit(-rand()%65535);
775
776 init_rt_task_param(&param);
777 param.exec_cost = wcet;
778 param.period = period;
779 param.priority = priority;
780 param.cls = class;
781 param.release_policy = TASK_PERIODIC;
782 param.budget_policy = (want_enforcement) ?
783 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
784 if (migrate) {
785 param.cpu = gettid();
786 }
787 ret = set_rt_task_param(gettid(), &param);
788
789 if (ret < 0)
790 bail_out("could not setup rt task params");
791
792 mc2_param.res_id = gettid();
793 ret = set_mc2_task_param(gettid(), &mc2_param);
794//printf("SET_MC2_TASK\n");
795 if (ret < 0)
796 bail_out("could not setup mc2 task params");
797
798 init_litmus();
799//printf("CALL\n");
800 if (mc2_param.crit == CRIT_LEVEL_C)
801 set_page_color(-1);
802 else if (mc2_param.crit < CRIT_LEVEL_C)
803 set_page_color(config.cpu);
804//printf("CALL\n");
805
806//printf("INIT_LITMUS\n");
807 start = wctime();
808 ret = task_mode(LITMUS_RT_TASK);
809//printf("TASK_MODE\n");
810 if (ret != 0)
811 bail_out("could not become RT task");
812
813
814 if (wait) {
815//printf("BEFORE WAIT\n");
816 ret = wait_for_ts_release();
817 if (ret != 0)
818 bail_out("wait_for_ts_release()");
819 start = wctime();
820 }
821
822 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
823
824 ret = task_mode(BACKGROUND_TASK);
825 if (ret != 0)
826 bail_out("could not become regular task (huh?)");
827
828 reservation_destroy(gettid(), config.cpu);
829 //post_job();
830// printf("%s/%d finished.\n",progname, gettid());
831 return 0;
832}
833
diff --git a/bin/rt_mode_poll.c b/bin/rt_mode_poll.c
new file mode 100644
index 0000000..08e9490
--- /dev/null
+++ b/bin/rt_mode_poll.c
@@ -0,0 +1,235 @@
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
16#define __NR_enact_mode 409
17
18int main_job(void){
19 syscall(__NR_enact_mode);
20}
21
22static char* progname;
23int loops = 1;
24//struct timeval t1, t2;
25
26static void usage(char *error) {
27 fprintf(stderr, "Error: %s\n", error);
28 fprintf(stderr,
29 "Usage:\n"
30 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
31 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
32 " rt_spin -l\n"
33 "\n"
34 "COMMON-OPTS = [-w] [-s SCALE]\n"
35 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
36 "\n"
37 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
38 exit(EXIT_FAILURE);
39}
40
41inline unsigned long get_cyclecount (void)
42{
43 unsigned long value;
44 // Read CCNT Register
45 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
46 return value;
47}
48
49static int job(double exec_time, double program_end)
50{
51 if (wctime() > program_end)
52 return 0;
53 else {
54 main_job();
55 sleep_next_period();
56 return 1;
57 }
58}
59
60#define OPTSTR "p:wves:l:m:i:b:"
61int main(int argc, char** argv)
62{
63 int ret;
64 lt_t wcet;
65 lt_t period;
66 lt_t budget;
67 double wcet_us, period_us, budget_us;
68 unsigned int priority = LITMUS_NO_PRIORITY;
69 int migrate = 0;
70 int cluster = 0;
71 int opt;
72 int wait = 0;
73 int want_enforcement = 0;
74 double duration = 0, start = 0;
75 double scale = 1.0;
76 task_class_t class = RT_CLASS_HARD;
77 struct rt_task param;
78 struct mc2_task mc2_param;
79 struct reservation_config config;
80 int res_type = PERIODIC_POLLING;
81
82 unsigned int job_no;
83
84
85 progname = argv[0];
86
87 /* default for reservation */
88 config.id = 0;
89 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
90 config.cpu = -1;
91
92 mc2_param.crit = CRIT_LEVEL_C;
93
94 budget_us = 10000;
95
96 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
97 switch (opt) {
98 case 'w':
99 wait = 1;
100 break;
101 case 'p':
102 cluster = atoi(optarg);
103 migrate = 1;
104 config.cpu = cluster;
105 break;
106 case 'e':
107 want_enforcement = 1;
108 break;
109 case 's':
110 scale = atof(optarg);
111 break;
112 case 'l':
113 loops = atoi(optarg);
114 break;
115 case 'm':
116 mc2_param.crit = atoi(optarg);
117 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
118 usage("Invalid criticality level.");
119 }
120 res_type = PERIODIC_POLLING;
121 break;
122 case 'b':
123 budget_us = atof(optarg);
124 break;
125 case 'i':
126 config.priority = atoi(optarg);
127 break;
128 case ':':
129 usage("Argument missing.");
130 break;
131 case '?':
132 default:
133 usage("Bad argument.");
134 break;
135 }
136 }
137
138 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
139 usage("Bad criticailty level or priority");
140
141 if (argc - optind < 3)
142 usage("Arguments missing.");
143
144 wcet_us = atof(argv[optind + 0]);
145 period_us = atof(argv[optind + 1]);
146
147 wcet = us2ns(wcet_us);
148 period = us2ns(period_us);
149 budget = us2ns(budget_us);
150
151 if (wcet <= 0)
152 usage("The worst-case execution time must be a "
153 "positive number.");
154 if (period <= 0)
155 usage("The period must be a positive number.");
156 if (wcet > period) {
157 usage("The worst-case execution time must not "
158 "exceed the period.");
159 }
160
161 duration = atof(argv[optind + 2]);
162
163 if (migrate) {
164 ret = be_migrate_to_domain(cluster);
165 if (ret < 0)
166 bail_out("could not migrate to target partition or cluster.");
167 }
168
169 /* reservation config */
170 config.id = gettid();
171
172 config.polling_params.budget = budget;
173 config.polling_params.period = period;
174 config.polling_params.offset = 0;
175 config.polling_params.relative_deadline = 0;
176 if (config.polling_params.budget > config.polling_params.period) {
177 usage("The budget must not exceed the period.");
178 }
179
180 /* create a reservation */
181 ret = reservation_create(res_type, &config);
182 if (ret < 0) {
183 bail_out("failed to create reservation.");
184 }
185
186 init_rt_task_param(&param);
187 param.exec_cost = wcet;
188 param.period = period;
189 param.priority = priority;
190 param.cls = class;
191 param.release_policy = TASK_PERIODIC;
192 param.budget_policy = (want_enforcement) ?
193 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
194 if (migrate) {
195 param.cpu = gettid();
196 }
197 ret = set_rt_task_param(gettid(), &param);
198
199 if (ret < 0)
200 bail_out("could not setup rt task params");
201
202 mc2_param.res_id = gettid();
203 ret = set_mc2_task_param(gettid(), &mc2_param);
204 if (ret < 0)
205 bail_out("could not setup mc2 task params");
206
207 init_litmus();
208 if (mc2_param.crit == CRIT_LEVEL_C)
209 set_page_color(8);
210 else if (mc2_param.crit < CRIT_LEVEL_C)
211 set_page_color(config.cpu*2 + mc2_param.crit);
212
213 start = wctime();
214 ret = task_mode(LITMUS_RT_TASK);
215 if (ret != 0)
216 bail_out("could not become RT task");
217
218
219 if (wait) {
220 ret = wait_for_ts_release();
221 if (ret != 0)
222 bail_out("wait_for_ts_release()");
223 start = wctime();
224 }
225
226 while (job(wcet_us * 0.000001 * scale, start + duration)) {};
227
228 ret = task_mode(BACKGROUND_TASK);
229 if (ret != 0)
230 bail_out("could not become regular task (huh?)");
231
232 reservation_destroy(gettid(), config.cpu);
233 printf("%s/%d finished.\n",progname, gettid());
234 return 0;
235}
diff --git a/bin/rt_neighborhood.c b/bin/rt_neighborhood.c
new file mode 100644
index 0000000..8679cfb
--- /dev/null
+++ b/bin/rt_neighborhood.c
@@ -0,0 +1,381 @@
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#include "DISstressmarkRNG.h"
16#include "utili.h"
17
18#define MIN_PIXEL 0
19
20static char* progname;
21int loops = 1;
22struct timeval t1, t2;
23
24long int seed;
25int max_dimension;
26int numberLines;
27int minThickness;
28int maxThickness;
29int distanceShort;
30int distanceLong;
31int bitDepth;
32int maxPixel;
33Pixel *image;
34Neighborhood values;
35int *sumHist, *diffHist;
36int numBins;
37
38int init_job() {
39 //fscanf(stdin, "%ld %d %d %d %d %d %d %d",
40// &seed, &bitDepth, &dimension, &numberLines,
41// &minThickness, &maxThickness,
42// &distanceShort, &distanceLong);
43
44 seed = -2;
45 bitDepth = 8;
46 /*
47 dimension = 1501;
48 numberLines = 10000;
49 minThickness = 10;
50 maxThickness = 1000;
51 distanceShort = 100;
52 distanceLong = 1000;
53 */
54 /* for online */
55 max_dimension = 501;
56 numberLines = randInt(200,600);
57 minThickness = randInt(1,max_dimension/2);
58 maxThickness = randInt(minThickness+1,max_dimension-1);
59 distanceShort = 10;
60 distanceLong = randInt(20, max_dimension-1);
61
62
63 /* for case
64 max_dimension = 301;
65 //max_dimension = 1501;
66 numberLines = randInt(2000,6000);
67 minThickness = randInt(1,max_dimension/2);
68 maxThickness = randInt(minThickness+1,max_dimension-1);
69 distanceShort = 10;
70 distanceLong = randInt(20, max_dimension-1);
71*/
72
73 assert((seed >= MIN_SEED) && (seed <= MAX_SEED));
74 assert((max_dimension > 0) && (max_dimension <= MAX_DIMENSION));
75 assert((numberLines > 0) && (numberLines <= MAX_NUMBER_LINES));
76 assert((minThickness > 0) && (minThickness < max_dimension));
77 assert((maxThickness >= minThickness) && (maxThickness < max_dimension));
78 assert((distanceShort > 0) && (distanceShort < max_dimension));
79 assert((distanceLong > 0) && (distanceLong < max_dimension));
80 assert((bitDepth >= MIN_BIT_DEPTH) && (bitDepth <= MAX_BIT_DEPTH));
81
82 //randInit(seed);
83 maxPixel = (1 << bitDepth) - 1;
84 //image = createImage(dimension, maxPixel, numberLines,
85 // minThickness, maxThickness);
86 //assert (image != NULL);
87
88 image = (Pixel *)malloc(sizeof(Pixel) * max_dimension * max_dimension);
89 assert (image != NULL);
90
91 numBins = (2 * (maxPixel - MIN_PIXEL + 1) -1);
92 sumHist = (int *) malloc(numBins * sizeof(int));
93 assert (sumHist != NULL);
94 diffHist = (int *)malloc(numBins * sizeof(int));
95 assert(diffHist != NULL);
96
97
98 return 0;
99}
100
101
102int main_job() {
103 int dimension;
104
105 /* online */
106/* dimension = randInt(101, 501);
107 numberLines = randInt(10,150);
108 minThickness = randInt(1,dimension/2);
109 maxThickness = randInt(minThickness+1,dimension-1);
110 distanceShort = 10;
111 distanceLong = randInt(20, dimension-1);
112*/
113 /* case */
114 dimension = randInt(11, 151);
115 numberLines = randInt(5,100);
116 minThickness = randInt(1,dimension/2);
117 maxThickness = randInt(minThickness+1,dimension-1);
118 distanceShort = 10;
119 distanceLong = randInt(5, dimension-1);
120
121
122
123 image = createImage(image, dimension, maxPixel, numberLines, minThickness, maxThickness);
124
125 //assert (image != NULL);
126
127 neighborhoodCalculation(image, dimension, distanceShort, distanceLong, &values, maxPixel, sumHist, diffHist);
128
129 return 0;
130}
131
132int post_job() {
133 if (image) {
134 free((Pixel *)image);
135 image = NULL;
136 }
137 if (sumHist) {
138 free(sumHist);
139 sumHist = NULL;
140 }
141 if (diffHist) {
142 free(diffHist);
143 diffHist = NULL;
144 }
145
146 return (0);
147}
148
149static void usage(char *error) {
150 fprintf(stderr, "Error: %s\n", error);
151 fprintf(stderr,
152 "Usage:\n"
153 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
154 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
155 " rt_spin -l\n"
156 "\n"
157 "COMMON-OPTS = [-w] [-s SCALE]\n"
158 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
159 "\n"
160 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
161 exit(EXIT_FAILURE);
162}
163
164inline unsigned long get_cyclecount (void)
165{
166 unsigned long value;
167 // Read CCNT Register
168 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
169 return value;
170}
171
172static int job(double exec_time, double program_end)
173{
174 if (wctime() > program_end)
175 return 0;
176 else {
177 register int iter = 0;
178 //register unsigned long t;
179 //t = get_cyclecount();
180 //init_job();
181 //gettimeofday(&t1, NULL);
182 while (iter++ < loops) {
183 main_job();
184 }
185 //t = get_cyclecount() - t;
186 //printf("%ld cycles\n", t);
187 //gettimeofday(&t2, NULL);
188 //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
189 //post_job();
190 sleep_next_period();
191 return 1;
192 }
193}
194
195#define OPTSTR "p:wves:l:m:i:b:"
196int main(int argc, char** argv)
197{
198 int ret;
199 lt_t wcet;
200 lt_t period;
201 lt_t budget;
202 double wcet_ms, period_ms, budget_ms;
203 unsigned int priority = LITMUS_NO_PRIORITY;
204 int migrate = 0;
205 int cluster = 0;
206 int opt;
207 int wait = 0;
208 int want_enforcement = 0;
209 double duration = 0, start = 0;
210 double scale = 1.0;
211 task_class_t class = RT_CLASS_HARD;
212 struct rt_task param;
213 struct mc2_task mc2_param;
214 struct reservation_config config;
215 int res_type = PERIODIC_POLLING;
216
217 unsigned int job_no;
218
219
220 progname = argv[0];
221
222 /* default for reservation */
223 config.id = 0;
224 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
225 config.cpu = -1;
226
227 mc2_param.crit = CRIT_LEVEL_C;
228
229 budget_ms = 10;
230
231 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
232 switch (opt) {
233 case 'w':
234 wait = 1;
235 break;
236 case 'p':
237 cluster = atoi(optarg);
238 migrate = 1;
239 config.cpu = cluster;
240 break;
241 case 'e':
242 want_enforcement = 1;
243 break;
244 case 's':
245 scale = atof(optarg);
246 break;
247 case 'l':
248 loops = atoi(optarg);
249 break;
250 case 'm':
251 mc2_param.crit = atoi(optarg);
252 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
253 usage("Invalid criticality level.");
254 }
255 res_type = PERIODIC_POLLING;
256 break;
257 case 'b':
258 budget_ms = atof(optarg);
259 break;
260 case 'i':
261 config.priority = atoi(optarg);
262 break;
263 case ':':
264 usage("Argument missing.");
265 break;
266 case '?':
267 default:
268 usage("Bad argument.");
269 break;
270 }
271 }
272
273 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
274 usage("Bad criticailty level or priority");
275
276 if (argc - optind < 3)
277 usage("Arguments missing.");
278
279 wcet_ms = atof(argv[optind + 0]);
280 period_ms = atof(argv[optind + 1]);
281
282 wcet = ms2ns(wcet_ms);
283 period = ms2ns(period_ms);
284 budget = ms2ns(budget_ms);
285
286 if (wcet <= 0)
287 usage("The worst-case execution time must be a "
288 "positive number.");
289 if (period <= 0)
290 usage("The period must be a positive number.");
291 if (wcet > period) {
292 usage("The worst-case execution time must not "
293 "exceed the period.");
294 }
295
296 duration = atof(argv[optind + 2]);
297
298 if (migrate) {
299 ret = be_migrate_to_domain(cluster);
300 if (ret < 0)
301 bail_out("could not migrate to target partition or cluster.");
302 }
303
304 /* reservation config */
305 config.id = gettid();
306
307 config.polling_params.budget = budget;
308 config.polling_params.period = period;
309 config.polling_params.offset = 0;
310 config.polling_params.relative_deadline = 0;
311 if (config.polling_params.budget > config.polling_params.period) {
312 usage("The budget must not exceed the period.");
313 }
314
315 /* create a reservation */
316 ret = reservation_create(res_type, &config);
317 if (ret < 0) {
318 bail_out("failed to create reservation.");
319 }
320
321 randInit(-2);
322 init_job();
323
324
325 init_rt_task_param(&param);
326 param.exec_cost = wcet;
327 param.period = period;
328 param.priority = priority;
329 param.cls = class;
330 param.release_policy = TASK_PERIODIC;
331 param.budget_policy = (want_enforcement) ?
332 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
333 if (migrate) {
334 param.cpu = gettid();
335 }
336 ret = set_rt_task_param(gettid(), &param);
337
338 if (ret < 0)
339 bail_out("could not setup rt task params");
340
341 mc2_param.res_id = gettid();
342 ret = set_mc2_task_param(gettid(), &mc2_param);
343//printf("SET_MC2_TASK\n");
344 if (ret < 0)
345 bail_out("could not setup mc2 task params");
346
347 init_litmus();
348//printf("CALL\n");
349 if (mc2_param.crit == CRIT_LEVEL_C)
350 set_page_color(-1);
351 else if (mc2_param.crit < CRIT_LEVEL_C)
352 set_page_color(config.cpu);
353//printf("CALL\n");
354
355//printf("INIT_LITMUS\n");
356 start = wctime();
357 ret = task_mode(LITMUS_RT_TASK);
358//printf("TASK_MODE\n");
359 if (ret != 0)
360 bail_out("could not become RT task");
361
362
363 if (wait) {
364//printf("BEFORE WAIT\n");
365 ret = wait_for_ts_release();
366 if (ret != 0)
367 bail_out("wait_for_ts_release()");
368 start = wctime();
369 }
370
371 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
372
373 ret = task_mode(BACKGROUND_TASK);
374 if (ret != 0)
375 bail_out("could not become regular task (huh?)");
376
377 reservation_destroy(gettid(), config.cpu);
378 post_job();
379 printf("%s/%d finished.\n",progname, gettid());
380 return 0;
381}
diff --git a/bin/rt_neighborhood_spin.c b/bin/rt_neighborhood_spin.c
new file mode 100644
index 0000000..67b1b7e
--- /dev/null
+++ b/bin/rt_neighborhood_spin.c
@@ -0,0 +1,337 @@
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#include "DISstressmarkRNG.h"
16#include "utili.h"
17
18static char* progname;
19int loops = 1;
20struct timeval t1, t2;
21
22 long int seed;
23 int dimension;
24 int numberLines;
25 int minThickness;
26 int maxThickness;
27 int distanceShort;
28 int distanceLong;
29 int bitDepth;
30 int maxPixel;
31 Pixel *image;
32 Neighborhood values;
33
34int init_job() {
35 //fscanf(stdin, "%ld %d %d %d %d %d %d %d",
36// &seed, &bitDepth, &dimension, &numberLines,
37// &minThickness, &maxThickness,
38// &distanceShort, &distanceLong);
39
40 seed = -2;
41 bitDepth = 8;
42 /*
43 dimension = 1501;
44 numberLines = 10000;
45 minThickness = 10;
46 maxThickness = 1000;
47 distanceShort = 100;
48 distanceLong = 1000;
49 */
50 dimension = randInt(100,501);
51 numberLines = randInt(200,1000);
52 minThickness = randInt(1,dimension/2);
53 maxThickness = randInt(minThickness+1,dimension-1);
54 distanceShort = 10;
55 distanceLong = randInt(20, dimension-1);
56
57 assert((seed >= MIN_SEED) && (seed <= MAX_SEED));
58 assert((dimension > 0) && (dimension <= MAX_DIMENSION));
59 assert((numberLines > 0) && (numberLines <= MAX_NUMBER_LINES));
60 assert((minThickness > 0) && (minThickness < dimension));
61 assert((maxThickness >= minThickness) && (maxThickness < dimension));
62 assert((distanceShort > 0) && (distanceShort < dimension));
63 assert((distanceLong > 0) && (distanceLong < dimension));
64 assert((bitDepth >= MIN_BIT_DEPTH) && (bitDepth <= MAX_BIT_DEPTH));
65
66 //randInit(seed);
67 maxPixel = (1 << bitDepth) - 1;
68 image = createImage(dimension, maxPixel, numberLines,
69 minThickness, maxThickness);
70 assert (image != NULL);
71
72 return 0;
73}
74
75int main_job() {
76 neighborhoodCalculation(image, dimension,
77 distanceShort, distanceLong, &values, maxPixel);
78
79 return 0;
80}
81
82int post_job() {
83 if (image) {
84 free((Pixel *)image);
85 image = NULL;
86 }
87 return (0);
88}
89
90static void usage(char *error) {
91 fprintf(stderr, "Error: %s\n", error);
92 fprintf(stderr,
93 "Usage:\n"
94 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
95 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
96 " rt_spin -l\n"
97 "\n"
98 "COMMON-OPTS = [-w] [-s SCALE]\n"
99 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
100 "\n"
101 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
102 exit(EXIT_FAILURE);
103}
104
105inline unsigned long get_cyclecount (void)
106{
107 unsigned long value;
108 // Read CCNT Register
109 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
110 return value;
111}
112
113
114static int loop_main(double exec_time, double emergency_exit)
115{
116 double last_loop = 0, loop_start;
117 int tmp = 0;
118
119 double start = cputime();
120 double now = cputime();
121
122 while (now + last_loop < start + exec_time) {
123 loop_start = now;
124 tmp += main_job();
125 now = cputime();
126 last_loop = now - loop_start;
127 if (emergency_exit && wctime() > emergency_exit) {
128 /* Oops --- this should only be possible if the execution time tracking
129 * is broken in the LITMUS^RT kernel. */
130 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid());
131 fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n");
132 break;
133 }
134 }
135
136 return tmp;
137}
138
139static int job(double exec_time, double program_end)
140{
141 if (wctime() > program_end)
142 return 0;
143 else {
144 init_job();
145 //gettimeofday(&t1, NULL);
146 loop_main(exec_time, program_end + 1);
147 //gettimeofday(&t2, NULL);
148 //printf("%ld us\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
149 post_job();
150 sleep_next_period();
151 return 1;
152 }
153}
154
155#define OPTSTR "p:wves:l:m:i:b:"
156int main(int argc, char** argv)
157{
158 int ret;
159 lt_t wcet;
160 lt_t period;
161 lt_t budget;
162 double wcet_ms, period_ms, budget_ms;
163 unsigned int priority = LITMUS_NO_PRIORITY;
164 int migrate = 0;
165 int cluster = 0;
166 int opt;
167 int wait = 0;
168 int want_enforcement = 0;
169 double duration = 0, start = 0;
170 double scale = 1.0;
171 task_class_t class = RT_CLASS_HARD;
172 struct rt_task param;
173 struct mc2_task mc2_param;
174 struct reservation_config config;
175 int res_type = PERIODIC_POLLING;
176
177 unsigned int job_no;
178
179
180 progname = argv[0];
181
182 /* default for reservation */
183 config.id = 0;
184 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
185 config.cpu = -1;
186
187 mc2_param.crit = CRIT_LEVEL_C;
188
189 budget_ms = 10;
190
191 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
192 switch (opt) {
193 case 'w':
194 wait = 1;
195 break;
196 case 'p':
197 cluster = atoi(optarg);
198 migrate = 1;
199 config.cpu = cluster;
200 break;
201 case 'e':
202 want_enforcement = 1;
203 break;
204 case 's':
205 scale = atof(optarg);
206 break;
207 case 'l':
208 loops = atoi(optarg);
209 break;
210 case 'm':
211 mc2_param.crit = atoi(optarg);
212 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
213 usage("Invalid criticality level.");
214 }
215 res_type = PERIODIC_POLLING;
216 break;
217 case 'b':
218 budget_ms = atof(optarg);
219 break;
220 case 'i':
221 config.priority = atoi(optarg);
222 break;
223 case ':':
224 usage("Argument missing.");
225 break;
226 case '?':
227 default:
228 usage("Bad argument.");
229 break;
230 }
231 }
232
233 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
234 usage("Bad criticailty level or priority");
235
236 if (argc - optind < 3)
237 usage("Arguments missing.");
238
239 wcet_ms = atof(argv[optind + 0]);
240 period_ms = atof(argv[optind + 1]);
241
242 wcet = ms2ns(wcet_ms);
243 period = ms2ns(period_ms);
244 budget = ms2ns(budget_ms);
245
246 if (wcet <= 0)
247 usage("The worst-case execution time must be a "
248 "positive number.");
249 if (period <= 0)
250 usage("The period must be a positive number.");
251 if (wcet > period) {
252 usage("The worst-case execution time must not "
253 "exceed the period.");
254 }
255
256 duration = atof(argv[optind + 2]);
257
258 if (migrate) {
259 ret = be_migrate_to_domain(cluster);
260 if (ret < 0)
261 bail_out("could not migrate to target partition or cluster.");
262 }
263
264 /* reservation config */
265 config.id = gettid();
266
267 config.polling_params.budget = budget;
268 config.polling_params.period = period;
269 config.polling_params.offset = 0;
270 config.polling_params.relative_deadline = 0;
271 if (config.polling_params.budget > config.polling_params.period) {
272 usage("The budget must not exceed the period.");
273 }
274
275 /* create a reservation */
276 ret = reservation_create(res_type, &config);
277 if (ret < 0) {
278 bail_out("failed to create reservation.");
279 }
280 //init_job();
281 randInit(-2);
282
283 init_rt_task_param(&param);
284 param.exec_cost = wcet;
285 param.period = period;
286 param.priority = priority;
287 param.cls = class;
288 param.release_policy = TASK_PERIODIC;
289 param.budget_policy = (want_enforcement) ?
290 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
291 if (migrate) {
292 param.cpu = gettid();
293 }
294 ret = set_rt_task_param(gettid(), &param);
295
296 if (ret < 0)
297 bail_out("could not setup rt task params");
298
299 mc2_param.res_id = gettid();
300 ret = set_mc2_task_param(gettid(), &mc2_param);
301
302 if (ret < 0)
303 bail_out("could not setup mc2 task params");
304
305 init_litmus();
306
307 if (mc2_param.crit == CRIT_LEVEL_C)
308 set_page_color(-1);
309 else if (mc2_param.crit < CRIT_LEVEL_C)
310 set_page_color(config.cpu);
311
312 start = wctime();
313 ret = task_mode(LITMUS_RT_TASK);
314
315 if (ret != 0)
316 bail_out("could not become RT task");
317
318
319 if (wait) {
320
321 ret = wait_for_ts_release();
322 if (ret != 0)
323 bail_out("wait_for_ts_release()");
324 start = wctime();
325 }
326
327 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
328
329 ret = task_mode(BACKGROUND_TASK);
330 if (ret != 0)
331 bail_out("could not become regular task (huh?)");
332
333 reservation_destroy(gettid(), config.cpu);
334 //post_job();
335 //printf("%s/%d finished.\n",progname, gettid());
336 return 0;
337}
diff --git a/bin/rt_pointer.c b/bin/rt_pointer.c
new file mode 100644
index 0000000..bfd9fec
--- /dev/null
+++ b/bin/rt_pointer.c
@@ -0,0 +1,430 @@
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#include "DISstressmarkRNG.h"
16
17#define MIN_FIELD_SIZE 16
18#define MAX_FIELD_SIZE 16777216
19#define MIN_WINDOW_SIZE 1
20#define MAX_WINDOW_SIZE 15
21#define MIN_HOP_LIMIT 1
22
23#define MAX_HOP_LIMIT 4294967295U
24
25#define MIN_SEED -2147483647
26#define MAX_SEED -1
27#define MIN_THREADS 1
28#define MAX_THREADS 256
29
30static char* progname;
31int loops = 1;
32struct timeval t1, t2;
33
34unsigned int *field;
35unsigned int f_max;
36unsigned short int w;
37unsigned int maxhops;
38int seed = -2;
39unsigned int n_max;
40
41clock_t startTime;
42
43struct threadS{
44unsigned int initial;
45unsigned int minStop;
46unsigned int maxStop;
47unsigned int hops;
48}*thread;
49
50int init_job() {
51 //fscanf(stdin, "%lu %u %lu %ld %u",
52 // &f, &l, &maxhops, &seed, &n);
53
54 //f_max = 102400; //1048570;
55 f_max = 409600;
56 //f_max = 240000; // case study
57 maxhops = 512000;
58 //n_max = 50;
59 n_max = 10;
60
61 assert ((f_max >= MIN_FIELD_SIZE) && (f_max <= MAX_FIELD_SIZE));
62 assert ((maxhops >= MIN_HOP_LIMIT) && (maxhops <= MAX_HOP_LIMIT));
63 assert ((n_max >= MIN_THREADS) && (n_max <= MAX_THREADS));
64 if ((thread = (struct threadS *)malloc(n_max*sizeof(struct threadS))) == NULL)
65 return (-1);
66
67 /*for (l=0; l<n; l++){
68 //fscanf(stdin, "%lu %lu %lu",
69 //&(thread[l].initial), &(thread[l].minStop), &(thread[l].maxStop));
70 thread[l].initial = 10;
71 thread[l].minStop = f - thread[l].initial;
72 thread[l].maxStop = f - thread[l].initial;
73
74 assert ((thread[l].initial >= 0) && (thread[l].initial < f));
75 assert ((thread[l].minStop >= 0) && (thread[l].minStop < f));
76 assert ((thread[l].maxStop >= 0) && (thread[l].maxStop < f));
77 }
78*/
79 if ((field = (unsigned int *)malloc(f_max*sizeof(int))) == NULL)
80 return (-1);
81
82 //randInit(seed);
83 /*
84 for (l=0; l<f; l++){
85 field[l] = randInt(0, f-w);
86 }
87 */
88 return 0;
89}
90
91int main_job() {
92 unsigned int l;
93 unsigned int f, n;
94 unsigned short int w;
95
96 /* online appendix setting */
97
98 f = randInt(2048,f_max);
99 w = 1; //randInt(0,4)*2 + 1;
100 maxhops = 204800; //4096;
101 n = randInt(1,20);
102
103
104 /* case-study */
105/*
106 f = randInt(1024,240000); //409600);
107 w = 1; //randInt(0,4)*2 + 1;
108 maxhops = 1024; //4096;
109 n = 1; //randInt(4,30);
110*/
111
112 assert ((w >= MIN_WINDOW_SIZE) && (w <= MAX_WINDOW_SIZE));
113 assert (w % 2 == 1);
114 assert (f > w);
115
116 for (l=0; l<n; l++){
117 //fscanf(stdin, "%lu %lu %lu",
118 //&(thread[l].initial), &(thread[l].minStop), &(thread[l].maxStop));
119 thread[l].initial = 1;
120 thread[l].minStop = f - thread[l].initial;
121 thread[l].maxStop = f - thread[l].initial;
122
123 assert ((thread[l].initial >= 0) && (thread[l].initial < f));
124 assert ((thread[l].minStop >= 0) && (thread[l].minStop < f));
125 assert ((thread[l].maxStop >= 0) && (thread[l].maxStop < f));
126 }
127
128 for (l=0; l<f; l++){
129 field[l] = randInt(0, f-w);
130 }
131
132 for (l=0; l<n; l++) {
133 unsigned int index;
134 unsigned int minStop, maxStop;
135 unsigned int hops;
136
137 hops = 0;
138 minStop = thread[l].minStop;
139 maxStop = thread[l].maxStop;
140 index = thread[l].initial;
141 while ((hops < maxhops) &&
142 (!((index >= minStop) &&
143 (index < maxStop)))){
144
145 unsigned int ll, lll;
146 unsigned int max, min;
147 unsigned int partition;
148 unsigned int high;
149
150 partition = field[index];
151 max = MAX_FIELD_SIZE;
152 min = 0;
153 high = 0;
154
155 for (ll=0; ll<w; ll++){
156 unsigned int balance;
157 unsigned int x;
158 x = field[index+ll];
159
160 if (x > max) high++;
161 else if (x > min){ /* start else* */
162 partition = x;
163 balance = 0;
164 for (lll=ll+1; lll<w; lll++){
165 if (field[index+lll] > partition) balance++;
166 }/* end for loop */
167
168 if (balance+high == w/2) break;
169 else if (balance+high > w/2){
170 min = partition;
171 }/* end if */
172 else {
173 max = partition;
174 high++;
175 }/* end else */
176 }
177 if (min == max) break;
178 } /* end else* */
179 index = (partition+hops)%(f-w);
180 hops++;
181 }/* end loop ll */
182 thread[l].hops = hops;
183 } /* end while */
184
185 return(0);
186}
187
188int post_job() {
189 if (field) {
190 free(field);
191 field = NULL;
192 }
193 if (thread) {
194 free(thread);
195 thread = NULL;
196 }
197 return 0;
198}
199
200static void usage(char *error) {
201 fprintf(stderr, "Error: %s\n", error);
202 fprintf(stderr,
203 "Usage:\n"
204 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
205 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
206 " rt_spin -l\n"
207 "\n"
208 "COMMON-OPTS = [-w] [-s SCALE]\n"
209 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
210 "\n"
211 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
212 exit(EXIT_FAILURE);
213}
214
215inline unsigned long get_cyclecount (void)
216{
217 unsigned long value;
218 // Read CCNT Register
219 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
220 return value;
221}
222
223static int job(double exec_time, double program_end)
224{
225 if (wctime() > program_end)
226 return 0;
227 else {
228 register int iter = 0;
229 //register unsigned long t;
230 //t = get_cyclecount();
231 //init_job();
232 //gettimeofday(&t1, NULL);
233 //while (iter++ < loops) {
234 main_job();
235 //}
236 //t = get_cyclecount() - t;
237 //printf("%ld cycles\n", t);
238 //gettimeofday(&t2, NULL);
239 //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
240 //post_job();
241 sleep_next_period();
242 return 1;
243 }
244}
245
246#define OPTSTR "p:wves:l:m:i:b:"
247int main(int argc, char** argv)
248{
249 int ret;
250 lt_t wcet;
251 lt_t period;
252 lt_t budget;
253 double wcet_ms, period_ms, budget_ms;
254 unsigned int priority = LITMUS_NO_PRIORITY;
255 int migrate = 0;
256 int cluster = 0;
257 int opt;
258 int wait = 0;
259 int want_enforcement = 0;
260 double duration = 0, start = 0;
261 double scale = 1.0;
262 task_class_t class = RT_CLASS_HARD;
263 struct rt_task param;
264 struct mc2_task mc2_param;
265 struct reservation_config config;
266 int res_type = PERIODIC_POLLING;
267
268 progname = argv[0];
269
270 /* default for reservation */
271 config.id = 0;
272 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
273 config.cpu = -1;
274
275 mc2_param.crit = CRIT_LEVEL_C;
276
277 budget_ms = 10;
278
279 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
280 switch (opt) {
281 case 'w':
282 wait = 1;
283 break;
284 case 'p':
285 cluster = atoi(optarg);
286 migrate = 1;
287 config.cpu = cluster;
288 break;
289 case 'e':
290 want_enforcement = 1;
291 break;
292 case 's':
293 scale = atof(optarg);
294 break;
295 case 'l':
296 loops = atoi(optarg);
297 break;
298 case 'm':
299 mc2_param.crit = atoi(optarg);
300 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
301 usage("Invalid criticality level.");
302 }
303 res_type = PERIODIC_POLLING;
304 break;
305 case 'b':
306 budget_ms = atof(optarg);
307 break;
308 case 'i':
309 config.priority = atoi(optarg);
310 break;
311 case ':':
312 usage("Argument missing.");
313 break;
314 case '?':
315 default:
316 usage("Bad argument.");
317 break;
318 }
319 }
320
321 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
322 usage("Bad criticailty level or priority");
323
324 if (argc - optind < 3)
325 usage("Arguments missing.");
326
327 wcet_ms = atof(argv[optind + 0]);
328 period_ms = atof(argv[optind + 1]);
329
330 wcet = ms2ns(wcet_ms);
331 period = ms2ns(period_ms);
332 budget = ms2ns(budget_ms);
333
334 if (wcet <= 0)
335 usage("The worst-case execution time must be a "
336 "positive number.");
337 if (period <= 0)
338 usage("The period must be a positive number.");
339 if (wcet > period) {
340 usage("The worst-case execution time must not "
341 "exceed the period.");
342 }
343
344 duration = atof(argv[optind + 2]);
345
346 if (migrate) {
347 ret = be_migrate_to_domain(cluster);
348 if (ret < 0)
349 bail_out("could not migrate to target partition or cluster.");
350 }
351
352 /* reservation config */
353 config.id = gettid();
354
355 config.polling_params.budget = budget;
356 config.polling_params.period = period;
357 config.polling_params.offset = 0;
358 config.polling_params.relative_deadline = 0;
359 if (config.polling_params.budget > config.polling_params.period) {
360 usage("The budget must not exceed the period.");
361 }
362
363 /* create a reservation */
364 ret = reservation_create(res_type, &config);
365 if (ret < 0) {
366 bail_out("failed to create reservation.");
367 }
368 //srand (time(NULL));
369 //randInit((-rand()%65535)-2);
370 randInit(-2);
371
372 init_job();
373
374 init_rt_task_param(&param);
375 param.exec_cost = wcet;
376 param.period = period;
377 param.priority = priority;
378 param.cls = class;
379 param.release_policy = TASK_PERIODIC;
380 param.budget_policy = (want_enforcement) ?
381 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
382 if (migrate) {
383 param.cpu = gettid();
384 }
385 ret = set_rt_task_param(gettid(), &param);
386
387 if (ret < 0)
388 bail_out("could not setup rt task params");
389
390 mc2_param.res_id = gettid();
391 ret = set_mc2_task_param(gettid(), &mc2_param);
392//printf("SET_MC2_TASK\n");
393 if (ret < 0)
394 bail_out("could not setup mc2 task params");
395
396 init_litmus();
397//printf("CALL\n");
398 if (mc2_param.crit == CRIT_LEVEL_C)
399 set_page_color(-1);
400 else if (mc2_param.crit < CRIT_LEVEL_C)
401 set_page_color(config.cpu);
402//printf("CALL\n");
403
404//printf("INIT_LITMUS\n");
405 start = wctime();
406 ret = task_mode(LITMUS_RT_TASK);
407//printf("TASK_MODE\n");
408 if (ret != 0)
409 bail_out("could not become RT task");
410
411
412 if (wait) {
413//printf("BEFORE WAIT\n");
414 ret = wait_for_ts_release();
415 if (ret != 0)
416 bail_out("wait_for_ts_release()");
417 start = wctime();
418 }
419
420 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
421
422 ret = task_mode(BACKGROUND_TASK);
423 if (ret != 0)
424 bail_out("could not become regular task (huh?)");
425
426 reservation_destroy(gettid(), config.cpu);
427 //post_job();
428 printf("%s/%d finished.\n",progname, gettid());
429 return 0;
430}
diff --git a/bin/rt_pointer_spin.c b/bin/rt_pointer_spin.c
new file mode 100644
index 0000000..73e7b1d
--- /dev/null
+++ b/bin/rt_pointer_spin.c
@@ -0,0 +1,439 @@
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#include "DISstressmarkRNG.h"
16
17#define MIN_FIELD_SIZE 16
18#define MAX_FIELD_SIZE 16777216
19#define MIN_WINDOW_SIZE 1
20#define MAX_WINDOW_SIZE 15
21#define MIN_HOP_LIMIT 1
22
23#define MAX_HOP_LIMIT 4294967295U
24
25#define MIN_SEED -2147483647
26#define MAX_SEED -1
27#define MIN_THREADS 1
28#define MAX_THREADS 256
29
30static char* progname;
31int loops = 1;
32struct timeval t1, t2;
33
34unsigned int *field;
35unsigned int f;
36unsigned short int w;
37unsigned int maxhops;
38int seed = -2;
39unsigned int n;
40
41clock_t startTime;
42
43struct threadS{
44unsigned int initial;
45unsigned int minStop;
46unsigned int maxStop;
47unsigned int hops;
48}*thread;
49
50unsigned int l;
51
52int init_job() {
53 //fscanf(stdin, "%lu %u %lu %ld %u",
54 // &f, &l, &maxhops, &seed, &n);
55
56 f = 1048570;
57 l = 15;
58 maxhops = 5120000;
59 n = 1;
60
61 assert ((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE));
62 w = (unsigned int) l;
63 assert ((w >= MIN_WINDOW_SIZE) && (w <= MAX_WINDOW_SIZE));
64 assert (w % 2 == 1);
65 assert (f > w);
66 assert ((maxhops >= MIN_HOP_LIMIT) && (maxhops <= MAX_HOP_LIMIT));
67 assert ((seed >= MIN_SEED) && (seed <= MAX_SEED));
68
69 assert ((n >= MIN_THREADS) && (n <= MAX_THREADS));
70 if ((thread = (struct threadS *)malloc(n*sizeof(struct threadS))) == NULL)
71 return (-1);
72
73 /*for (l=0; l<n; l++){
74 //fscanf(stdin, "%lu %lu %lu",
75 //&(thread[l].initial), &(thread[l].minStop), &(thread[l].maxStop));
76 thread[l].initial = 10;
77 thread[l].minStop = f - thread[l].initial;
78 thread[l].maxStop = f - thread[l].initial;
79
80 assert ((thread[l].initial >= 0) && (thread[l].initial < f));
81 assert ((thread[l].minStop >= 0) && (thread[l].minStop < f));
82 assert ((thread[l].maxStop >= 0) && (thread[l].maxStop < f));
83 }
84*/
85 if ((field = (unsigned int *)malloc(f*sizeof(int))) == NULL)
86 return (-1);
87
88 //randInit(seed);
89 /*
90 for (l=0; l<f; l++){
91 field[l] = randInt(0, f-w);
92 }
93 */
94 return 0;
95}
96
97int main_job() {
98 f = randInt(16,65536);
99 w = randInt(0,7)*2 + 1;
100 maxhops = 32768;
101 n = 1;
102 for (l=0; l<n; l++){
103 //fscanf(stdin, "%lu %lu %lu",
104 //&(thread[l].initial), &(thread[l].minStop), &(thread[l].maxStop));
105 thread[l].initial = 10;
106 thread[l].minStop = f - thread[l].initial;
107 thread[l].maxStop = f - thread[l].initial;
108
109 assert ((thread[l].initial >= 0) && (thread[l].initial < f));
110 assert ((thread[l].minStop >= 0) && (thread[l].minStop < f));
111 assert ((thread[l].maxStop >= 0) && (thread[l].maxStop < f));
112 }
113
114 for (l=0; l<f; l++){
115 field[l] = randInt(0, f-w);
116 }
117
118for (l=0; l<n; l++) {
119 unsigned int index;
120 unsigned int minStop, maxStop;
121 unsigned int hops;
122
123 hops = 0;
124 minStop = thread[l].minStop;
125 maxStop = thread[l].maxStop;
126 index = thread[l].initial;
127 while ((hops < maxhops) &&
128 (!((index >= minStop) &&
129 (index < maxStop)))){
130
131 unsigned int ll, lll;
132 unsigned int max, min;
133 unsigned int partition;
134 unsigned int high;
135
136 partition = field[index];
137 max = MAX_FIELD_SIZE;
138 min = 0;
139 high = 0;
140
141 for (ll=0; ll<w; ll++){
142 unsigned int balance;
143 unsigned int x;
144 x = field[index+ll];
145
146 if (x > max) high++;
147 else if (x > min){ /* start else* */
148 partition = x;
149 balance = 0;
150 for (lll=ll+1; lll<w; lll++){
151 if (field[index+lll] > partition) balance++;
152 }/* end for loop */
153
154 if (balance+high == w/2) break;
155 else if (balance+high > w/2){
156 min = partition;
157 }/* end if */
158 else {
159 max = partition;
160 high++;
161 }/* end else */
162 }
163 if (min == max) break;
164 } /* end else* */
165 index = (partition+hops)%(f-w);
166 hops++;
167 }/* end loop ll */
168 thread[l].hops = hops;
169} /* end while */
170
171 return(0);
172}
173
174int post_job() {
175 if (field) {
176 free(field);
177 field = NULL;
178 }
179 if (thread) {
180 free(thread);
181 thread = NULL;
182 }
183 return 0;
184}
185
186static void usage(char *error) {
187 fprintf(stderr, "Error: %s\n", error);
188 fprintf(stderr,
189 "Usage:\n"
190 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
191 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
192 " rt_spin -l\n"
193 "\n"
194 "COMMON-OPTS = [-w] [-s SCALE]\n"
195 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
196 "\n"
197 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
198 exit(EXIT_FAILURE);
199}
200
201inline unsigned long get_cyclecount (void)
202{
203 unsigned long value;
204 // Read CCNT Register
205 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
206 return value;
207}
208
209static int loop_main(double exec_time, double emergency_exit)
210{
211 double last_loop = 0, loop_start;
212 int tmp = 0;
213
214 double start = cputime();
215 double now = cputime();
216
217 while (now + last_loop < start + exec_time) {
218 loop_start = now;
219 tmp += main_job();
220 now = cputime();
221 last_loop = now - loop_start;
222 if (emergency_exit && wctime() > emergency_exit) {
223 /* Oops --- this should only be possible if the execution time tracking
224 * is broken in the LITMUS^RT kernel. */
225 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid());
226 fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n");
227 break;
228 }
229 }
230
231 return tmp;
232}
233
234static int job(double exec_time, double program_end)
235{
236 if (wctime() > program_end)
237 return 0;
238 else {
239 register int iter = 0;
240 //register unsigned long t;
241 //t = get_cyclecount();
242 //init_job();
243 //gettimeofday(&t1, NULL);
244 loop_main(exec_time, program_end + 1);
245 //t = get_cyclecount() - t;
246 //printf("%ld cycles\n", t);
247 //gettimeofday(&t2, NULL);
248 //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
249 //post_job();
250 sleep_next_period();
251 return 1;
252 }
253}
254
255#define OPTSTR "p:wves:l:m:i:b:"
256int main(int argc, char** argv)
257{
258 int ret;
259 lt_t wcet;
260 lt_t period;
261 lt_t budget;
262 double wcet_ms, period_ms, budget_ms;
263 unsigned int priority = LITMUS_NO_PRIORITY;
264 int migrate = 0;
265 int cluster = 0;
266 int opt;
267 int wait = 0;
268 int want_enforcement = 0;
269 double duration = 0, start = 0;
270 double scale = 1.0;
271 task_class_t class = RT_CLASS_HARD;
272 struct rt_task param;
273 struct mc2_task mc2_param;
274 struct reservation_config config;
275 int res_type = PERIODIC_POLLING;
276
277 progname = argv[0];
278
279 /* default for reservation */
280 config.id = 0;
281 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
282 config.cpu = -1;
283
284 mc2_param.crit = CRIT_LEVEL_C;
285
286 budget_ms = 10;
287
288 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
289 switch (opt) {
290 case 'w':
291 wait = 1;
292 break;
293 case 'p':
294 cluster = atoi(optarg);
295 migrate = 1;
296 config.cpu = cluster;
297 break;
298 case 'e':
299 want_enforcement = 1;
300 break;
301 case 's':
302 scale = atof(optarg);
303 break;
304 case 'l':
305 loops = atoi(optarg);
306 break;
307 case 'm':
308 mc2_param.crit = atoi(optarg);
309 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
310 usage("Invalid criticality level.");
311 }
312 res_type = PERIODIC_POLLING;
313 break;
314 case 'b':
315 budget_ms = atof(optarg);
316 break;
317 case 'i':
318 config.priority = atoi(optarg);
319 break;
320 case ':':
321 usage("Argument missing.");
322 break;
323 case '?':
324 default:
325 usage("Bad argument.");
326 break;
327 }
328 }
329
330 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
331 usage("Bad criticailty level or priority");
332
333 if (argc - optind < 3)
334 usage("Arguments missing.");
335
336 wcet_ms = atof(argv[optind + 0]);
337 period_ms = atof(argv[optind + 1]);
338
339 wcet = ms2ns(wcet_ms);
340 period = ms2ns(period_ms);
341 budget = ms2ns(budget_ms);
342
343 if (wcet <= 0)
344 usage("The worst-case execution time must be a "
345 "positive number.");
346 if (period <= 0)
347 usage("The period must be a positive number.");
348 if (wcet > period) {
349 usage("The worst-case execution time must not "
350 "exceed the period.");
351 }
352
353 duration = atof(argv[optind + 2]);
354
355 if (migrate) {
356 ret = be_migrate_to_domain(cluster);
357 if (ret < 0)
358 bail_out("could not migrate to target partition or cluster.");
359 }
360
361 /* reservation config */
362 config.id = gettid();
363
364 config.polling_params.budget = budget;
365 config.polling_params.period = period;
366 config.polling_params.offset = 0;
367 config.polling_params.relative_deadline = 0;
368 if (config.polling_params.budget > config.polling_params.period) {
369 usage("The budget must not exceed the period.");
370 }
371
372 /* create a reservation */
373 ret = reservation_create(res_type, &config);
374 if (ret < 0) {
375 bail_out("failed to create reservation.");
376 }
377 //srand (time(NULL));
378 //randInit((-rand()%65535)-2);
379 randInit(-2);
380
381 init_job();
382
383 init_rt_task_param(&param);
384 param.exec_cost = wcet;
385 param.period = period;
386 param.priority = priority;
387 param.cls = class;
388 param.release_policy = TASK_PERIODIC;
389 param.budget_policy = (want_enforcement) ?
390 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
391 if (migrate) {
392 param.cpu = gettid();
393 }
394 ret = set_rt_task_param(gettid(), &param);
395
396 if (ret < 0)
397 bail_out("could not setup rt task params");
398
399 mc2_param.res_id = gettid();
400 ret = set_mc2_task_param(gettid(), &mc2_param);
401//printf("SET_MC2_TASK\n");
402 if (ret < 0)
403 bail_out("could not setup mc2 task params");
404
405 init_litmus();
406//printf("CALL\n");
407 if (mc2_param.crit == CRIT_LEVEL_C)
408 set_page_color(-1);
409 else if (mc2_param.crit < CRIT_LEVEL_C)
410 set_page_color(config.cpu);
411//printf("CALL\n");
412
413//printf("INIT_LITMUS\n");
414 start = wctime();
415 ret = task_mode(LITMUS_RT_TASK);
416//printf("TASK_MODE\n");
417 if (ret != 0)
418 bail_out("could not become RT task");
419
420
421 if (wait) {
422//printf("BEFORE WAIT\n");
423 ret = wait_for_ts_release();
424 if (ret != 0)
425 bail_out("wait_for_ts_release()");
426 start = wctime();
427 }
428
429 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
430
431 ret = task_mode(BACKGROUND_TASK);
432 if (ret != 0)
433 bail_out("could not become regular task (huh?)");
434
435 reservation_destroy(gettid(), config.cpu);
436 post_job();
437 //printf("%s/%d finished.\n",progname, gettid());
438 return 0;
439}
diff --git a/bin/rt_skeleton.c b/bin/rt_skeleton.c
new file mode 100644
index 0000000..16e189a
--- /dev/null
+++ b/bin/rt_skeleton.c
@@ -0,0 +1,247 @@
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:"
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
88 unsigned int job_no;
89
90
91 progname = argv[0];
92
93 /* default for reservation */
94 config.id = 0;
95 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
96 config.cpu = -1;
97
98 mc2_param.crit = CRIT_LEVEL_C;
99
100 budget_us = 10000;
101
102 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
103 switch (opt) {
104 case 'w':
105 wait = 1;
106 break;
107 case 'p':
108 cluster = atoi(optarg);
109 migrate = 1;
110 config.cpu = cluster;
111 break;
112 case 'e':
113 want_enforcement = 1;
114 break;
115 case 's':
116 scale = atof(optarg);
117 break;
118 case 'l':
119 loops = atoi(optarg);
120 break;
121 case 'm':
122 mc2_param.crit = atoi(optarg);
123 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
124 usage("Invalid criticality level.");
125 }
126 res_type = PERIODIC_POLLING;
127 break;
128 case 'b':
129 budget_us = atof(optarg);
130 break;
131 case 'i':
132 config.priority = atoi(optarg);
133 break;
134 case ':':
135 usage("Argument missing.");
136 break;
137 case '?':
138 default:
139 usage("Bad argument.");
140 break;
141 }
142 }
143
144 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
145 usage("Bad criticailty level or priority");
146
147 if (argc - optind < 3)
148 usage("Arguments missing.");
149
150 wcet_us = atof(argv[optind + 0]);
151 period_us = atof(argv[optind + 1]);
152
153 wcet = us2ns(wcet_us);
154 period = us2ns(period_us);
155 budget = us2ns(budget_us);
156
157 if (wcet <= 0)
158 usage("The worst-case execution time must be a "
159 "positive number.");
160 if (period <= 0)
161 usage("The period must be a positive number.");
162 if (wcet > period) {
163 usage("The worst-case execution time must not "
164 "exceed the period.");
165 }
166
167 duration = atof(argv[optind + 2]);
168
169 if (migrate) {
170 ret = be_migrate_to_domain(cluster);
171 if (ret < 0)
172 bail_out("could not migrate to target partition or cluster.");
173 }
174
175 /* reservation config */
176 config.id = gettid();
177
178 config.polling_params.budget = budget;
179 config.polling_params.period = period;
180 config.polling_params.offset = 0;
181 config.polling_params.relative_deadline = 0;
182 if (config.polling_params.budget > config.polling_params.period) {
183 usage("The budget must not exceed the period.");
184 }
185
186 /* create a reservation */
187 ret = reservation_create(res_type, &config);
188 if (ret < 0) {
189 bail_out("failed to create reservation.");
190 }
191
192 init_rt_task_param(&param);
193 param.exec_cost = wcet;
194 param.period = period;
195 param.priority = priority;
196 param.cls = class;
197 param.release_policy = TASK_PERIODIC;
198 param.budget_policy = (want_enforcement) ?
199 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
200 if (migrate) {
201 param.cpu = gettid();
202 }
203 ret = set_rt_task_param(gettid(), &param);
204
205 if (ret < 0)
206 bail_out("could not setup rt task params");
207
208 mc2_param.res_id = gettid();
209 ret = set_mc2_task_param(gettid(), &mc2_param);
210//printf("SET_MC2_TASK\n");
211 if (ret < 0)
212 bail_out("could not setup mc2 task params");
213
214 init_litmus();
215//printf("CALL\n");
216 if (mc2_param.crit == CRIT_LEVEL_C)
217 set_page_color(8);
218 else if (mc2_param.crit < CRIT_LEVEL_C)
219 set_page_color(config.cpu*2 + mc2_param.crit);
220//printf("CALL\n");
221
222//printf("INIT_LITMUS\n");
223 start = wctime();
224 ret = task_mode(LITMUS_RT_TASK);
225//printf("TASK_MODE\n");
226 if (ret != 0)
227 bail_out("could not become RT task");
228
229
230 if (wait) {
231//printf("BEFORE WAIT\n");
232 ret = wait_for_ts_release();
233 if (ret != 0)
234 bail_out("wait_for_ts_release()");
235 start = wctime();
236 }
237
238 while (job(wcet_us * 0.000001 * scale, start + duration)) {};
239
240 ret = task_mode(BACKGROUND_TASK);
241 if (ret != 0)
242 bail_out("could not become regular task (huh?)");
243
244 reservation_destroy(gettid(), config.cpu);
245 printf("%s/%d finished.\n",progname, gettid());
246 return 0;
247}
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}
diff --git a/bin/rt_skeleton_us.c b/bin/rt_skeleton_us.c
new file mode 100644
index 0000000..ecf3ed8
--- /dev/null
+++ b/bin/rt_skeleton_us.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 microseconds, DURATION is seconds.\n"
32 "CRITICAL SECTION LENGTH is in microseconds.\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_us, period_us, hyperperiod_us, budget_us;
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_us = 1000000;
90 budget_us = 10000;
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_us = atof(optarg);
145 break;
146 case 'b':
147 budget_us = 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_us = atof(argv[optind + 0]);
169 period_us = atof(argv[optind + 1]);
170
171 wcet = us2ns(wcet_us);
172 period = us2ns(period_us);
173 budget = us2ns(budget_us);
174 hyperperiod = us2ns(hyperperiod_us);
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_us * 0.000001 * scale, start + duration,
273 lock_od, cs_length * 0.000001));
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}
diff --git a/bin/rt_transitive.c b/bin/rt_transitive.c
new file mode 100644
index 0000000..dfad0da
--- /dev/null
+++ b/bin/rt_transitive.c
@@ -0,0 +1,362 @@
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#include "litmus.h"
13#include "common.h"
14#include "DISstressmarkRNG.h"
15
16#define MIN_VERTICES 8
17#define MAX_VERTICES 16384
18#define MIN_EDGES 0
19#define MAX_EDGES 268435456
20#define MIN_SEED -2147483647
21#define MAX_SEED -1
22#define NO_PATH 2147483647
23
24#define MIN_EDGS 0
25#define MAX_EDGE 255
26
27
28static char* progname;
29int loops = 1;
30
31struct timeval t1, t2;
32
33unsigned int *din, *dout;
34unsigned int n, n_max;
35unsigned int m, m_max;
36int seed;
37
38int init_job(){
39 //fscanf(stdin,"%d %d %d", &n, &m, &seed);
40 n_max = 100;
41 m_max = 400;
42 //n_max = 100;
43 //m_max = 1000;
44 seed = -2;
45
46 assert((n_max >= MIN_VERTICES) && (n_max <= MAX_VERTICES));
47 assert((m_max >= MIN_EDGES) && (m_max <= MAX_EDGES));
48 assert (m_max <= n_max*n_max);
49 assert ((seed >= MIN_SEED) && (seed <= MAX_SEED));
50
51 if ((din = (unsigned int *)malloc(n_max*n_max*sizeof(unsigned int))) == NULL)
52 return (-1);
53 if ((dout = (unsigned int *)malloc(n_max*n_max*sizeof(unsigned int))) == NULL)
54 return (-1);
55
56
57
58 //srand (time(NULL));
59 randInit(seed);
60
61 return 0;
62}
63
64int main_job() {
65 unsigned int i, j, k;
66 unsigned int sum;
67
68 /* online */
69/* n = randInt(10, n_max);
70 m = randInt(100, m_max);
71 */
72
73 /* case */
74 n = randInt(5, 50);
75 m = randInt(10, 100);
76
77 for (i=0; i<n_max*n_max; i++){
78 *(din + i) = NO_PATH;
79 *(dout + i) = NO_PATH;
80 }
81
82 for (k=0; k<m; k++){
83 i = randInt(0, n);
84 j = randInt(0, n);
85 *(din + j*n + i) = randInt(MIN_EDGES, MAX_EDGES);
86 }
87
88 for (k=0; k<n; k++){
89 unsigned int old;
90 unsigned int new1;
91 unsigned int *dtemp;
92
93 for (i=0; i<n; i++){
94 for (j=0; j<n; j++){
95 old = *(din + j*n + i);
96 new1 = *(din + j*n + k) + *(din + k*n + i);
97 *(dout + j*n + i) = (new1 < old ? new1: old);
98 assert (*(dout + j*n + i) <= NO_PATH);
99 assert (*(dout + j*n + i) <= *(din + j*n + i));
100 }
101 }
102 dtemp = dout;
103 dout = din;
104 din = dtemp;
105 }
106
107 /*
108 for (j=0; j<n; j++){
109 sum = 0;
110 for (i=0; i<n; i++){
111 if (*(din + j*n + i) != NO_PATH)
112 sum += *(din + j*n + i);
113 }
114 }
115 for (i=0; i<n; i++){
116 sum = 0;
117 for (j=0; j<n; j++){
118 if (*(din + j*n + i) != NO_PATH)
119 sum += *(din+j*n+i);
120 }
121 }
122 */
123 return 0;
124}
125
126int post_job() {
127 if (din) {
128 //free(din);
129 din = NULL;
130 }
131 if (dout) {
132 //free(dout);
133 dout = NULL;
134 }
135 return(0);
136}
137
138static void usage(char *error) {
139 fprintf(stderr, "Error: %s\n", error);
140 fprintf(stderr,
141 "Usage:\n"
142 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
143 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
144 " rt_spin -l\n"
145 "\n"
146 "COMMON-OPTS = [-w] [-s SCALE]\n"
147 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
148 "\n"
149 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
150 exit(EXIT_FAILURE);
151}
152
153inline unsigned long get_cyclecount (void)
154{
155 unsigned long value;
156 // Read CCNT Register
157 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
158 return value;
159}
160
161static int job(double exec_time, double program_end)
162{
163 if (wctime() > program_end)
164 return 0;
165 else {
166 register int iter = 0;
167 //register unsigned long t;
168 //t = get_cyclecount();
169 gettimeofday(&t1, NULL);
170 while (iter++ < loops) {
171 main_job();
172 }
173 //t = get_cyclecount() - t;
174 //printf("%ld cycles\n", t);
175 gettimeofday(&t2, NULL);
176 printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
177 sleep_next_period();
178 return 1;
179 }
180}
181
182#define OPTSTR "p:wves:l:m:i:b:"
183int main(int argc, char** argv)
184{
185 int ret;
186 lt_t wcet;
187 lt_t period;
188 lt_t budget;
189 double wcet_ms, period_ms, budget_ms;
190 unsigned int priority = LITMUS_NO_PRIORITY;
191 int migrate = 0;
192 int cluster = 0;
193 int opt;
194 int wait = 0;
195 int want_enforcement = 0;
196 double duration = 0, start = 0;
197 double scale = 1.0;
198 task_class_t class = RT_CLASS_HARD;
199 struct rt_task param;
200 struct mc2_task mc2_param;
201 struct reservation_config config;
202 int res_type = PERIODIC_POLLING;
203
204 progname = argv[0];
205
206 /* default for reservation */
207 config.id = 0;
208 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
209 config.cpu = -1;
210
211 mc2_param.crit = CRIT_LEVEL_C;
212
213 budget_ms = 10;
214
215 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
216 switch (opt) {
217 case 'w':
218 wait = 1;
219 break;
220 case 'p':
221 cluster = atoi(optarg);
222 migrate = 1;
223 config.cpu = cluster;
224 break;
225 case 'e':
226 want_enforcement = 1;
227 break;
228 case 's':
229 scale = atof(optarg);
230 break;
231 case 'l':
232 loops = atoi(optarg);
233 break;
234 case 'm':
235 mc2_param.crit = atoi(optarg);
236 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
237 usage("Invalid criticality level.");
238 }
239 res_type = PERIODIC_POLLING;
240 break;
241 case 'b':
242 budget_ms = atof(optarg);
243 break;
244 case 'i':
245 config.priority = atoi(optarg);
246 break;
247 case ':':
248 usage("Argument missing.");
249 break;
250 case '?':
251 default:
252 usage("Bad argument.");
253 break;
254 }
255 }
256
257 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
258 usage("Bad criticailty level or priority");
259
260 if (argc - optind < 3)
261 usage("Arguments missing.");
262
263 wcet_ms = atof(argv[optind + 0]);
264 period_ms = atof(argv[optind + 1]);
265
266 wcet = ms2ns(wcet_ms);
267 period = ms2ns(period_ms);
268 budget = ms2ns(budget_ms);
269
270 if (wcet <= 0)
271 usage("The worst-case execution time must be a "
272 "positive number.");
273 if (period <= 0)
274 usage("The period must be a positive number.");
275 if (wcet > period) {
276 usage("The worst-case execution time must not "
277 "exceed the period.");
278 }
279
280 duration = atof(argv[optind + 2]);
281
282 if (migrate) {
283 ret = be_migrate_to_domain(cluster);
284 if (ret < 0)
285 bail_out("could not migrate to target partition or cluster.");
286 }
287
288 /* reservation config */
289 config.id = gettid();
290
291 config.polling_params.budget = budget;
292 config.polling_params.period = period;
293 config.polling_params.offset = 0;
294 config.polling_params.relative_deadline = 0;
295 if (config.polling_params.budget > config.polling_params.period) {
296 usage("The budget must not exceed the period.");
297 }
298
299 /* create a reservation */
300 ret = reservation_create(res_type, &config);
301 if (ret < 0) {
302 bail_out("failed to create reservation.");
303 }
304 init_job();
305
306 init_rt_task_param(&param);
307 param.exec_cost = wcet;
308 param.period = period;
309 param.priority = priority;
310 param.cls = class;
311 param.release_policy = TASK_PERIODIC;
312 param.budget_policy = (want_enforcement) ?
313 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
314 if (migrate) {
315 param.cpu = gettid();
316 }
317 ret = set_rt_task_param(gettid(), &param);
318
319 if (ret < 0)
320 bail_out("could not setup rt task params");
321
322 mc2_param.res_id = gettid();
323 ret = set_mc2_task_param(gettid(), &mc2_param);
324//printf("SET_MC2_TASK\n");
325 if (ret < 0)
326 bail_out("could not setup mc2 task params");
327
328 init_litmus();
329//printf("CALL\n");
330 if (mc2_param.crit == CRIT_LEVEL_C)
331 set_page_color(-1);
332 else if (mc2_param.crit < CRIT_LEVEL_C)
333 set_page_color(config.cpu);
334//printf("CALL\n");
335
336//printf("INIT_LITMUS\n");
337 start = wctime();
338 ret = task_mode(LITMUS_RT_TASK);
339//printf("TASK_MODE\n");
340 if (ret != 0)
341 bail_out("could not become RT task");
342
343
344 if (wait) {
345//printf("BEFORE WAIT\n");
346 ret = wait_for_ts_release();
347 if (ret != 0)
348 bail_out("wait_for_ts_release()");
349 start = wctime();
350 }
351
352 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
353
354 ret = task_mode(BACKGROUND_TASK);
355 if (ret != 0)
356 bail_out("could not become regular task (huh?)");
357
358 reservation_destroy(gettid(), config.cpu);
359 post_job();
360 printf("%s/%d finished.\n",progname, gettid());
361 return 0;
362}
diff --git a/bin/rt_update.c b/bin/rt_update.c
new file mode 100644
index 0000000..4995071
--- /dev/null
+++ b/bin/rt_update.c
@@ -0,0 +1,387 @@
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#include "DISstressmarkRNG.h"
16
17#define MIN_FIELD_SIZE 16
18#define MAX_FIELD_SIZE 16777216
19#define MIN_WINDOW_SIZE 1
20#define MAX_WINDOW_SIZE 15
21#define MIN_HOP_LIMIT 1
22#define MAX_HOP_LIMIT 4294967295U
23#define MIN_SEED -2147483647
24#define MAX_SEED -1
25
26
27static char* progname;
28int loops = 1;
29
30struct timeval t1, t2;
31
32unsigned int *field;
33unsigned int f_max;
34unsigned int idx;
35unsigned short int w;
36unsigned int maxhops;
37int seed;
38unsigned int initial;
39unsigned int minStop;
40unsigned int maxStop;
41unsigned int hops;
42
43int init_job(){
44 //fscanf(stdin, "%u %u %u %d %u %u %u", &f, &l, &maxhops, &seed, &initial, &minStop, &maxStop);
45 //f_max = 819200;
46 f_max = 409600;
47 //f_max = 120000; // for case study
48 maxhops = 1024000;
49 seed = -2;
50 initial = 10;
51 minStop = f_max - 1;
52 maxStop = minStop;
53
54 assert((f_max >= MIN_FIELD_SIZE) && (f_max <= MAX_FIELD_SIZE));
55
56
57 assert((maxhops >= MIN_HOP_LIMIT) && (maxhops <= MAX_HOP_LIMIT));
58 assert((seed >= MIN_SEED) && (seed <= MAX_SEED));
59 assert((initial >= 0) && (initial < f_max));
60 assert((minStop >= 0) && (minStop < f_max));
61 assert((maxStop >= 0) && (maxStop < f_max));
62
63 if ((field = (unsigned int *)malloc(f_max*sizeof(int))) == NULL)
64 return (-1);
65 srand (time(NULL));
66 //randInit(-rand()%65535);
67 randInit(seed);
68 //randInit(seed);
69 /*for (l=0; l<f; l++){
70 field[l] = randInt(0, f-w);
71 }
72 */
73 return 0;
74}
75
76int main_job() {
77 unsigned int f;
78 unsigned int l;
79
80 /* for online-appendix */
81 f = randInt(65536, f_max);
82 //w = randInt(1,7);
83 //w = w*2 + 1;
84 w = 3;
85 maxhops = randInt(80000, 409600);
86 minStop = f - 10;
87 maxStop = f - 1;
88
89 /* for case-study */
90/* f = randInt(1024,120000); //409600);
91 w = 1;
92 maxhops = 1024; //4096;
93 minStop = f - 1;
94 maxStop = minStop;
95*/
96
97 initial = 1;
98
99 assert((w >= MIN_WINDOW_SIZE) && (w <= MAX_WINDOW_SIZE));
100 assert(w%2 == 1);
101 assert(f > w);
102
103 for (l=0; l<f; l++){
104 field[l] = randInt(0, f-w);
105 }
106
107 hops = 0;
108 idx = initial;
109
110 while ((hops < maxhops) &&
111 (!((idx >= minStop) &&
112 (idx < maxStop)))){
113 int sum;
114
115 unsigned int ll, lll;
116 unsigned int max, min;
117 unsigned int partition;
118 unsigned int high;
119 max = MAX_FIELD_SIZE;
120 min = 0;
121 high = 0;
122 sum = 0;
123
124 for (ll=0; ll<w; ll++){
125 unsigned int balance;
126 unsigned int x;
127 x = field[idx+ll];
128 sum += x;
129
130 if (x > max) high++;
131 else if (x >min){ /* start else* */
132 partition = x;
133 balance = 0;
134 for (lll=ll+1; lll<w; lll++){
135 if (field[idx+lll] > partition) balance++;
136 }
137 if (balance+high == w/2) break;
138 else if (balance+high>w/2){
139 min = partition;
140 }/* end if */
141 else{
142 max = partition;
143 high++;
144 } /* end else */
145 }
146 if (min == max) break;
147 }/* end else* */
148 field[idx] = sum % (f-w);
149 idx = (partition+hops)%(f-w);
150 hops++;
151 }/* end for loop */
152 return 0;
153}
154
155int post_job() {
156 free(field);
157 return(1);
158}
159
160static void usage(char *error) {
161 fprintf(stderr, "Error: %s\n", error);
162 fprintf(stderr,
163 "Usage:\n"
164 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
165 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
166 " rt_spin -l\n"
167 "\n"
168 "COMMON-OPTS = [-w] [-s SCALE]\n"
169 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
170 "\n"
171 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
172 exit(EXIT_FAILURE);
173}
174
175inline unsigned long get_cyclecount (void)
176{
177 unsigned long value;
178 // Read CCNT Register
179 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
180 return value;
181}
182
183static int job(double exec_time, double program_end)
184{
185 if (wctime() > program_end)
186 return 0;
187 else {
188 //register int iter = 0;
189 //register unsigned long t;
190 //t = get_cyclecount();
191 //gettimeofday(&t1, NULL);
192 //while (iter++ < loops) {
193 main_job();
194 //}
195 //t = get_cyclecount() - t;
196 //printf("%ld cycles\n", t);
197 //gettimeofday(&t2, NULL);
198 //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
199 sleep_next_period();
200 return 1;
201 }
202}
203
204#define OPTSTR "p:wves:l:m:i:b:"
205int main(int argc, char** argv)
206{
207 int ret;
208 lt_t wcet;
209 lt_t period;
210 lt_t budget;
211 double wcet_ms, period_ms, budget_ms;
212 unsigned int priority = LITMUS_NO_PRIORITY;
213 int migrate = 0;
214 int cluster = 0;
215 int opt;
216 int wait = 0;
217 int want_enforcement = 0;
218 double duration = 0, start = 0;
219 double scale = 1.0;
220 task_class_t class = RT_CLASS_HARD;
221 struct rt_task param;
222 struct mc2_task mc2_param;
223 struct reservation_config config;
224 int res_type = PERIODIC_POLLING;
225
226 unsigned int job_no;
227
228
229 progname = argv[0];
230
231 /* default for reservation */
232 config.id = 0;
233 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
234 config.cpu = -1;
235
236 mc2_param.crit = CRIT_LEVEL_C;
237
238 budget_ms = 10;
239
240 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
241 switch (opt) {
242 case 'w':
243 wait = 1;
244 break;
245 case 'p':
246 cluster = atoi(optarg);
247 migrate = 1;
248 config.cpu = cluster;
249 break;
250 case 'e':
251 want_enforcement = 1;
252 break;
253 case 's':
254 scale = atof(optarg);
255 break;
256 case 'l':
257 loops = atoi(optarg);
258 break;
259 case 'm':
260 mc2_param.crit = atoi(optarg);
261 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
262 usage("Invalid criticality level.");
263 }
264 res_type = PERIODIC_POLLING;
265 break;
266 case 'b':
267 budget_ms = atof(optarg);
268 break;
269 case 'i':
270 config.priority = atoi(optarg);
271 break;
272 case ':':
273 usage("Argument missing.");
274 break;
275 case '?':
276 default:
277 usage("Bad argument.");
278 break;
279 }
280 }
281
282 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
283 usage("Bad criticailty level or priority");
284
285 if (argc - optind < 3)
286 usage("Arguments missing.");
287
288 wcet_ms = atof(argv[optind + 0]);
289 period_ms = atof(argv[optind + 1]);
290
291 wcet = ms2ns(wcet_ms);
292 period = ms2ns(period_ms);
293 budget = ms2ns(budget_ms);
294
295 if (wcet <= 0)
296 usage("The worst-case execution time must be a "
297 "positive number.");
298 if (period <= 0)
299 usage("The period must be a positive number.");
300 if (wcet > period) {
301 usage("The worst-case execution time must not "
302 "exceed the period.");
303 }
304
305 duration = atof(argv[optind + 2]);
306
307 if (migrate) {
308 ret = be_migrate_to_domain(cluster);
309 if (ret < 0)
310 bail_out("could not migrate to target partition or cluster.");
311 }
312
313 /* reservation config */
314 config.id = gettid();
315
316 config.polling_params.budget = budget;
317 config.polling_params.period = period;
318 config.polling_params.offset = 0;
319 config.polling_params.relative_deadline = 0;
320 if (config.polling_params.budget > config.polling_params.period) {
321 usage("The budget must not exceed the period.");
322 }
323
324 /* create a reservation */
325 ret = reservation_create(res_type, &config);
326 if (ret < 0) {
327 bail_out("failed to create reservation.");
328 }
329 init_job();
330
331 init_rt_task_param(&param);
332 param.exec_cost = wcet;
333 param.period = period;
334 param.priority = priority;
335 param.cls = class;
336 param.release_policy = TASK_PERIODIC;
337 param.budget_policy = (want_enforcement) ?
338 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
339 if (migrate) {
340 param.cpu = gettid();
341 }
342 ret = set_rt_task_param(gettid(), &param);
343
344 if (ret < 0)
345 bail_out("could not setup rt task params");
346
347 mc2_param.res_id = gettid();
348 ret = set_mc2_task_param(gettid(), &mc2_param);
349//printf("SET_MC2_TASK\n");
350 if (ret < 0)
351 bail_out("could not setup mc2 task params");
352
353 init_litmus();
354//printf("CALL\n");
355 if (mc2_param.crit == CRIT_LEVEL_C)
356 set_page_color(-1);
357 else if (mc2_param.crit < CRIT_LEVEL_C)
358 set_page_color(config.cpu);
359//printf("CALL\n");
360
361//printf("INIT_LITMUS\n");
362 start = wctime();
363 ret = task_mode(LITMUS_RT_TASK);
364//printf("TASK_MODE\n");
365 if (ret != 0)
366 bail_out("could not become RT task");
367
368
369 if (wait) {
370//printf("BEFORE WAIT\n");
371 ret = wait_for_ts_release();
372 if (ret != 0)
373 bail_out("wait_for_ts_release()");
374 start = wctime();
375 }
376
377 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
378
379 ret = task_mode(BACKGROUND_TASK);
380 if (ret != 0)
381 bail_out("could not become regular task (huh?)");
382
383 reservation_destroy(gettid(), config.cpu);
384 post_job();
385 printf("%s/%d finished.\n",progname, gettid());
386 return 0;
387}
diff --git a/bin/rt_update_spin.c b/bin/rt_update_spin.c
new file mode 100644
index 0000000..259b03f
--- /dev/null
+++ b/bin/rt_update_spin.c
@@ -0,0 +1,398 @@
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#include "DISstressmarkRNG.h"
16
17#define MIN_FIELD_SIZE 16
18#define MAX_FIELD_SIZE 16777216
19#define MIN_WINDOW_SIZE 1
20#define MAX_WINDOW_SIZE 15
21#define MIN_HOP_LIMIT 1
22#define MAX_HOP_LIMIT 4294967295U
23#define MIN_SEED -2147483647
24#define MAX_SEED -1
25
26
27static char* progname;
28int loops = 1;
29
30//struct timeval t1, t2;
31
32unsigned int *field;
33unsigned int f;
34unsigned int idx;
35unsigned short int w;
36unsigned int maxhops;
37int seed;
38unsigned int initial;
39unsigned int minStop;
40unsigned int maxStop;
41unsigned int hops;
42unsigned int l;
43
44int init_job(){
45 //fscanf(stdin, "%u %u %u %d %u %u %u", &f, &l, &maxhops, &seed, &initial, &minStop, &maxStop);
46 f = 262145;
47 l = 15;
48 maxhops = 102400;
49 seed = -2;
50 initial = 10;
51 minStop = f - 1;
52 maxStop = minStop;
53
54 assert((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE));
55 w = (unsigned int )l;
56 assert((w >= MIN_WINDOW_SIZE) && (w <= MAX_WINDOW_SIZE));
57 assert(w%2 == 1);
58 assert(f > w);
59 assert((maxhops >= MIN_HOP_LIMIT) && (maxhops <= MAX_HOP_LIMIT));
60 assert((seed >= MIN_SEED) && (seed <= MAX_SEED));
61 assert((initial >= 0) && (initial < f));
62 assert((minStop >= 0) && (minStop < f));
63 assert((maxStop >= 0) && (maxStop < f));
64
65 if ((field = (unsigned int *)malloc(f*sizeof(int))) == NULL)
66 return (-1);
67
68 srand (time(NULL));
69 randInit(-rand()%65535);
70/* randInit(seed);
71 for (l=0; l<f; l++){
72 field[l] = randInt(0, f-w);
73 }
74*/
75 return 0;
76}
77
78int main_job() {
79 f = randInt(1024, 262145);
80 l = randInt(1,7);
81 l = l*2 + 1;
82 maxhops = randInt(1024, 4096);
83 minStop = f - 1;
84 maxStop = minStop;
85
86 for (l=0; l<f; l++){
87 field[l] = randInt(0, f-w);
88 }
89
90 hops = 0;
91 idx = initial;
92
93 while ((hops < maxhops) &&
94 (!((idx >= minStop) &&
95 (idx < maxStop)))){
96 int sum;
97
98 unsigned int ll, lll;
99 unsigned int max, min;
100 unsigned int partition;
101 unsigned int high;
102 max = MAX_FIELD_SIZE;
103 min = 0;
104 high = 0;
105 sum = 0;
106
107 for (ll=0; ll<w; ll++){
108 unsigned int balance;
109 unsigned int x;
110 x = field[idx+ll];
111 sum += x;
112
113 if (x > max) high++;
114 else if (x >min){ /* start else* */
115 partition = x;
116 balance = 0;
117 for (lll=ll+1; lll<w; lll++){
118 if (field[idx+lll] > partition) balance++;
119 }
120 if (balance+high == w/2) break;
121 else if (balance+high>w/2){
122 min = partition;
123 }/* end if */
124 else{
125 max = partition;
126 high++;
127 } /* end else */
128 }
129 if (min == max) break;
130 }/* end else* */
131 field[idx] = sum % (f-w);
132 idx = (partition+hops)%(f-w);
133 hops++;
134 }/* end for loop */
135 return 0;
136}
137
138int post_job() {
139 free(field);
140 return(1);
141}
142
143static void usage(char *error) {
144 fprintf(stderr, "Error: %s\n", error);
145 fprintf(stderr,
146 "Usage:\n"
147 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
148 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
149 " rt_spin -l\n"
150 "\n"
151 "COMMON-OPTS = [-w] [-s SCALE]\n"
152 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
153 "\n"
154 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
155 exit(EXIT_FAILURE);
156}
157
158inline unsigned long get_cyclecount (void)
159{
160 unsigned long value;
161 // Read CCNT Register
162 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
163 return value;
164}
165
166static int loop_main(double exec_time, double emergency_exit)
167{
168 double last_loop = 0, loop_start;
169 int tmp = 0;
170
171 double start = cputime();
172 double now = cputime();
173
174 while (now + last_loop < start + exec_time) {
175 loop_start = now;
176 tmp += main_job();
177 now = cputime();
178 last_loop = now - loop_start;
179 if (emergency_exit && wctime() > emergency_exit) {
180 /* Oops --- this should only be possible if the execution time tracking
181 * is broken in the LITMUS^RT kernel. */
182 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid());
183 fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n");
184 break;
185 }
186 }
187
188 return tmp;
189}
190
191static int job(double exec_time, double program_end)
192{
193 if (wctime() > program_end)
194 return 0;
195 else {
196 register int iter = 0;
197 //register unsigned long t;
198 //t = get_cyclecount();
199 //gettimeofday(&t1, NULL);
200 //while (iter++ < loops) {
201 loop_main(exec_time, program_end + 1);
202 //}
203 //t = get_cyclecount() - t;
204 //printf("%ld cycles\n", t);
205 //gettimeofday(&t2, NULL);
206 //printf("%ld us\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
207 sleep_next_period();
208 return 1;
209 }
210}
211
212#define OPTSTR "p:wves:l:m:i:b:"
213int main(int argc, char** argv)
214{
215 int ret;
216 lt_t wcet;
217 lt_t period;
218 lt_t budget;
219 double wcet_ms, period_ms, budget_ms;
220 unsigned int priority = LITMUS_NO_PRIORITY;
221 int migrate = 0;
222 int cluster = 0;
223 int opt;
224 int wait = 0;
225 int want_enforcement = 0;
226 double duration = 0, start = 0;
227 double scale = 1.0;
228 task_class_t class = RT_CLASS_HARD;
229 struct rt_task param;
230 struct mc2_task mc2_param;
231 struct reservation_config config;
232 int res_type = PERIODIC_POLLING;
233
234 unsigned int job_no;
235
236
237 progname = argv[0];
238
239 /* default for reservation */
240 config.id = 0;
241 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
242 config.cpu = -1;
243
244 mc2_param.crit = CRIT_LEVEL_C;
245
246 budget_ms = 0;
247
248 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
249 switch (opt) {
250 case 'w':
251 wait = 1;
252 break;
253 case 'p':
254 cluster = atoi(optarg);
255 migrate = 1;
256 config.cpu = cluster;
257 break;
258 case 'e':
259 want_enforcement = 1;
260 break;
261 case 's':
262 scale = atof(optarg);
263 break;
264 case 'l':
265 loops = atoi(optarg);
266 break;
267 case 'm':
268 mc2_param.crit = atoi(optarg);
269 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
270 usage("Invalid criticality level.");
271 }
272 res_type = PERIODIC_POLLING;
273 break;
274 case 'b':
275 budget_ms = atof(optarg);
276 break;
277 case 'i':
278 config.priority = atoi(optarg);
279 break;
280 case ':':
281 usage("Argument missing.");
282 break;
283 case '?':
284 default:
285 usage("Bad argument.");
286 break;
287 }
288 }
289
290 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
291 usage("Bad criticailty level or priority");
292
293 if (argc - optind < 3)
294 usage("Arguments missing.");
295
296 wcet_ms = atof(argv[optind + 0]);
297 period_ms = atof(argv[optind + 1]);
298
299 wcet = ms2ns(wcet_ms);
300 period = ms2ns(period_ms);
301 if (budget_ms == 0)
302 budget_ms = wcet_ms;
303 budget = ms2ns(budget_ms);
304
305 if (wcet <= 0)
306 usage("The worst-case execution time must be a "
307 "positive number.");
308 if (period <= 0)
309 usage("The period must be a positive number.");
310 if (wcet > period) {
311 usage("The worst-case execution time must not "
312 "exceed the period.");
313 }
314
315 duration = atof(argv[optind + 2]);
316
317 if (migrate) {
318 ret = be_migrate_to_domain(cluster);
319 if (ret < 0)
320 bail_out("could not migrate to target partition or cluster.");
321 }
322
323 /* reservation config */
324 config.id = gettid();
325
326 config.polling_params.budget = budget;
327 config.polling_params.period = period;
328 config.polling_params.offset = 0;
329 config.polling_params.relative_deadline = 0;
330 if (config.polling_params.budget > config.polling_params.period) {
331 usage("The budget must not exceed the period.");
332 }
333
334 /* create a reservation */
335 ret = reservation_create(res_type, &config);
336 if (ret < 0) {
337 bail_out("failed to create reservation.");
338 }
339 init_job();
340
341 init_rt_task_param(&param);
342 param.exec_cost = wcet;
343 param.period = period;
344 param.priority = priority;
345 param.cls = class;
346 param.release_policy = TASK_PERIODIC;
347 param.budget_policy = (want_enforcement) ?
348 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
349 if (migrate) {
350 param.cpu = gettid();
351 }
352 ret = set_rt_task_param(gettid(), &param);
353
354 if (ret < 0)
355 bail_out("could not setup rt task params");
356
357 mc2_param.res_id = gettid();
358 ret = set_mc2_task_param(gettid(), &mc2_param);
359//printf("SET_MC2_TASK\n");
360 if (ret < 0)
361 bail_out("could not setup mc2 task params");
362
363 init_litmus();
364//printf("CALL\n");
365 if (mc2_param.crit == CRIT_LEVEL_C)
366 set_page_color(-1);
367 else if (mc2_param.crit < CRIT_LEVEL_C)
368 set_page_color(config.cpu);
369//printf("CALL\n");
370
371//printf("INIT_LITMUS\n");
372 start = wctime();
373 ret = task_mode(LITMUS_RT_TASK);
374//printf("TASK_MODE\n");
375 if (ret != 0)
376 bail_out("could not become RT task");
377
378
379 if (wait) {
380//printf("BEFORE WAIT\n");
381 ret = wait_for_ts_release();
382 if (ret != 0)
383 bail_out("wait_for_ts_release()");
384 start = wctime();
385 }
386
387 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
388
389 ret = task_mode(BACKGROUND_TASK);
390 if (ret != 0)
391 bail_out("could not become regular task (huh?)");
392
393 reservation_destroy(gettid(), config.cpu);
394 post_job();
395 //printf("%s/%d finished.\n",progname, gettid());
396 return 0;
397}
398