Attachment 'pgmrt-liblitmus-ecrts14.patch'
Download 1 From 6d3c2bd5adbcb6b3ac8fbc8c80e8913d7a68441c Mon Sep 17 00:00:00 2001
2 From: Glenn Elliott <gelliott@cs.unc.edu>
3 Date: Wed, 19 Feb 2014 16:30:21 -0500
4 Subject: [PATCH] ECRTS14 PGM^RT patch for liblitmus
5
6 ---
7 Makefile | 2 +-
8 bin/rt_launch.c | 10 ++---
9 bin/rtspin.c | 13 ++++---
10 include/litmus.h | 34 ++++++++++-------
11 include/migration.h | 22 ++++++-----
12 src/kernel_iface.c | 59 ++++++++++++++++++++++++++++-
13 src/litmus.c | 11 +++---
14 src/migration.c | 105 +++++++++++++++++++++++----------------------------
15 src/task.c | 9 +++--
16 9 files changed, 161 insertions(+), 104 deletions(-)
17
18 diff --git a/Makefile b/Makefile
19 index e8003e8..39a79a7 100644
20 --- a/Makefile
21 +++ b/Makefile
22 @@ -19,7 +19,7 @@ LITMUS_KERNEL ?= ../litmus-rt
23 # Internal configuration.
24
25 # compiler flags
26 -flags-debug = -O2 -Wall -Werror -g -Wdeclaration-after-statement
27 +flags-debug = -Os -march=native -Wall -Werror -Wdeclaration-after-statement
28 flags-api = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE
29
30 # architecture-specific flags
31 diff --git a/bin/rt_launch.c b/bin/rt_launch.c
32 index 93f10d5..5e29893 100644
33 --- a/bin/rt_launch.c
34 +++ b/bin/rt_launch.c
35 @@ -42,7 +42,7 @@ void usage(char *error) {
36 }
37
38
39 -#define OPTSTR "p:z:c:vwq:"
40 +#define OPTSTR "p:c:vwq:"
41
42 int main(int argc, char** argv)
43 {
44 @@ -51,7 +51,6 @@ int main(int argc, char** argv)
45 lt_t period;
46 int migrate = 0;
47 int cluster = 0;
48 - int cluster_size = 1;
49 int opt;
50 int verbose = 0;
51 int wait = 0;
52 @@ -71,9 +70,6 @@ int main(int argc, char** argv)
53 cluster = atoi(optarg);
54 migrate = 1;
55 break;
56 - case 'z':
57 - cluster_size = atoi(optarg);
58 - break;
59 case 'q':
60 priority = atoi(optarg);
61 if (!litmus_is_valid_fixed_prio(priority))
62 @@ -114,11 +110,11 @@ int main(int argc, char** argv)
63 info.argv = argv + optind + 2;
64 info.wait = wait;
65 if (migrate) {
66 - ret = be_migrate_to_cluster(cluster, cluster_size);
67 + ret = be_migrate_to_domain(cluster);
68 if (ret < 0)
69 bail_out("could not migrate to target partition or cluster");
70 }
71 - ret = __create_rt_task(launch, &info, cluster, cluster_size, wcet, period,
72 + ret = __create_rt_task(launch, &info, cluster, wcet, period,
73 priority, class);
74
75
76 diff --git a/bin/rtspin.c b/bin/rtspin.c
77 index 167741d..b518574 100644
78 --- a/bin/rtspin.c
79 +++ b/bin/rtspin.c
80 @@ -184,7 +184,7 @@ static int job(double exec_time, double program_end, int lock_od, double cs_leng
81 }
82 }
83
84 -#define OPTSTR "p:z:c:wlveo:f:s:q:X:L:Q:"
85 +#define OPTSTR "p:c:wlveo:f:s:q:X:L:Q:n:"
86 int main(int argc, char** argv)
87 {
88 int ret;
89 @@ -192,9 +192,9 @@ int main(int argc, char** argv)
90 lt_t period;
91 double wcet_ms, period_ms;
92 unsigned int priority = LITMUS_LOWEST_PRIORITY;
93 + int split_factor = 1;
94 int migrate = 0;
95 int cluster = 0;
96 - int cluster_size = 1;
97 int opt;
98 int wait = 0;
99 int test_loop = 0;
100 @@ -226,8 +226,8 @@ int main(int argc, char** argv)
101 cluster = atoi(optarg);
102 migrate = 1;
103 break;
104 - case 'z':
105 - cluster_size = atoi(optarg);
106 + case 'n':
107 + split_factor = atoi(optarg);
108 break;
109 case 'q':
110 priority = atoi(optarg);
111 @@ -326,7 +326,7 @@ int main(int argc, char** argv)
112 duration += period_ms * 0.001 * (num_jobs - 1);
113
114 if (migrate) {
115 - ret = be_migrate_to_cluster(cluster, cluster_size);
116 + ret = be_migrate_to_domain(cluster);
117 if (ret < 0)
118 bail_out("could not migrate to target partition or cluster.");
119 }
120 @@ -334,12 +334,13 @@ int main(int argc, char** argv)
121 init_rt_task_param(¶m);
122 param.exec_cost = wcet;
123 param.period = period;
124 + param.split = split_factor;
125 param.priority = priority;
126 param.cls = class;
127 param.budget_policy = (want_enforcement) ?
128 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
129 if (migrate)
130 - param.cpu = cluster_to_first_cpu(cluster, cluster_size);
131 + param.cpu = domain_to_first_cpu(cluster);
132 ret = set_rt_task_param(gettid(), ¶m);
133 if (ret < 0)
134 bail_out("could not setup rt task params");
135 diff --git a/include/litmus.h b/include/litmus.h
136 index ef3fef3..2b0d5c2 100644
137 --- a/include/litmus.h
138 +++ b/include/litmus.h
139 @@ -24,20 +24,13 @@ void init_rt_task_param(struct rt_task* param);
140 int set_rt_task_param(pid_t pid, struct rt_task* param);
141 int get_rt_task_param(pid_t pid, struct rt_task* param);
142
143 -/* Release-master-aware functions for getting the first
144 - * CPU in a particular cluster or partition. Use these
145 - * to set rt_task::cpu for cluster/partitioned scheduling.
146 - */
147 -int partition_to_cpu(int partition);
148 -int cluster_to_first_cpu(int cluster, int cluster_size);
149 -
150 /* Convenience functions for setting up real-time tasks.
151 * Default behaviors set by init_rt_task_params() used.
152 * Also sets affinity masks for clustered/partitions
153 * functions. Time units in nanoseconds. */
154 int sporadic_global(lt_t e_ns, lt_t p_ns);
155 int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition);
156 -int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster, int cluster_size);
157 +int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster);
158
159 /* simple time unit conversion macros */
160 #define s2ns(s) ((s)*1000000000LL)
161 @@ -47,6 +40,13 @@ int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster, int cluster_size);
162 #define ms2us(ms) ((ms)*1000LL)
163 #define us2ns(us) ((us)*1000LL)
164
165 +#define ns2s(ns) ((ns)/1000000000LL)
166 +#define ns2ms(ns) ((ns)/1000000LL)
167 +#define ns2us(ns) ((ns)/1000LL)
168 +#define us2ms(us) ((us)/1000LL)
169 +#define us2s(us) ((us)/1000000LL)
170 +#define ms2s(ms) ((ms)/1000LL)
171 +
172 /* file descriptor attached shared objects support */
173 typedef enum {
174 FMLP_SEM = 0,
175 @@ -54,7 +54,7 @@ typedef enum {
176 MPCP_SEM = 2,
177 MPCP_VS_SEM = 3,
178 DPCP_SEM = 4,
179 - PCP_SEM = 5,
180 + PCP_SEM = 5,
181 } obj_type_t;
182
183 int lock_protocol_for_name(const char* name);
184 @@ -71,7 +71,7 @@ static inline int od_open(int fd, obj_type_t type, int obj_id)
185 int litmus_open_lock(
186 obj_type_t protocol, /* which locking protocol to use, e.g., FMLP_SEM */
187 int lock_id, /* numerical id of the lock, user-specified */
188 - const char* namespace, /* path to a shared file */
189 + const char* name_space, /* path to a shared file */
190 void *config_param); /* any extra info needed by the protocol (such
191 * as CPU under SRP and PCP), may be NULL */
192
193 @@ -93,12 +93,12 @@ void exit_litmus(void);
194 typedef int (*rt_fn_t)(void*);
195
196 /* These two functions configure the RT task to use enforced exe budgets.
197 - * Partitioned scheduling: cluster = desired partition, cluster_size = 1
198 - * Global scheduling: cluster = 0, cluster_size = 0
199 + * Partitioned/clustered scheduling: cluster = desired partition
200 + * Global scheduling: cluster = 0
201 */
202 -int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size,
203 +int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster,
204 lt_t wcet, lt_t period, unsigned int prio);
205 -int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size,
206 +int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster,
207 lt_t wcet, lt_t period, unsigned int prio, task_class_t cls);
208
209 /* per-task modes */
210 @@ -116,6 +116,12 @@ void enter_np(void);
211 void exit_np(void);
212 int requested_to_preempt(void);
213
214 +/* pgm support */
215 +void enter_pgm_wait(void);
216 +void exit_pgm_wait(void);
217 +void enter_pgm_send(void);
218 +void exit_pgm_send(void);
219 +
220 /* task system support */
221 int wait_for_ts_release(void);
222 int release_ts(lt_t *delay);
223 diff --git a/include/migration.h b/include/migration.h
224 index 2413e7c..757dd51 100644
225 --- a/include/migration.h
226 +++ b/include/migration.h
227 @@ -4,21 +4,25 @@ typedef int pid_t;
228 /* obtain the PID of a thread */
229 pid_t gettid();
230
231 -/* Assign a task to a cpu/partition/cluster.
232 +/* Assign a task to a cpu.
233 * PRECOND: tid is not yet in real-time mode (it's a best effort task).
234 * Set tid == 0 to migrate the caller */
235 int be_migrate_thread_to_cpu(pid_t tid, int target_cpu);
236 -int be_migrate_thread_to_partition(pid_t tid, int partition);
237 -/* If using release master, set cluster_sz to size of largest cluster. tid
238 - * will not be scheduled on release master. */
239 -int be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz);
240
241 -/* set ignore_rm == 1 to include release master in tid's cpu affinity */
242 -int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz, int ignore_rm);
243 +/* Assign a task to a scheduling domain (cluster, partition, etc.)
244 + * PRECOND: (1) tid is not yet in real-time mode.
245 + * (2) plugin that supports /proc/litmus/domain is active.
246 + */
247 +int be_migrate_thread_to_cluster(pid_t tid, int domain);
248
249 int be_migrate_to_cpu(int target_cpu);
250 -int be_migrate_to_partition(int partition);
251 -int be_migrate_to_cluster(int cluster, int cluster_sz);
252 +int be_migrate_to_domain(int domain);
253
254 int num_online_cpus();
255 int release_master();
256 +int domain_to_cpus(int domain, unsigned long long int* mask);
257 +int cpu_to_domains(int cpu, unsigned long long int* mask);
258 +
259 +/* Needed while rt_task::cpu field is in use.
260 + * XXX: Update Litmus to not use rt_task::cpu */
261 +int domain_to_first_cpu(int domain);
262 diff --git a/src/kernel_iface.c b/src/kernel_iface.c
263 index ca874ff..1aa941d 100644
264 --- a/src/kernel_iface.c
265 +++ b/src/kernel_iface.c
266 @@ -2,7 +2,7 @@
267 #include <sys/fcntl.h> /* for O_RDWR */
268 #include <sys/unistd.h>
269 #include <sched.h> /* for sched_yield() */
270 -
271 +#include <assert.h>
272
273 #include <stdio.h>
274
275 @@ -140,6 +140,63 @@ int requested_to_preempt(void)
276 return (likely(ctrl_page != NULL) && ctrl_page->sched.np.preempt);
277 }
278
279 +
280 +void enter_pgm_wait(void)
281 +{
282 + if (likely(ctrl_page != NULL) || init_kernel_iface() == 0) {
283 + assert(!ctrl_page->pgm_waiting);
284 + ctrl_page->pgm_waiting = 1;
285 + __sync_synchronize();
286 + }
287 + else {
288 + fprintf(stderr, "enter_pgm_wait: control page not mapped!\n");
289 + }
290 +}
291 +
292 +void exit_pgm_wait(void)
293 +{
294 + if (likely(ctrl_page != NULL)) {
295 + assert(ctrl_page->pgm_waiting);
296 + ctrl_page->pgm_waiting = 0;
297 + __sync_synchronize();
298 + }
299 + else {
300 + fprintf(stderr, "exit_pgm_wait: control page not mapped!\n");
301 + }
302 +}
303 +
304 +void enter_pgm_send(void)
305 +{
306 + if (likely(ctrl_page != NULL) || init_kernel_iface() == 0) {
307 + assert(!ctrl_page->pgm_sending);
308 + ctrl_page->pgm_sending = 1; /* we will become boosted if
309 + anyone tries to preempt us. */
310 + __sync_synchronize();
311 + }
312 + else {
313 + fprintf(stderr, "enter_pgm_send: control page not mapped!\n");
314 + }
315 +}
316 +
317 +void exit_pgm_send(void)
318 +{
319 + if (likely(ctrl_page != NULL)) {
320 + assert(ctrl_page->pgm_sending);
321 +
322 + ctrl_page->pgm_satisfied = 1;
323 + __sync_synchronize();
324 +
325 + /* re-eval priority. Should clear pgm_sending and pgm_satisfied. */
326 + sched_yield();
327 +
328 + /* double check that Litmus is doing its job */
329 + assert(!ctrl_page->pgm_sending && !ctrl_page->pgm_satisfied);
330 + }
331 + else {
332 + fprintf(stderr, "exit_pgm_send: control page not mapped!\n");
333 + }
334 +}
335 +
336 /* init and return a ptr to the control page for
337 * preemption and migration overhead analysis
338 *
339 diff --git a/src/litmus.c b/src/litmus.c
340 index dce8e1b..a05c180 100644
341 --- a/src/litmus.c
342 +++ b/src/litmus.c
343 @@ -103,6 +103,7 @@ void init_rt_task_param(struct rt_task* tp)
344 tp->priority = LITMUS_LOWEST_PRIORITY;
345 tp->budget_policy = NO_ENFORCEMENT;
346 tp->release_policy = TASK_SPORADIC;
347 + tp->split = 1;
348 }
349
350 task_class_t str2class(const char* str)
351 @@ -135,7 +136,7 @@ int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition)
352 int ret;
353 struct rt_task param;
354
355 - ret = be_migrate_to_partition(partition);
356 + ret = be_migrate_to_domain(partition);
357 check("be_migrate_to_partition()");
358 if (ret != 0)
359 return ret;
360 @@ -143,17 +144,17 @@ int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition)
361 init_rt_task_param(¶m);
362 param.exec_cost = e_ns;
363 param.period = p_ns;
364 - param.cpu = partition_to_cpu(partition);
365 + param.cpu = domain_to_first_cpu(partition);
366
367 return set_rt_task_param(gettid(), ¶m);
368 }
369
370 -int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster, int cluster_size)
371 +int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster)
372 {
373 int ret;
374 struct rt_task param;
375
376 - ret = be_migrate_to_cluster(cluster, cluster_size);
377 + ret = be_migrate_to_domain(cluster);
378 check("be_migrate_to_cluster()");
379 if (ret != 0)
380 return ret;
381 @@ -161,7 +162,7 @@ int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster, int cluster_size)
382 init_rt_task_param(¶m);
383 param.exec_cost = e_ns;
384 param.period = p_ns;
385 - param.cpu = cluster_to_first_cpu(cluster, cluster_size);
386 + param.cpu = domain_to_first_cpu(cluster);
387
388 return set_rt_task_param(gettid(), ¶m);
389 }
390 diff --git a/src/migration.c b/src/migration.c
391 index 5de81d5..195eeba 100644
392 --- a/src/migration.c
393 +++ b/src/migration.c
394 @@ -27,31 +27,48 @@ int num_online_cpus()
395 return sysconf(_SC_NPROCESSORS_ONLN);
396 }
397
398 -int partition_to_cpu(int partition)
399 +static int read_mapping(int idx, const char* which, unsigned long long int* mask)
400 {
401 - int cpu = partition;
402 - int master = release_master();
403 - if (master != -1 && master <= cpu) {
404 - ++cpu; /* skip over the release master */
405 + int ret = -1;
406 + char buf[129] = {0};
407 + char fname[80] = {0};
408 +
409 + if (num_online_cpus() > 64) {
410 + /* XXX: Support more than 64 CPUs.
411 + * User can still set appropriate values directly. */
412 + goto out;
413 }
414 - return cpu;
415 -}
416
417 -int cluster_to_first_cpu(int cluster, int cluster_sz)
418 -{
419 - int first_cpu;
420 - int master;
421 + snprintf(fname, sizeof(fname), "/proc/litmus/%s/%d", which, idx);
422
423 - if (cluster_sz == 1)
424 - return partition_to_cpu(cluster);
425 + ret = read_file(fname, &buf, sizeof(buf)-1);
426 + if (ret <= 0)
427 + goto out;
428
429 - master = release_master();
430 - first_cpu = cluster * cluster_sz;
431 + *mask = strtoull(buf, NULL, 16);
432 + ret = 0;
433 +
434 +out:
435 + return ret;
436 +}
437
438 - if (master == first_cpu)
439 - ++first_cpu;
440 +int domain_to_cpus(int domain, unsigned long long int* mask)
441 +{
442 + return read_mapping(domain, "domains", mask);
443 +}
444
445 - return first_cpu;
446 +int cpu_to_domains(int cpu, unsigned long long int* mask)
447 +{
448 + return read_mapping(cpu, "cpus", mask);
449 +}
450 +
451 +int domain_to_first_cpu(int domain)
452 +{
453 + unsigned long long int mask;
454 + int ret = domain_to_cpus(domain, &mask);
455 + if(ret == 0)
456 + return (ffsll(mask)-1);
457 + return ret;
458 }
459
460 int be_migrate_thread_to_cpu(pid_t tid, int target_cpu)
461 @@ -89,44 +106,29 @@ int be_migrate_thread_to_cpu(pid_t tid, int target_cpu)
462 return ret;
463 }
464
465 -int be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz)
466 -{
467 - return __be_migrate_thread_to_cluster(tid, cluster, cluster_sz, 0);
468 -}
469 -
470 -int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz,
471 - int ignore_rm)
472 +int be_migrate_thread_to_domain(pid_t tid, int domain)
473 {
474 - int first_cpu = cluster * cluster_sz; /* first CPU in cluster */
475 - int last_cpu = first_cpu + cluster_sz - 1;
476 - int master;
477 - int num_cpus;
478 + int ret, num_cpus;
479 cpu_set_t *cpu_set;
480 size_t sz;
481 - int i;
482 - int ret;
483 + unsigned long long int mask;
484
485 - /* TODO: Error check to make sure that tid is not a real-time task. */
486 + ret = domain_to_cpus(domain, &mask);
487 + if (ret != 0)
488 + return ret;
489
490 - if (cluster_sz == 1) {
491 - /* we're partitioned */
492 - return be_migrate_thread_to_partition(tid, cluster);
493 - }
494 -
495 - master = (ignore_rm) ? -1 : release_master();
496 num_cpus = num_online_cpus();
497 -
498 - if (num_cpus == -1 || last_cpu >= num_cpus || first_cpu < 0)
499 + if (num_cpus == -1)
500 return -1;
501
502 cpu_set = CPU_ALLOC(num_cpus);
503 sz = CPU_ALLOC_SIZE(num_cpus);
504 CPU_ZERO_S(sz, cpu_set);
505
506 - for (i = first_cpu; i <= last_cpu; ++i) {
507 - if (i != master) {
508 - CPU_SET_S(i, sz, cpu_set);
509 - }
510 + while(mask) {
511 + int idx = ffsll(mask) - 1;
512 + CPU_SET_S(idx, sz, cpu_set);
513 + mask &= ~(1ull<<idx);
514 }
515
516 /* apply to caller */
517 @@ -140,23 +142,12 @@ int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz,
518 return ret;
519 }
520
521 -int be_migrate_thread_to_partition(pid_t tid, int partition)
522 -{
523 - return be_migrate_thread_to_cpu(tid, partition_to_cpu(partition));
524 -}
525 -
526 -
527 int be_migrate_to_cpu(int target_cpu)
528 {
529 return be_migrate_thread_to_cpu(0, target_cpu);
530 }
531
532 -int be_migrate_to_cluster(int cluster, int cluster_sz)
533 -{
534 - return be_migrate_thread_to_cluster(0, cluster, cluster_sz);
535 -}
536 -
537 -int be_migrate_to_partition(int partition)
538 +int be_migrate_to_domain(int domain)
539 {
540 - return be_migrate_thread_to_partition(0, partition);
541 + return be_migrate_thread_to_domain(0, domain);
542 }
543 diff --git a/src/task.c b/src/task.c
544 index 5f2fa26..636e5fe 100644
545 --- a/src/task.c
546 +++ b/src/task.c
547 @@ -40,15 +40,16 @@ int __launch_rt_task(rt_fn_t rt_prog, void *rt_arg, rt_setup_fn_t setup,
548 return rt_task;
549 }
550
551 -int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size,
552 +int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster,
553 lt_t wcet, lt_t period, unsigned int priority, task_class_t class)
554 {
555 struct rt_task params;
556 - params.cpu = cluster_to_first_cpu(cluster, cluster_size);
557 + params.cpu = domain_to_first_cpu(cluster);
558 params.period = period;
559 params.exec_cost = wcet;
560 params.cls = class;
561 params.phase = 0;
562 + params.split = 1;
563 params.priority = priority;
564 /* enforce budget for tasks that might not use sleep_next_period() */
565 params.budget_policy = QUANTUM_ENFORCEMENT;
566 @@ -57,10 +58,10 @@ int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size,
567 (rt_setup_fn_t) set_rt_task_param, ¶ms);
568 }
569
570 -int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size,
571 +int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster,
572 lt_t wcet, lt_t period, unsigned int prio)
573 {
574 - return __create_rt_task(rt_prog, arg, cluster, cluster_size, wcet, period,
575 + return __create_rt_task(rt_prog, arg, cluster, wcet, period,
576 prio, RT_CLASS_HARD);
577 }
578
579 --
580 1.7.10.4
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.