aboutsummaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-06-24 19:50:19 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-06-24 19:50:19 -0400
commitc176d77f446a9f218e0bd413bfad949b286e8326 (patch)
treee55aad93dd3a4fa410e54c01d97f687cf2669dbc /bin
parent623b61db6649c1fd60791df965f38a06acb3ea93 (diff)
[NPS-F] Add rtspin and utility to add notional processors
- add syscall to add notional processors (servers) - add rtspin_npsf program to run on specified (npsf_id, cpu) - add npsf_add_server as wrapper on the syscall
Diffstat (limited to 'bin')
-rw-r--r--bin/npsf_add_server.c45
-rw-r--r--bin/rtspin_npsf.c252
2 files changed, 297 insertions, 0 deletions
diff --git a/bin/npsf_add_server.c b/bin/npsf_add_server.c
new file mode 100644
index 0000000..3983e77
--- /dev/null
+++ b/bin/npsf_add_server.c
@@ -0,0 +1,45 @@
1/* wrapper for sys_add_server */
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h>
5
6#include "litmus.h"
7#include "common.h"
8
9void usage(char *error) {
10 fprintf(stderr, "Error: %s\n", error);
11 fprintf(stderr,
12 "Usage: npsf_add_server NPSF-ID UTIL SLOT-SIZE(ms) CPU \n");
13 exit(1);
14}
15
16int main(int argc, char** argv)
17{
18 int ret;
19 int cpu = 0;
20 int npsf_id = 0;
21 double util = 0;
22 int slot_ms = 0;
23 lt_t budget_ns = 0;
24
25 if (argc < 5)
26 usage("Arguments missing.");
27 npsf_id = atoi(argv[1]);
28 util = atof(argv[2]);
29 slot_ms = atoi(argv[3]);
30 cpu = atoi(argv[4]);
31
32 if (util > 1)
33 usage("Utilization > 1");
34
35 budget_ns = (lt_t)((__NS_PER_MS * util) * slot_ms);
36
37 printf("Trying to add NP(%d): budget = %f\n", npsf_id, (double)(budget_ns) / __NS_PER_MS);
38
39 ret = add_server(&npsf_id, &budget_ns, &cpu);
40
41 if (ret < 0)
42 bail_out("Cannot add Notional Processor: ");
43
44 return 0;
45}
diff --git a/bin/rtspin_npsf.c b/bin/rtspin_npsf.c
new file mode 100644
index 0000000..87eb52f
--- /dev/null
+++ b/bin/rtspin_npsf.c
@@ -0,0 +1,252 @@
1#include <sys/time.h>
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <time.h>
7
8
9#include "litmus.h"
10#include "common.h"
11
12
13static double cputime()
14{
15 struct timespec ts;
16 int err;
17 err = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
18 if (err != 0)
19 perror("clock_gettime");
20 return (ts.tv_sec + 1E-9 * ts.tv_nsec);
21}
22
23static double wctime()
24{
25 struct timeval tv;
26 gettimeofday(&tv, NULL);
27 return (tv.tv_sec + 1E-6 * tv.tv_usec);
28}
29
30void usage(char *error) {
31 fprintf(stderr, "Error: %s\n", error);
32 fprintf(stderr,
33 "Usage: rt_spin [-w] WCET PERIOD DURATION CPU NPSF-ID\n"
34 " rt_spin -l\n");
35 exit(1);
36}
37
38#define NUMS 4096
39static int num[NUMS];
40static double loop_length = 1.0;
41static char* progname;
42
43static int loop_once(void)
44{
45 int i, j = 0;
46 for (i = 0; i < NUMS; i++)
47 j += num[i]++;
48 return j;
49}
50
51static int loop_for(double exec_time)
52{
53 double t = 0;
54 int tmp = 0;
55/* while (t + loop_length < exec_time) {
56 tmp += loop_once();
57 t += loop_length;
58 }
59*/
60 double start = cputime();
61 double now = cputime();
62 while (now + loop_length < start + exec_time) {
63 tmp += loop_once();
64 t += loop_length;
65 now = cputime();
66 }
67
68 return tmp;
69}
70
71static void fine_tune(double interval)
72{
73 double start, end, delta;
74
75 start = wctime();
76 loop_for(interval);
77 end = wctime();
78 delta = (end - start - interval) / interval;
79 if (delta != 0)
80 loop_length = loop_length / (1 - delta);
81}
82
83static void configure_loop(void)
84{
85 double start;
86
87 /* prime cache */
88 loop_once();
89 loop_once();
90 loop_once();
91
92 /* measure */
93 start = wctime();
94 loop_once(); /* hope we didn't get preempted */
95 loop_length = wctime();
96 loop_length -= start;
97
98 /* fine tune */
99 fine_tune(0.1);
100 fine_tune(0.1);
101 fine_tune(0.1);
102}
103
104static void show_loop_length(void)
105{
106 printf("%s/%d: loop_length=%f (%ldus)\n",
107 progname, getpid(), loop_length,
108 (long) (loop_length * 1000000));
109}
110
111static void debug_delay_loop(void)
112{
113 double start, end, delay;
114 show_loop_length();
115 while (1) {
116 for (delay = 0.5; delay > 0.01; delay -= 0.01) {
117 start = wctime();
118 loop_for(delay);
119 end = wctime();
120 printf("%6.4fs: looped for %10.8fs, delta=%11.8fs, error=%7.4f%%\n",
121 delay,
122 end - start,
123 end - start - delay,
124 100 * (end - start - delay) / delay);
125 }
126 }
127}
128
129static int job(double exec_time)
130{
131 loop_for(exec_time);
132 sleep_next_period();
133 return 0;
134}
135
136#define OPTSTR "c:wld:v"
137
138int main(int argc, char** argv)
139{
140 int ret;
141 lt_t wcet;
142 lt_t period;
143 double wcet_ms, period_ms;
144 int migrate = 0;
145 int cpu = 0;
146 int npsf_id = 0;
147 int opt;
148 int wait = 0;
149 int test_loop = 0;
150 int skip_config = 0;
151 int verbose = 0;
152 double duration, start;
153 task_class_t class = RT_CLASS_HARD;
154
155 progname = argv[0];
156
157 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
158 switch (opt) {
159 case 'w':
160 wait = 1;
161 break;
162 case 'c':
163 class = str2class(optarg);
164 if (class == -1)
165 usage("Unknown task class.");
166 break;
167 case 'l':
168 test_loop = 1;
169 break;
170 case 'd':
171 /* manually configure delay per loop iteration
172 * unit: microseconds */
173 loop_length = atof(optarg) / 1000000;
174 skip_config = 1;
175 break;
176 case 'v':
177 verbose = 1;
178 break;
179 case ':':
180 usage("Argument missing.");
181 break;
182 case '?':
183 default:
184 usage("Bad argument.");
185 break;
186 }
187 }
188
189
190 if (!skip_config)
191 configure_loop();
192
193 if (test_loop) {
194 debug_delay_loop();
195 return 0;
196 }
197
198 if (argc - optind < 3)
199 usage("Arguments missing.");
200 wcet_ms = atof(argv[optind + 0]);
201 period_ms = atof(argv[optind + 1]);
202 duration = atof(argv[optind + 2]);
203 cpu = atoi(argv[optind + 3]);
204 migrate = 1;
205 npsf_id = atoi(argv[optind + 4]);
206 wcet = wcet_ms * __NS_PER_MS;
207 period = period_ms * __NS_PER_MS;
208 if (wcet <= 0)
209 usage("The worst-case execution time must be a "
210 "positive number.");
211 if (period <= 0)
212 usage("The period must be a positive number.");
213 if (wcet > period) {
214 usage("The worst-case execution time must not "
215 "exceed the period.");
216 }
217
218 if (migrate) {
219 ret = be_migrate_to(cpu);
220 if (ret < 0)
221 bail_out("could not migrate to target partition");
222 }
223
224 ret = sporadic_task_ns_npsf(wcet, period, 0, cpu, class, npsf_id,
225 NO_ENFORCEMENT, migrate);
226
227 if (ret < 0)
228 bail_out("could not setup rt task params");
229
230 if (verbose)
231 show_loop_length();
232
233 init_litmus();
234
235 ret = task_mode(LITMUS_RT_TASK);
236 if (ret != 0)
237 bail_out("could not become RT task");
238
239 if (wait) {
240 ret = wait_for_ts_release();
241 if (ret != 0)
242 bail_out("wait_for_ts_release()");
243 }
244
245 start = wctime();
246
247 while (start + duration > wctime()) {
248 job(wcet_ms * 0.0009); /* 90% wcet, in seconds */
249 }
250
251 return 0;
252}