aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2017-07-28 11:32:04 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2017-07-28 11:32:04 -0400
commit92494a3297a21b98ce4f4d5a9ca0880e35852949 (patch)
tree208d022b849455fe31f50ba473e7fc84d7d1a13b
parent914897a4bc19ddf24ec85e5f4306431b1f07cbf2 (diff)
rtspin: streamline "read exec. times from CSV" option (was -F -C, now only -C)
Specify a single argument of the form -C FILE[:COLUMN] instead of -F FILE -C COLUMN.
-rw-r--r--bin/common.c11
-rw-r--r--bin/rtspin.c40
-rw-r--r--include/common.h1
3 files changed, 34 insertions, 18 deletions
diff --git a/bin/common.c b/bin/common.c
index b614077..3749b87 100644
--- a/bin/common.c
+++ b/bin/common.c
@@ -1,6 +1,7 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <stdlib.h> 2#include <stdlib.h>
3#include <limits.h> 3#include <limits.h>
4#include <string.h>
4#include <errno.h> 5#include <errno.h>
5 6
6#include "common.h" 7#include "common.h"
@@ -35,3 +36,13 @@ double str2double(const char* arg, int *failure_flag)
35 *failure_flag = *arg == '\0' || *end != '\0'; 36 *failure_flag = *arg == '\0' || *end != '\0';
36 return val; 37 return val;
37} 38}
39
40char* strsplit(char split_char, char *str)
41{
42 char *found = strrchr(str, split_char);
43 if (found) {
44 /* terminate first string and move to next char */
45 *found++ = '\0';
46 }
47 return found;
48}
diff --git a/bin/rtspin.c b/bin/rtspin.c
index d7cb7b0..13d6626 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -18,7 +18,7 @@
18const char *usage_msg = 18const char *usage_msg =
19 "Usage: (1) rtspin OPTIONS WCET PERIOD DURATION\n" 19 "Usage: (1) rtspin OPTIONS WCET PERIOD DURATION\n"
20 " (2) rtspin -S [INPUT] WCET PERIOD DURATION\n" 20 " (2) rtspin -S [INPUT] WCET PERIOD DURATION\n"
21 " (3) rtspin OPTIONS -F FILE [-C COLUMN] WCET PERIOD [DURATION]\n" 21 " (3) rtspin OPTIONS -C FILE:COLUMN WCET PERIOD [DURATION]\n"
22 " (4) rtspin -l\n" 22 " (4) rtspin -l\n"
23 " (5) rtspin -B -m FOOTPRINT\n" 23 " (5) rtspin -B -m FOOTPRINT\n"
24 "\n" 24 "\n"
@@ -27,7 +27,7 @@ const char *usage_msg =
27 " using INPUT as a file from which events are received\n" 27 " using INPUT as a file from which events are received\n"
28 " by means of blocking reads (default: read from STDIN)\n" 28 " by means of blocking reads (default: read from STDIN)\n"
29 " (3) as (1) or (2), but load per-job execution times from\n" 29 " (3) as (1) or (2), but load per-job execution times from\n"
30 " a CSV file\n" 30 " the given column of a CSV file\n"
31 " (4) Run calibration loop (how accurately are target\n" 31 " (4) Run calibration loop (how accurately are target\n"
32 " runtimes met?)\n" 32 " runtimes met?)\n"
33 " (5) Run background, non-real-time cache-thrashing loop.\n" 33 " (5) Run background, non-real-time cache-thrashing loop.\n"
@@ -56,8 +56,9 @@ const char *usage_msg =
56 " -v verbose (print per-job statistics)\n" 56 " -v verbose (print per-job statistics)\n"
57 " -w wait for synchronous release\n" 57 " -w wait for synchronous release\n"
58 "\n" 58 "\n"
59 " -F FILE load per-job execution times from CSV file\n" 59 " -C FILE[:COLUMN] load per-job execution times from CSV file;\n"
60 " -C COLUMN specify column to read per-job execution times from (default: 1)\n" 60 " if COLUMN is given, it specifies the column to read\n"
61 " per-job execution times from (default: 1)\n"
61 "\n" 62 "\n"
62 " -S[FILE] read from FILE to trigger sporadic job releases\n" 63 " -S[FILE] read from FILE to trigger sporadic job releases\n"
63 " default w/o -S: periodic job releases\n" 64 " default w/o -S: periodic job releases\n"
@@ -326,7 +327,7 @@ static void job(double exec_time, double program_end, int lock_od, double cs_len
326 } 327 }
327} 328}
328 329
329#define OPTSTR "p:c:wlveo:F:s:m:q:r:X:L:Q:iRu:U:Bhd:C:S::O::TD:E:" 330#define OPTSTR "p:c:wlveo:s:m:q:r:X:L:Q:iRu:U:Bhd:C:S::O::TD:E:"
330 331
331int main(int argc, char** argv) 332int main(int argc, char** argv)
332{ 333{
@@ -349,7 +350,7 @@ int main(int argc, char** argv)
349 int test_loop = 0; 350 int test_loop = 0;
350 int background_loop = 0; 351 int background_loop = 0;
351 int column = 1; 352 int column = 1;
352 const char *file = NULL; 353 const char *cost_csv_file = NULL;
353 int want_enforcement = 0; 354 int want_enforcement = 0;
354 double duration = 0, start = 0; 355 double duration = 0, start = 0;
355 double *exec_times = NULL; 356 double *exec_times = NULL;
@@ -358,6 +359,8 @@ int main(int argc, char** argv)
358 int cur_job = 0, num_jobs = 0; 359 int cur_job = 0, num_jobs = 0;
359 struct rt_task param; 360 struct rt_task param;
360 361
362 char *after_colon;
363
361 int rss = 0; 364 int rss = 0;
362 int idx; 365 int idx;
363 366
@@ -420,10 +423,11 @@ int main(int argc, char** argv)
420 background_loop = 1; 423 background_loop = 1;
421 break; 424 break;
422 case 'C': 425 case 'C':
423 column = want_non_negative_int(optarg, "-C"); 426 after_colon = strsplit(':', optarg);
424 break; 427 cost_csv_file = optarg;
425 case 'F': 428 if (after_colon) {
426 file = optarg; 429 column = want_non_negative_int(after_colon, "-C");
430 }
427 break; 431 break;
428 case 'S': 432 case 'S':
429 sporadic = 1; 433 sporadic = 1;
@@ -555,7 +559,7 @@ int main(int argc, char** argv)
555 return 0; 559 return 0;
556 } 560 }
557 561
558 if (argc - optind < 3 || (argc - optind < 2 && !file)) 562 if (argc - optind < 3 || (argc - optind < 2 && !cost_csv_file))
559 usage("Arguments missing."); 563 usage("Arguments missing.");
560 564
561 wcet_ms = want_positive_double(argv[optind + 0], "WCET"); 565 wcet_ms = want_positive_double(argv[optind + 0], "WCET");
@@ -574,15 +578,15 @@ int main(int argc, char** argv)
574 578
575 if (period <= 0) 579 if (period <= 0)
576 usage("The period must be a positive number."); 580 usage("The period must be a positive number.");
577 if (!file && wcet > period) { 581 if (!cost_csv_file && wcet > period) {
578 usage("The worst-case execution time must not " 582 usage("The worst-case execution time must not "
579 "exceed the period."); 583 "exceed the period.");
580 } 584 }
581 585
582 if (file) 586 if (cost_csv_file)
583 get_exec_times(file, column, &num_jobs, &exec_times); 587 get_exec_times(cost_csv_file, column, &num_jobs, &exec_times);
584 588
585 if (argc - optind < 3 && file) 589 if (argc - optind < 3 && cost_csv_file)
586 /* If duration is not given explicitly, 590 /* If duration is not given explicitly,
587 * take duration from file. */ 591 * take duration from file. */
588 duration = num_jobs * period_ms * 0.001; 592 duration = num_jobs * period_ms * 0.001;
@@ -731,9 +735,8 @@ int main(int argc, char** argv)
731 } 735 }
732 736
733 /* figure out for how long this job should use the CPU */ 737 /* figure out for how long this job should use the CPU */
734 cur_job++;
735 738
736 if (file) { 739 if (cost_csv_file) {
737 /* read from provided CSV file and convert to seconds */ 740 /* read from provided CSV file and convert to seconds */
738 acet = exec_times[cur_job % num_jobs] * 0.001; 741 acet = exec_times[cur_job % num_jobs] * 0.001;
739 } else { 742 } else {
@@ -793,13 +796,14 @@ int main(int argc, char** argv)
793 sleep_next_period(); 796 sleep_next_period();
794 } 797 }
795 } 798 }
799 cur_job++;
796 } 800 }
797 801
798 ret = task_mode(BACKGROUND_TASK); 802 ret = task_mode(BACKGROUND_TASK);
799 if (ret != 0) 803 if (ret != 0)
800 bail_out("could not become regular task (huh?)"); 804 bail_out("could not become regular task (huh?)");
801 805
802 if (file) 806 if (cost_csv_file)
803 free(exec_times); 807 free(exec_times);
804 808
805 if (base != MAP_FAILED) 809 if (base != MAP_FAILED)
diff --git a/include/common.h b/include/common.h
index 216f01c..e936878 100644
--- a/include/common.h
+++ b/include/common.h
@@ -62,5 +62,6 @@ double str2double(const char* arg, int *failure_flag);
62 usage("option " name " requires a positive argument"); \ 62 usage("option " name " requires a positive argument"); \
63 __val; }) 63 __val; })
64 64
65char* strsplit(char split_char, char *str);
65 66
66#endif 67#endif