aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2017-09-14 17:58:28 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2017-09-14 17:58:28 -0400
commita430c7b5cacae4219a185decb863f6fb9e5cbcb9 (patch)
tree8a1302ddb89504f856ff89ec2d17deaac1172cb6
parente9d67470da50e5428ab4d359f2beedf54a28f9aa (diff)
parent31352298446e1fc1ba4dc391197aef3fd57bf080 (diff)
Merge remote-tracking branch 'github/master'
Conflicts: bin/rtspin.c Resolve option clash by moving the calibration loop to -a0.
-rw-r--r--bin/rtspin.c136
-rw-r--r--include/common.h6
2 files changed, 112 insertions, 30 deletions
diff --git a/bin/rtspin.c b/bin/rtspin.c
index 68f721d..fb7f13f 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -19,8 +19,9 @@ const 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 -C FILE: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 [-a CYCLES]\n"
23 " (5) rtspin -B -m FOOTPRINT\n" 23 " (5) rtspin -B -m FOOTPRINT\n"
24 " (6) rtspin -a 0\n"
24 "\n" 25 "\n"
25 "Modes: (1) run as periodic task with given WCET and PERIOD\n" 26 "Modes: (1) run as periodic task with given WCET and PERIOD\n"
26 " (2) run as sporadic task with given WCET and PERIOD,\n" 27 " (2) run as sporadic task with given WCET and PERIOD,\n"
@@ -31,12 +32,15 @@ const char *usage_msg =
31 " (4) Run calibration loop (how accurately are target\n" 32 " (4) Run calibration loop (how accurately are target\n"
32 " runtimes met?)\n" 33 " runtimes met?)\n"
33 " (5) Run background, non-real-time cache-thrashing loop.\n" 34 " (5) Run background, non-real-time cache-thrashing loop.\n"
35 " (6) Run 1 ms workload calibration (estimate cycles for 1ms, 10ms, 100ms workload)\n"
34 "\n" 36 "\n"
35 "Required arguments:\n" 37 "Required arguments:\n"
36 " WCET, PERIOD reservation parameters (in ms)\n" 38 " WCET, PERIOD reservation parameters (in ms)\n"
37 " DURATION terminate the task after DURATION seconds\n" 39 " DURATION terminate the task after DURATION seconds\n"
38 "\n" 40 "\n"
39 "Options:\n" 41 "Options:\n"
42 " -a CYCLES number of cycles for 1ms of workload loop chosen after calibration;\n "
43 " pass '0' to run the calibration loop\n"
40 " -B run non-real-time background loop\n" 44 " -B run non-real-time background loop\n"
41 " -c be|srt|hrt task class (best-effort, soft real-time, hard real-time)\n" 45 " -c be|srt|hrt task class (best-effort, soft real-time, hard real-time)\n"
42 " -d DEADLINE relative deadline, equal to the period by default (in ms)\n" 46 " -d DEADLINE relative deadline, equal to the period by default (in ms)\n"
@@ -106,18 +110,23 @@ static int nr_of_pages = 0;
106static int page_size; 110static int page_size;
107static void *base = NULL; 111static void *base = NULL;
108 112
109static int loop_once(void) 113static int cycles_ms = 0;
114
115static noinline int loop(int count)
110{ 116{
111 int i, j = 0; 117 int i, j = 0;
112 /* touch some numbers and do some math */ 118 /* touch some numbers and do some math */
113 for (i = 0; i < NUMS; i++) { 119 for (i = 0; i < count; i++) {
114 j += num[i]++; 120 int index = i % NUMS;
115 if (j > num[i]) 121 j += num[index]++;
116 num[i] = (j / 2) + 1; 122 if (j > num[index])
123 num[index] = (j / 2) + 1;
117 } 124 }
118 return j; 125 return j;
119} 126}
120 127
128#define loop_once() loop(NUMS)
129
121static int loop_once_with_mem(void) 130static int loop_once_with_mem(void)
122{ 131{
123 int i, j = 0; 132 int i, j = 0;
@@ -143,30 +152,35 @@ static int loop_once_with_mem(void)
143 152
144static int loop_for(double exec_time, double emergency_exit) 153static int loop_for(double exec_time, double emergency_exit)
145{ 154{
146 double last_loop = 0, loop_start;
147 int tmp = 0; 155 int tmp = 0;
148 156
149 double start = cputime(); 157 if (cycles_ms) {
150 double now = cputime(); 158 double count = cycles_ms * exec_time * 1000;
159 tmp += loop(count);
160 } else {
161 double last_loop = 0, loop_start;
162 double start = cputime();
163 double now = cputime();
151 164
152 while (now + last_loop < start + exec_time) { 165 while (now + last_loop < start + exec_time) {
153 loop_start = now; 166 loop_start = now;
154 if (nr_of_pages) 167 if (nr_of_pages)
155 tmp += loop_once_with_mem(); 168 tmp += loop_once_with_mem();
156 else 169 else
157 tmp += loop_once(); 170 tmp += loop_once();
158 now = cputime(); 171 now = cputime();
159 last_loop = now - loop_start; 172 last_loop = now - loop_start;
160 if (emergency_exit && wctime() > emergency_exit) { 173 if (emergency_exit && wctime() > emergency_exit) {
161 /* Oops --- this should only be possible if the 174 /* Oops --- this should only be possible if the
162 * execution time tracking is broken in the LITMUS^RT 175 * execution time tracking is broken in the LITMUS^RT
163 * kernel or the user specified infeasible parameters. 176 * kernel or the user specified infeasible parameters.
164 */ 177 */
165 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", 178 fprintf(stderr, "!!! rtspin/%d emergency exit!\n",
166 getpid()); 179 getpid());
167 fprintf(stderr, "Reached experiment timeout while " 180 fprintf(stderr, "Reached experiment timeout while "
168 "spinning.\n"); 181 "spinning.\n");
169 break; 182 break;
183 }
170 } 184 }
171 } 185 }
172 186
@@ -180,9 +194,9 @@ static void debug_delay_loop(void)
180 194
181 while (1) { 195 while (1) {
182 for (delay = 0.5; delay > 0.01; delay -= 0.01) { 196 for (delay = 0.5; delay > 0.01; delay -= 0.01) {
183 start = wctime(); 197 start = cputime();
184 loop_for(delay, 0); 198 loop_for(delay, 0);
185 end = wctime(); 199 end = cputime();
186 printf("%6.4fs: looped for %10.8fs, delta=%11.8fs, error=%7.4f%%\n", 200 printf("%6.4fs: looped for %10.8fs, delta=%11.8fs, error=%7.4f%%\n",
187 delay, 201 delay,
188 end - start, 202 end - start,
@@ -194,6 +208,51 @@ static void debug_delay_loop(void)
194 208
195static char input_buf[4096] = "<no input>"; 209static char input_buf[4096] = "<no input>";
196 210
211static int calibrate_ms(int ms)
212{
213 int right = NUMS;
214 int left = 0;
215 int middle;
216
217 double start;
218 double now;
219 double dms = 0.001 * ms;
220
221 /*look for initial loop count values for binary search*/
222 for (;;)
223 {
224 printf("Probe %d loops for %d ms:\n", right, ms);
225 start = wctime();
226 loop(right);
227 now = wctime();
228 if ((now - start) >= dms)
229 break;
230 left = right;
231 right += right;
232 }
233
234 middle = (left + right) / 2;
235
236 /*binary search for a loop count value for expected calibration time*/
237 while (left < middle)
238 {
239 start = wctime();
240 loop(middle);
241 now = wctime();
242
243 printf("%d loops elapsed in %4.20f s\n", middle, now - start);
244
245 if ((now - start) < dms)
246 left = middle;
247 else if ((now - start) == dms)
248 return middle;
249 else
250 right = middle;
251 middle = (left + right) / 2;
252 }
253 return middle;
254}
255
197static int wait_for_input(int event_fd) 256static int wait_for_input(int event_fd)
198{ 257{
199 /* We do a blocking read, accepting up to 4KiB of data. 258 /* We do a blocking read, accepting up to 4KiB of data.
@@ -277,7 +336,7 @@ static lt_t choose_inter_arrival_time_ns(
277 return ms2ns(iat_ms); 336 return ms2ns(iat_ms);
278} 337}
279 338
280#define OPTSTR "p:c:wlveo:s:m:q:r:X:L:Q:iRu:U:Bhd:C:S::O::TD:E:A:" 339#define OPTSTR "p:c:wlveo:s:m:q:r:X:L:Q:iRu:U:Bhd:C:S::O::TD:E:A:a:"
281 340
282int main(int argc, char** argv) 341int main(int argc, char** argv)
283{ 342{
@@ -298,6 +357,7 @@ int main(int argc, char** argv)
298 int opt; 357 int opt;
299 int wait = 0; 358 int wait = 0;
300 int test_loop = 0; 359 int test_loop = 0;
360 int caliber_ms = 0;
301 int background_loop = 0; 361 int background_loop = 0;
302 362
303 int cost_column = 1; 363 int cost_column = 1;
@@ -480,6 +540,11 @@ int main(int argc, char** argv)
480 verbose = 1; 540 verbose = 1;
481 report_interrupts = 1; 541 report_interrupts = 1;
482 break; 542 break;
543 case 'a':
544 cycles_ms = want_non_negative_int(optarg, "-a");
545 if (!cycles_ms)
546 caliber_ms = 1;
547 break;
483 case ':': 548 case ':':
484 usage("Argument missing."); 549 usage("Argument missing.");
485 break; 550 break;
@@ -513,10 +578,21 @@ int main(int argc, char** argv)
513 srand(getpid()); 578 srand(getpid());
514 579
515 if (test_loop) { 580 if (test_loop) {
581 if (cycles_ms > 0)
582 printf("Evaluating loop with %d cycles:\n", cycles_ms);
583
516 debug_delay_loop(); 584 debug_delay_loop();
517 return 0; 585 return 0;
518 } 586 }
519 587
588 if (caliber_ms) {
589 printf("In 1 ms %d loops.\n", calibrate_ms(1));
590 printf("In 10 ms %d loops.\n", calibrate_ms(10));
591 printf("In 100 ms %d loops.\n", calibrate_ms(100));
592 printf("In 1 s %d loops.\n", calibrate_ms(1000));
593 return 0;
594 }
595
520 if (background_loop) { 596 if (background_loop) {
521 while (1) { 597 while (1) {
522 if (nr_of_pages) 598 if (nr_of_pages)
diff --git a/include/common.h b/include/common.h
index b77ae67..7c33c94 100644
--- a/include/common.h
+++ b/include/common.h
@@ -6,6 +6,12 @@
6#ifndef COMMON_H 6#ifndef COMMON_H
7#define COMMON_H 7#define COMMON_H
8 8
9#if defined(__GNUC__)
10#define noinline __attribute__((__noinline__))
11#else
12#define noinline
13#endif
14
9/** 15/**
10 * End the current task with a message 16 * End the current task with a message
11 * @param msg Message to output before bailing 17 * @param msg Message to output before bailing