aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--include/adaptive.h24
-rw-r--r--src/adaptive.c16
-rw-r--r--src/rt_launch.c82
4 files changed, 97 insertions, 27 deletions
diff --git a/Makefile b/Makefile
index 24c7d2a..8dd3698 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
1CFLAGS=-Wall -g -Iinclude/ 1CFLAGS=-Wall -g -Iinclude/ -D_XOPEN_SOURCE=600
2CPPFLAGS=-Wall -g 2CPPFLAGS=-Wall -g
3 3
4LIBS= ./liblitmus.a 4LIBS= ./liblitmus.a
diff --git a/include/adaptive.h b/include/adaptive.h
index a67c540..21e1dfd 100644
--- a/include/adaptive.h
+++ b/include/adaptive.h
@@ -1,23 +1,35 @@
1#ifndef ADAPTIVE_H 1#ifndef ADAPTIVE_H
2#define ADAPTIVE_H 2#define ADAPTIVE_H
3 3
4#define MAX_SERVICE_LEVELS 10 4#define FP_SHIFT 16
5typedef struct
6{
7 long long val;
8} fp_t;
9
10static inline fp_t f2fp(double f)
11{
12 return (fp_t) {f * (1 << FP_SHIFT)};
13}
5 14
15#define MAX_SERVICE_LEVELS 10
6typedef struct { 16typedef struct {
7 unsigned long exec_cost; 17 fp_t weight;
8 unsigned long period; 18 unsigned long period;
9 /* fixed point */ 19 fp_t value;
10 unsigned long utility;
11} service_level_t; 20} service_level_t;
12 21
13int set_service_levels(pid_t pid, 22int set_service_levels(pid_t pid,
14 unsigned int nr_levels, 23 unsigned int nr_levels,
15 service_level_t* levels); 24 service_level_t* levels,
25 fp_t *wt_y,
26 fp_t *wt_slope);
16 27
17int get_cur_service_level(void); 28int get_cur_service_level(void);
18 29
19int create_adaptive_rt_task(rt_fn_t rt_prog, void *arg, 30int create_adaptive_rt_task(rt_fn_t rt_prog, void *arg,
20 unsigned int no_levels, service_level_t* levels); 31 unsigned int no_levels, service_level_t* levels,
32 fp_t wt_y, fp_t wt_slope);
21 33
22 34
23#endif 35#endif
diff --git a/src/adaptive.c b/src/adaptive.c
index ebf662d..8dfb27b 100644
--- a/src/adaptive.c
+++ b/src/adaptive.c
@@ -11,9 +11,11 @@
11 11
12int set_service_levels(pid_t pid, 12int set_service_levels(pid_t pid,
13 unsigned int nr_levels, 13 unsigned int nr_levels,
14 service_level_t* levels) 14 service_level_t* levels,
15 fp_t *wt_y,
16 fp_t *wt_slope)
15{ 17{
16 return syscall(__NR_set_service_levels, pid, nr_levels, levels); 18 return syscall(__NR_set_service_levels, pid, nr_levels, levels, wt_y, wt_slope);
17} 19}
18 20
19 21
@@ -26,19 +28,25 @@ int get_cur_service_level(void)
26struct adaptive_param { 28struct adaptive_param {
27 unsigned int no_levels; 29 unsigned int no_levels;
28 service_level_t* levels; 30 service_level_t* levels;
31 fp_t wt_y;
32 fp_t wt_slope;
29}; 33};
30 34
31int setup_adaptive(int pid, struct adaptive_param* arg) 35int setup_adaptive(int pid, struct adaptive_param* arg)
32{ 36{
33 return set_service_levels(pid, arg->no_levels, arg->levels); 37 return set_service_levels(pid, arg->no_levels, arg->levels,
38 &arg->wt_y, &arg->wt_slope);
34} 39}
35 40
36int create_adaptive_rt_task(rt_fn_t rt_prog, void *arg, 41int create_adaptive_rt_task(rt_fn_t rt_prog, void *arg,
37 unsigned int no_levels, service_level_t* levels) 42 unsigned int no_levels, service_level_t* levels,
43 fp_t wt_y, fp_t wt_slope)
38{ 44{
39 struct adaptive_param p; 45 struct adaptive_param p;
40 p.no_levels = no_levels; 46 p.no_levels = no_levels;
41 p.levels = levels; 47 p.levels = levels;
48 p.wt_y = wt_y;
49 p.wt_slope = wt_slope;
42 return __launch_rt_task(rt_prog, arg, 50 return __launch_rt_task(rt_prog, arg,
43 (rt_setup_fn_t) setup_adaptive, &p); 51 (rt_setup_fn_t) setup_adaptive, &p);
44} 52}
diff --git a/src/rt_launch.c b/src/rt_launch.c
index cd98ad3..b76cb8c 100644
--- a/src/rt_launch.c
+++ b/src/rt_launch.c
@@ -22,39 +22,78 @@ int launch(void *task_info_p) {
22} 22}
23 23
24void usage(char *error) { 24void usage(char *error) {
25 fprintf(stderr, "%s\nUsage: launch_rt [-c {hrt|srt|be}] [-p <cpu>]" 25 fprintf(stderr, "%s\nUsage: \nlaunch_rt supports one of two modes:\n"
26 "{<wcet> <period>|{-a wcet/period/utility}+}" 26 "\n\tlaunch_rt <SPORADIC OPTIONS> program arg1 arg2 ...\n"
27 " program arg1 arg2 ...\n", 27 "\n\tlaunch_rt <ADAPTIVE OPTIONS> program arg1 arg2 ...\n"
28 "\nwhere:"
29 "\n\t <SPORADIC OPTIONS> = "
30 "[-c {hrt|srt|be}] [-p <cpu>] <wcet> <period>\n"
31 "\n\t <ADAPTIVE OPTIONS> = "
32 "(-a weight/period/utility)+ [-w <y intercept>+<slope>v]\n"
33 "\nExamples:"
34 "\n\trt_launch -p 2 10 100 cpu_job"
35 "\n\t => Launch cpu_job a hard real-time task with period 100 and weight 0.1"
36 "\n\t on CPU 2.\n"
37 "\n\trt_launch -a 0.1/100/0.4 -a 0.2/75/0.5 -w 0.2+0.3v adaptive_job"
38 "\n\t => Launch adaptive_job with two service levels and a custom "
39 "\n\t weight-transfer function."
40 "\n\n",
28 error); 41 error);
29 exit(1); 42 exit(1);
30} 43}
31 44
32/* argument format should be wcet/period/utility */ 45/* argument format should be weight/period/utility */
33static int parse_service_level(service_level_t* level, char* str) 46static int parse_service_level(service_level_t* level, char* str)
34{ 47{
35 char *wcet, *period, *utility; 48 char *weight, *period, *utility;
36 double u; 49 double u, w;
37 wcet = strtok(str, "/"); 50 weight = strtok(str, "/");
38 period = strtok(NULL, "/"); 51 period = strtok(NULL, "/");
39 utility = strtok(NULL, "/"); 52 utility = strtok(NULL, "/");
40 str = strtok(NULL, "/"); 53 str = strtok(NULL, "/");
41 54
42 if (str || !utility || !period || !wcet) 55 if (str || !utility || !period || !weight)
43 return 0; 56 return 0;
44 57
45 level->exec_cost = atol(wcet); 58 w = atof(weight);
46 level->period = atol(period);
47 u = atof(utility); 59 u = atof(utility);
60 level->weight = f2fp(w);
61 level->period = atol(period);
62 level->value = f2fp(u);
63
64 if (level->period == 0 ||
65 u <= 0.0 || u > 1.0 || w <= 0.0 || w > 1.0)
66 return 0;
67 return 1;
68}
48 69
49 if (level->exec_cost == 0 || level->period < level->exec_cost || 70/* argument format should be <y intercept>+<slope>v */
50 u <= 0.0 || u > 1.0) 71static int parse_wt(fp_t *_y, fp_t *_slope, char* str)
72{
73 char *y, *slope;
74 double yf, sf;
75 y = strtok(str, "+");
76 slope = strtok(NULL, "v");
77 str = strtok(NULL, "/"); /* If we find anyting at all then the
78 * string is malformed.
79 */
80 if (str || !y || !slope)
51 return 0; 81 return 0;
52 82
53 level->utility = (unsigned long) ULONG_MAX * u; 83 yf = strtof(y, &y);
84 sf = strtof(slope, &slope);
85
86 if (*y || *slope ||
87 yf < 0.0 || sf <= 0.0)
88 return 0;
89
90 *_y = f2fp(yf);
91 *_slope = f2fp(sf);
54 return 1; 92 return 1;
55} 93}
56 94
57#define OPTSTR "p:c:a:" 95
96#define OPTSTR "p:c:a:w:"
58 97
59int main(int argc, char** argv) 98int main(int argc, char** argv)
60{ 99{
@@ -69,7 +108,13 @@ int main(int argc, char** argv)
69 int adaptive = 0; 108 int adaptive = 0;
70 unsigned int level = 0; 109 unsigned int level = 0;
71 service_level_t slevel[MAX_SERVICE_LEVELS]; 110 service_level_t slevel[MAX_SERVICE_LEVELS];
111 fp_t wt_y; /* weight-transfer y intercept */
112 fp_t wt_slope; /* weight-transfer slope */
72 113
114
115 wt_y = f2fp(0.0);
116 wt_slope = f2fp(1.0);
117
73 while ((opt = getopt(argc, argv, OPTSTR)) != -1) { 118 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
74 switch (opt) { 119 switch (opt) {
75 case 'a': 120 case 'a':
@@ -79,6 +124,10 @@ int main(int argc, char** argv)
79 if (!parse_service_level(slevel + level++, optarg)) 124 if (!parse_service_level(slevel + level++, optarg))
80 usage("Bad service level."); 125 usage("Bad service level.");
81 break; 126 break;
127 case 'w':
128 if (!parse_wt(&wt_y, &wt_slope, optarg))
129 usage("Bad weight transfer function.");
130 break;
82 case 'p': 131 case 'p':
83 cpu = atoi(optarg); 132 cpu = atoi(optarg);
84 break; 133 break;
@@ -93,7 +142,7 @@ int main(int argc, char** argv)
93 break; 142 break;
94 case '?': 143 case '?':
95 default: 144 default:
96 usage("Unknown flag."); 145 usage("Bad argument.");
97 break; 146 break;
98 } 147 }
99 } 148 }
@@ -120,7 +169,8 @@ int main(int argc, char** argv)
120 usage("Arguments missing."); 169 usage("Arguments missing.");
121 info.exec_path = argv[optind]; 170 info.exec_path = argv[optind];
122 info.argv = argv + optind; 171 info.argv = argv + optind;
123 ret = create_adaptive_rt_task(launch, &info, level, slevel); 172 ret = create_adaptive_rt_task(launch, &info, level, slevel,
173 wt_y, wt_slope);
124 } 174 }
125 175
126 176