aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-03-25 21:48:12 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-03-25 21:48:12 -0400
commit7b709ceb7d2191fc552ab70bc1365b47120c634c (patch)
tree4cd9b9efa3ac6af5211a47460dce2bb1c52c2f2b
parent8ce85aaacafa0a46827f7799d051a20fac639ee9 (diff)
auto-configure spin loop in rtspin
Don't just blindly overrun the budget. Instead, try to measure a spin loop and hope that we get good results.
-rw-r--r--bin/rtspin.c123
1 files changed, 110 insertions, 13 deletions
diff --git a/bin/rtspin.c b/bin/rtspin.c
index 435e496..56f5549 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -9,11 +9,6 @@
9#include "litmus.h" 9#include "litmus.h"
10#include "common.h" 10#include "common.h"
11 11
12void usage(char *error) {
13 fprintf(stderr, "Error: %s\n", error);
14 fprintf(stderr, "Usage: rt_spin [-w] [-p PARTITION] [-c CLASS] WCET PERIOD DURATION\n");
15 exit(1);
16}
17 12
18static double wctime() 13static double wctime()
19{ 14{
@@ -22,11 +17,99 @@ static double wctime()
22 return (tv.tv_sec + 1E-6 * tv.tv_usec); 17 return (tv.tv_sec + 1E-6 * tv.tv_usec);
23} 18}
24 19
25#define OPTSTR "p:c:w" 20void usage(char *error) {
21 fprintf(stderr, "Error: %s\n", error);
22 fprintf(stderr,
23 "Usage: rt_spin [-w] [-p PARTITION] [-c CLASS] WCET PERIOD DURATION\n"
24 " rt_spin -l\n");
25 exit(1);
26}
27
28#define NUMS 4096
29static int num[NUMS];
30static double loop_length = 1.0;
31
32static int loop_once(void)
33{
34 int i, j = 0;
35 for (i = 0; i < NUMS; i++)
36 j += num[i]++;
37 return j;
38}
39
40static int loop_for(double exec_time)
41{
42 double t = 0;
43 int tmp = 0;
44 while (t + loop_length < exec_time) {
45 tmp += loop_once();
46 t += loop_length;
47 }
48 return tmp;
49}
50
51static void fine_tune(double interval)
52{
53 double start, end, delta;
54
55 start = wctime();
56 loop_for(interval);
57 end = wctime();
58 delta = (end - start - interval) / interval;
59 if (delta != 0)
60 loop_length = loop_length / (1 - delta);
61}
62
63static void configure_loop(void)
64{
65 double start;
66
67 /* prime cache */
68 loop_once();
69 loop_once();
70 loop_once();
71
72 /* measure */
73 start = wctime();
74 loop_once(); /* hope we didn't get preempted */
75 loop_length = wctime();
76 loop_length -= start;
77
78 /* fine tune */
79 fine_tune(0.1);
80 fine_tune(0.1);
81 fine_tune(0.1);
82}
83
84static void debug_delay_loop(void)
85{
86 double start, end, delay;
87 printf("loop_length=%f\n", loop_length);
88 while (1) {
89 for (delay = 0.5; delay > 0.01; delay -= 0.01) {
90 start = wctime();
91 loop_for(delay);
92 end = wctime();
93 printf("%6.4fs: looped for %10.8fs, delta=%11.8fs, error=%7.4f%%\n",
94 delay,
95 end - start,
96 end - start - delay,
97 100 * (end - start - delay) / delay);
98 }
99 }
100}
101
102static int job(double exec_time)
103{
104 loop_for(exec_time);
105 sleep_next_period();
106 return 0;
107}
108
109#define OPTSTR "p:c:wl"
26 110
27int main(int argc, char** argv) 111int main(int argc, char** argv)
28{ 112{
29 int i;
30 int ret; 113 int ret;
31 lt_t wcet; 114 lt_t wcet;
32 lt_t period; 115 lt_t period;
@@ -34,6 +117,7 @@ int main(int argc, char** argv)
34 int cpu = 0; 117 int cpu = 0;
35 int opt; 118 int opt;
36 int wait = 0; 119 int wait = 0;
120 int test_loop = 0;
37 double duration, start; 121 double duration, start;
38 task_class_t class = RT_CLASS_HARD; 122 task_class_t class = RT_CLASS_HARD;
39 123
@@ -51,6 +135,9 @@ int main(int argc, char** argv)
51 if (class == -1) 135 if (class == -1)
52 usage("Unknown task class."); 136 usage("Unknown task class.");
53 break; 137 break;
138 case 'l':
139 test_loop = 1;
140 break;
54 case ':': 141 case ':':
55 usage("Argument missing."); 142 usage("Argument missing.");
56 break; 143 break;
@@ -61,6 +148,14 @@ int main(int argc, char** argv)
61 } 148 }
62 } 149 }
63 150
151
152 configure_loop();
153
154 if (test_loop) {
155 debug_delay_loop();
156 return 0;
157 }
158
64 if (argc - optind < 3) 159 if (argc - optind < 3)
65 usage("Arguments missing."); 160 usage("Arguments missing.");
66 wcet = atoi(argv[optind + 0]); 161 wcet = atoi(argv[optind + 0]);
@@ -75,21 +170,21 @@ int main(int argc, char** argv)
75 usage("The worst-case execution time must not " 170 usage("The worst-case execution time must not "
76 "exceed the period."); 171 "exceed the period.");
77 } 172 }
173
78 if (migrate) { 174 if (migrate) {
79 ret = be_migrate_to(cpu); 175 ret = be_migrate_to(cpu);
80 if (ret < 0) 176 if (ret < 0)
81 bail_out("could not migrate to target partition"); 177 bail_out("could not migrate to target partition");
82 } 178 }
83 179
84// printf("wcet: %llu\nperiod: %llu\n", wcet, period);
85 ret = sporadic_task(wcet, period, 0, cpu, class, migrate); 180 ret = sporadic_task(wcet, period, 0, cpu, class, migrate);
86 181
87 if (ret < 0) 182 if (ret < 0)
88 bail_out("could not become rt tasks."); 183 bail_out("could not become rt tasks.");
89 184
90// ret = init_litmus(); 185 ret = init_litmus();
91// if (ret < 0) 186 if (ret < 0)
92// perror("init_litmus()"); 187 perror("init_litmus()");
93 188
94 ret = task_mode(LITMUS_RT_TASK); 189 ret = task_mode(LITMUS_RT_TASK);
95 if (ret != 0) 190 if (ret != 0)
@@ -100,10 +195,12 @@ int main(int argc, char** argv)
100 if (ret != 0) 195 if (ret != 0)
101 bail_out("wait_for_ts_release()"); 196 bail_out("wait_for_ts_release()");
102 } 197 }
198
199
103 start = wctime(); 200 start = wctime();
104 201
105 while (start + duration > wctime()) { 202 while (start + duration > wctime()) {
106 for (i = 0; i < 500000; i++); 203 job(wcet * 0.0009); /* 90% wcet, in seconds */
107 } 204 }
108 205
109 return 0; 206 return 0;