diff options
author | Namhoon Kim <namhoonk@cs.unc.edu> | 2017-05-01 16:02:05 -0400 |
---|---|---|
committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2017-05-01 16:02:05 -0400 |
commit | 11765fcf37057053065abd3715cf9cb46f2fa4db (patch) | |
tree | 8403d716bbcbd96493c481a82e7e02b5da9231e8 /bin/test1.c | |
parent | bfee87a910560e022b04c81a026b1f88522cd62f (diff) |
RTSS17 submitwip-modechange
Diffstat (limited to 'bin/test1.c')
-rw-r--r-- | bin/test1.c | 453 |
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 | |||
20 | static 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 | */ | ||
40 | static 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 | |||
47 | static 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 | |||
55 | static 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 | ||
106 | static int num[NUMS]; | ||
107 | static char* progname; | ||
108 | static char* smem; | ||
109 | static int access_type; /* 0: read 1: write */ | ||
110 | |||
111 | static 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 | |||
127 | static 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 | |||
153 | static 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 | |||
171 | static 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:" | ||
203 | int 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(¶m); | ||
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(), ¶m); | ||
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 | } | ||