aboutsummaryrefslogtreecommitdiffstats
path: root/bin/test1.c
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2017-05-01 16:02:05 -0400
committerNamhoon Kim <namhoonk@cs.unc.edu>2017-05-01 16:02:05 -0400
commit11765fcf37057053065abd3715cf9cb46f2fa4db (patch)
tree8403d716bbcbd96493c481a82e7e02b5da9231e8 /bin/test1.c
parentbfee87a910560e022b04c81a026b1f88522cd62f (diff)
RTSS17 submitwip-modechange
Diffstat (limited to 'bin/test1.c')
-rw-r--r--bin/test1.c453
1 files changed, 0 insertions, 453 deletions
diff --git a/bin/test1.c b/bin/test1.c
deleted file mode 100644
index a38d402..0000000
--- a/bin/test1.c
+++ /dev/null
@@ -1,453 +0,0 @@
1#include <sys/time.h>
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <time.h>
7#include <string.h>
8#include <assert.h>
9#include <limits.h>
10#include <sys/mman.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13#include <fcntl.h>
14
15#include "litmus.h"
16#include "common.h"
17
18
19
20static void usage(char *error) {
21 fprintf(stderr, "Error: %s\n", error);
22 fprintf(stderr,
23 "Usage:\n"
24 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
25 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
26 " rt_spin -l\n"
27 "\n"
28 "COMMON-OPTS = [-w] [-s SCALE]\n"
29 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS]\n"
30 " [-X LOCKING-PROTOCOL] [-L CRITICAL SECTION LENGTH] [-Q RESOURCE-ID]"
31 "\n"
32 "WCET and PERIOD are milliseconds, DURATION is seconds.\n"
33 "CRITICAL SECTION LENGTH is in milliseconds.\n");
34 exit(EXIT_FAILURE);
35}
36
37/*
38 * returns the character that made processing stop, newline or EOF
39 */
40static int skip_to_next_line(FILE *fstream)
41{
42 int ch;
43 for (ch = fgetc(fstream); ch != EOF && ch != '\n'; ch = fgetc(fstream));
44 return ch;
45}
46
47static void skip_comments(FILE *fstream)
48{
49 int ch;
50 for (ch = fgetc(fstream); ch == '#'; ch = fgetc(fstream))
51 skip_to_next_line(fstream);
52 ungetc(ch, fstream);
53}
54
55static void get_exec_times(const char *file, const int column,
56 int *num_jobs, double **exec_times)
57{
58 FILE *fstream;
59 int cur_job, cur_col, ch;
60 *num_jobs = 0;
61
62 fstream = fopen(file, "r");
63 if (!fstream)
64 bail_out("could not open execution time file");
65
66 /* figure out the number of jobs */
67 do {
68 skip_comments(fstream);
69 ch = skip_to_next_line(fstream);
70 if (ch != EOF)
71 ++(*num_jobs);
72 } while (ch != EOF);
73
74 if (-1 == fseek(fstream, 0L, SEEK_SET))
75 bail_out("rewinding file failed");
76
77 /* allocate space for exec times */
78 *exec_times = calloc(*num_jobs, sizeof(*exec_times));
79 if (!*exec_times)
80 bail_out("couldn't allocate memory");
81
82 for (cur_job = 0; cur_job < *num_jobs && !feof(fstream); ++cur_job) {
83
84 skip_comments(fstream);
85
86 for (cur_col = 1; cur_col < column; ++cur_col) {
87 /* discard input until we get to the column we want */
88 int unused __attribute__ ((unused)) = fscanf(fstream, "%*s,");
89 }
90
91 /* get the desired exec. time */
92 if (1 != fscanf(fstream, "%lf", (*exec_times)+cur_job)) {
93 fprintf(stderr, "invalid execution time near line %d\n",
94 cur_job);
95 exit(EXIT_FAILURE);
96 }
97
98 skip_to_next_line(fstream);
99 }
100
101 assert(cur_job == *num_jobs);
102 fclose(fstream);
103}
104
105#define NUMS 4096
106static int num[NUMS];
107static char* progname;
108static char* smem;
109static int access_type; /* 0: read 1: write */
110
111static int loop_once(void)
112{
113 int i, j = 0;
114 for (i = 0; i < NUMS; i++) {
115 j += num[i]++;
116 if (access_type == 1) {
117 smem[i] = j%255;
118 printf("Write %d at [%d]\n", smem[i], i);
119 } else {
120 char tmp = smem[i];
121 printf("Read %d at [%d]\n", tmp, i);
122 }
123 }
124 return j;
125}
126
127static int loop_for(double exec_time, double emergency_exit)
128{
129 double last_loop = 0, loop_start;
130 int tmp = 0;
131
132 double start = cputime();
133 double now = cputime();
134
135 while (now + last_loop < start + exec_time) {
136 loop_start = now;
137 tmp += loop_once();
138 now = cputime();
139 last_loop = now - loop_start;
140 if (emergency_exit && wctime() > emergency_exit) {
141 /* Oops --- this should only be possible if the execution time tracking
142 * is broken in the LITMUS^RT kernel. */
143 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid());
144 fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n");
145 break;
146 }
147 }
148
149 return tmp;
150}
151
152
153static void debug_delay_loop(void)
154{
155 double start, end, delay;
156
157 while (1) {
158 for (delay = 0.5; delay > 0.01; delay -= 0.01) {
159 start = wctime();
160 loop_for(delay, 0);
161 end = wctime();
162 printf("%6.4fs: looped for %10.8fs, delta=%11.8fs, error=%7.4f%%\n",
163 delay,
164 end - start,
165 end - start - delay,
166 100 * (end - start - delay) / delay);
167 }
168 }
169}
170
171static int job(double exec_time, double program_end, int lock_od, double cs_length)
172{
173 double chunk1, chunk2;
174
175 if (wctime() > program_end)
176 return 0;
177 else {
178 if (lock_od >= 0) {
179 /* simulate critical section somewhere in the middle */
180 chunk1 = drand48() * (exec_time - cs_length);
181 chunk2 = exec_time - cs_length - chunk1;
182
183 /* non-critical section */
184 loop_for(chunk1, program_end + 1);
185
186 /* critical section */
187 litmus_lock(lock_od);
188 loop_for(cs_length, program_end + 1);
189 litmus_unlock(lock_od);
190
191 /* non-critical section */
192 loop_for(chunk2, program_end + 2);
193 } else {
194 //loop_for(exec_time, program_end + 1);
195 loop_once();
196 }
197 sleep_next_period();
198 return 1;
199 }
200}
201
202#define OPTSTR "p:c:wlveo:f:s:q:r:X:L:Q:vt:"
203int main(int argc, char** argv)
204{
205 int ret;
206 lt_t wcet;
207 lt_t period;
208 double wcet_ms, period_ms;
209 unsigned int priority = LITMUS_NO_PRIORITY;
210 int migrate = 0;
211 int cluster = 0;
212 int reservation = -1;
213 int opt;
214 int wait = 0;
215 int test_loop = 0;
216 int column = 1;
217 const char *file = NULL;
218 int want_enforcement = 0;
219 double duration = 0, start = 0;
220 double *exec_times = NULL;
221 double scale = 1.0;
222 task_class_t class = RT_CLASS_HARD;
223 int cur_job = 0, num_jobs = 0;
224 struct rt_task param;
225
226 int verbose = 0;
227 unsigned int job_no;
228
229 /* locking */
230 int lock_od = -1;
231 int resource_id = 0;
232 const char *lock_namespace = "./rtspin-locks";
233 int protocol = -1;
234 double cs_length = 1; /* millisecond */
235 int fd;
236
237 progname = argv[0];
238
239 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
240 switch (opt) {
241 case 'w':
242 wait = 1;
243 break;
244 case 'p':
245 cluster = atoi(optarg);
246 migrate = 1;
247 break;
248 case 'r':
249 reservation = atoi(optarg);
250 break;
251 case 'q':
252 priority = atoi(optarg);
253 if (!litmus_is_valid_fixed_prio(priority))
254 usage("Invalid priority.");
255 break;
256 case 'c':
257 class = str2class(optarg);
258 if (class == -1)
259 usage("Unknown task class.");
260 break;
261 case 'e':
262 want_enforcement = 1;
263 break;
264 case 'l':
265 test_loop = 1;
266 break;
267 case 'o':
268 column = atoi(optarg);
269 break;
270 case 'f':
271 file = optarg;
272 break;
273 case 's':
274 scale = atof(optarg);
275 break;
276 case 'X':
277 protocol = lock_protocol_for_name(optarg);
278 if (protocol < 0)
279 usage("Unknown locking protocol specified.");
280 break;
281 case 'L':
282 cs_length = atof(optarg);
283 if (cs_length <= 0)
284 usage("Invalid critical section length.");
285 break;
286 case 'Q':
287 resource_id = atoi(optarg);
288 if (resource_id <= 0 && strcmp(optarg, "0"))
289 usage("Invalid resource ID.");
290 break;
291 case 'v':
292 verbose = 1;
293 break;
294 case 't':
295 access_type = atoi(optarg);
296 if (access_type != 0 && access_type != 1)
297 usage("Wrong SHM access type.");
298 break;
299 case ':':
300 usage("Argument missing.");
301 break;
302 case '?':
303 default:
304 usage("Bad argument.");
305 break;
306 }
307 }
308
309 if (test_loop) {
310 debug_delay_loop();
311 return 0;
312 }
313
314 srand(getpid());
315
316 if (file) {
317 get_exec_times(file, column, &num_jobs, &exec_times);
318
319 if (argc - optind < 2)
320 usage("Arguments missing.");
321
322 for (cur_job = 0; cur_job < num_jobs; ++cur_job) {
323 /* convert the execution time to seconds */
324 duration += exec_times[cur_job] * 0.001;
325 }
326 } else {
327 /*
328 * if we're not reading from the CSV file, then we need
329 * three parameters
330 */
331 if (argc - optind < 3)
332 usage("Arguments missing.");
333 }
334
335 wcet_ms = atof(argv[optind + 0]);
336 period_ms = atof(argv[optind + 1]);
337
338 wcet = ms2ns(wcet_ms);
339 period = ms2ns(period_ms);
340 if (wcet <= 0)
341 usage("The worst-case execution time must be a "
342 "positive number.");
343 if (period <= 0)
344 usage("The period must be a positive number.");
345 if (!file && wcet > period) {
346 usage("The worst-case execution time must not "
347 "exceed the period.");
348 }
349
350 if (!file)
351 duration = atof(argv[optind + 2]);
352 else if (file && num_jobs > 1)
353 duration += period_ms * 0.001 * (num_jobs - 1);
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
362 /* allocate shared memory */
363 fd = open("/dev/shm/region1", O_CREAT|O_RDWR|O_TRUNC, 0666);
364 if (fd == -1)
365 bail_out("could not open /dev/shm.");
366
367 fallocate(fd, 0, 0, 4096);
368 smem = NULL;
369 if (access_type == 1) {
370 printf("open write mmap now.\n");
371 smem = (char*) mmap(NULL, 4096, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
372 if (smem == MAP_FAILED)
373 bail_out("mmap error.");
374 close(fd);
375 }
376 else {
377 printf("open read mmap now.\n");
378 smem = (char*) mmap(NULL, 4096, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
379 if (smem == MAP_FAILED)
380 bail_out("mmap error.");
381 close(fd);
382 }
383 printf("smem addr = %p\n", smem);
384 init_rt_task_param(&param);
385 param.exec_cost = wcet;
386 param.period = period;
387 param.priority = priority;
388 param.cls = class;
389 param.budget_policy = (want_enforcement) ?
390 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
391 if (migrate) {
392 if (reservation >= 0)
393 param.cpu = reservation;
394 else
395 param.cpu = domain_to_first_cpu(cluster);
396 }
397 ret = set_rt_task_param(gettid(), &param);
398 if (ret < 0)
399 bail_out("could not setup rt task params");
400
401 init_litmus();
402//test_call(0);
403 start = wctime();
404 ret = task_mode(LITMUS_RT_TASK);
405 if (ret != 0)
406 bail_out("could not become RT task");
407
408 if (protocol >= 0) {
409 /* open reference to semaphore */
410 lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cluster);
411 if (lock_od < 0) {
412 perror("litmus_open_lock");
413 usage("Could not open lock.");
414 }
415 }
416
417
418 if (wait) {
419 ret = wait_for_ts_release();
420 if (ret != 0)
421 bail_out("wait_for_ts_release()");
422 start = wctime();
423 }
424
425 if (file) {
426 /* use times read from the CSV file */
427 for (cur_job = 0; cur_job < num_jobs; ++cur_job) {
428 /* convert job's length to seconds */
429 job(exec_times[cur_job] * 0.001 * scale,
430 start + duration,
431 lock_od, cs_length * 0.001);
432 }
433 } else {
434 do {
435 if (verbose) {
436 get_job_no(&job_no);
437 printf("rtspin/%d:%u @ %.4fms\n", gettid(),
438 job_no, (wctime() - start) * 1000);
439 }
440 /* convert to seconds and scale */
441 } while (job(wcet_ms * 0.001 * scale, start + duration,
442 lock_od, cs_length * 0.001));
443 }
444
445 ret = task_mode(BACKGROUND_TASK);
446 if (ret != 0)
447 bail_out("could not become regular task (huh?)");
448
449 if (file)
450 free(exec_times);
451
452 return 0;
453}