From 0a54a84457bb8a33113c7dd2a2b63b2a837cc92e Mon Sep 17 00:00:00 2001 From: Glenn Elliott Date: Tue, 5 Mar 2013 18:32:01 -0500 Subject: Cluster-aware rtspin and rt_launch. This patch adds cluster scheduling options to rtspin and rt_launch. The convenience routines in litmus.h were also updated to facilitate clustered scheduling. For partitioned scheduling, just set cluster_size = 1 (default size for rtspin and rt_launch). --- bin/rt_launch.c | 22 ++++++++++++++-------- bin/rtspin.c | 24 ++++++++++++------------ include/litmus.h | 36 +++++++++++++++++++++++++----------- src/litmus.c | 17 +++++++++-------- src/task.c | 14 ++++++++------ 5 files changed, 68 insertions(+), 45 deletions(-) diff --git a/bin/rt_launch.c b/bin/rt_launch.c index 97d9df9..ae68601 100644 --- a/bin/rt_launch.c +++ b/bin/rt_launch.c @@ -29,10 +29,11 @@ int launch(void *task_info_p) { } void usage(char *error) { - fprintf(stderr, "%s\nUsage: rt_launch [-w][-v][-p cpu][-q prio][-c hrt | srt | be] wcet period program [arg1 arg2 ...]\n" + fprintf(stderr, "%s\nUsage: rt_launch [-w][-v][-p partition/cluster [-z cluster size]][-q prio][-c hrt | srt | be] wcet period program [arg1 arg2 ...]\n" "\t-w\tSynchronous release\n" "\t-v\tVerbose\n" - "\t-p\tcpu (or initial cpu)\n" + "\t-p\tpartition or cluster\n" + "\t-z\tsize of cluster (default = 1 for partitioned)\n" "\t-c\tClass\n" "\twcet, period in ms\n" "\tprogram to be launched\n", @@ -41,7 +42,7 @@ void usage(char *error) { } -#define OPTSTR "p:c:vwq:" +#define OPTSTR "p:z:c:vwq:" int main(int argc, char** argv) { @@ -49,7 +50,8 @@ int main(int argc, char** argv) lt_t wcet; lt_t period; int migrate = 0; - int cpu = 0; + int cluster = 0; + int cluster_size = 1; int opt; int verbose = 0; int wait = 0; @@ -66,9 +68,12 @@ int main(int argc, char** argv) verbose = 1; break; case 'p': - cpu = atoi(optarg); + cluster = atoi(optarg); migrate = 1; break; + case 'z': + cluster_size = atoi(optarg); + break; case 'q': priority = atoi(optarg); if (!litmus_is_valid_fixed_prio(priority)) @@ -109,11 +114,12 @@ int main(int argc, char** argv) info.argv = argv + optind + 2; info.wait = wait; if (migrate) { - ret = be_migrate_to_cpu(cpu); + ret = be_migrate_to_cluster(cluster, cluster_size); if (ret < 0) - bail_out("could not migrate to target partition"); + bail_out("could not migrate to target partition or cluster"); } - ret = __create_rt_task(launch, &info, cpu, wcet, period, priority, class); + ret = __create_rt_task(launch, &info, cluster, cluster_size, wcet, period, + priority, class); if (ret < 0) diff --git a/bin/rtspin.c b/bin/rtspin.c index 5f12930..b05c17c 100644 --- a/bin/rtspin.c +++ b/bin/rtspin.c @@ -21,7 +21,8 @@ static void usage(char *error) { " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" " rt_spin -l\n" "\n" - "COMMON-OPTS = [-w] [-p PARTITION] [-c CLASS] [-s SCALE]\n" + "COMMON-OPTS = [-w] [-s SCALE]\n" + " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS]\n" " [-X LOCKING-PROTOCOL] [-L CRITICAL SECTION LENGTH] [-Q RESOURCE-ID]" "\n" "WCET and PERIOD are milliseconds, DURATION is seconds.\n" @@ -183,7 +184,7 @@ static int job(double exec_time, double program_end, int lock_od, double cs_leng } } -#define OPTSTR "p:c:wlveo:f:s:q:X:L:Q:" +#define OPTSTR "p:z:c:wlveo:f:s:q:X:L:Q:" int main(int argc, char** argv) { @@ -193,7 +194,8 @@ int main(int argc, char** argv) double wcet_ms, period_ms; unsigned int priority = LITMUS_LOWEST_PRIORITY; int migrate = 0; - int cpu = 0; + int cluster = 0; + int cluster_size = 1; int opt; int wait = 0; int test_loop = 0; @@ -221,9 +223,12 @@ int main(int argc, char** argv) wait = 1; break; case 'p': - cpu = atoi(optarg); + cluster = atoi(optarg); migrate = 1; break; + case 'z': + cluster_size = atoi(optarg); + break; case 'q': priority = atoi(optarg); if (!litmus_is_valid_fixed_prio(priority)) @@ -320,13 +325,8 @@ int main(int argc, char** argv) else if (file && num_jobs > 1) duration += period_ms * 0.001 * (num_jobs - 1); - if (migrate) { - ret = be_migrate_to_cpu(cpu); - if (ret < 0) - bail_out("could not migrate to target partition"); - } - - ret = sporadic_task_ns(wcet, period, 0, cpu, priority, class, + ret = sporadic_task_ns(wcet, period, 0, cluster, cluster_size, + priority, class, want_enforcement ? PRECISE_ENFORCEMENT : NO_ENFORCEMENT, migrate); @@ -341,7 +341,7 @@ int main(int argc, char** argv) if (protocol >= 0) { /* open reference to semaphore */ - lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cpu); + lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cluster); if (lock_od < 0) { perror("litmus_open_lock"); usage("Could not open lock."); diff --git a/include/litmus.h b/include/litmus.h index b2e81f2..335d01b 100644 --- a/include/litmus.h +++ b/include/litmus.h @@ -21,6 +21,13 @@ extern "C" { int set_rt_task_param(pid_t pid, struct rt_task* param); int get_rt_task_param(pid_t pid, struct rt_task* param); +/* Release-master-aware functions for getting the first + * CPU in a particular cluster or partition. Use these + * to set rt_task::cpu for cluster/partitioned scheduling. + */ +int partition_to_cpu(int partition); +int cluster_to_first_cpu(int cluster, int cluster_size); + /* setup helper */ /* Times are given in ms. The 'priority' parameter @@ -30,9 +37,9 @@ int get_rt_task_param(pid_t pid, struct rt_task* param); */ int sporadic_task( lt_t e, lt_t p, lt_t phase, - int partition, unsigned int priority, + int cluster, int cluster_size, unsigned int priority, task_class_t cls, - budget_policy_t budget_policy, int set_cpu_set); + budget_policy_t budget_policy, int be_migrate); /* Times are given in ns. The 'priority' parameter * is only relevant under fixed-priority scheduling (and @@ -41,16 +48,19 @@ int sporadic_task( */ int sporadic_task_ns( lt_t e, lt_t p, lt_t phase, - int cpu, unsigned int priority, + int cluster, int cluster_size, unsigned int priority, task_class_t cls, - budget_policy_t budget_policy, int set_cpu_set); + budget_policy_t budget_policy, int be_migrate); /* Convenience macros. Budget enforcement off by default in these macros. */ #define sporadic_global(e, p) \ - sporadic_task(e, p, 0, 0, LITMUS_LOWEST_PRIORITY, \ + sporadic_task(e, p, 0, 0, 0, LITMUS_LOWEST_PRIORITY, \ RT_CLASS_SOFT, NO_ENFORCEMENT, 0) -#define sporadic_partitioned(e, p, cpu) \ - sporadic_task(e, p, 0, cpu, LITMUS_LOWEST_PRIORITY, \ +#define sporadic_partitioned(e, p, partition) \ + sporadic_task(e, p, 0, partition, 1, LITMUS_LOWEST_PRIORITY, \ + RT_CLASS_SOFT, NO_ENFORCEMENT, 1) +#define sporadic_clustered(e, p, cluster, cluster_size) \ + sporadic_task(e, p, 0, cluster, cluster_size, LITMUS_LOWEST_PRIORITY, \ RT_CLASS_SOFT, NO_ENFORCEMENT, 1) /* file descriptor attached shared objects support */ @@ -98,10 +108,14 @@ void exit_litmus(void); /* A real-time program. */ typedef int (*rt_fn_t)(void*); -/* These two functions configure the RT task to use enforced exe budgets */ -int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, lt_t wcet, lt_t period, unsigned int prio); -int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, lt_t wcet, - lt_t period, unsigned int priority, task_class_t cls); +/* These two functions configure the RT task to use enforced exe budgets. + * Partitioned scheduling: cluster = desired partition, cluster_size = 1 + * Global scheduling: cluster = 0, cluster_size = 0 + */ +int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, + lt_t wcet, lt_t period, unsigned int prio); +int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, + lt_t wcet, lt_t period, unsigned int prio, task_class_t cls); /* per-task modes */ enum rt_task_mode_t { diff --git a/src/litmus.c b/src/litmus.c index b774c63..1110bd4 100644 --- a/src/litmus.c +++ b/src/litmus.c @@ -92,18 +92,19 @@ task_class_t str2class(const char* str) #define NS_PER_MS 1000000 int sporadic_task(lt_t e, lt_t p, lt_t phase, - int cpu, unsigned int priority, + int cluster, int cluster_size, unsigned int priority, task_class_t cls, budget_policy_t budget_policy, int set_cpu_set) { return sporadic_task_ns(e * NS_PER_MS, p * NS_PER_MS, phase * NS_PER_MS, - cpu, priority, cls, budget_policy, set_cpu_set); + cluster, cluster_size, priority, cls, + budget_policy, set_cpu_set); } int sporadic_task_ns(lt_t e, lt_t p, lt_t phase, - int cpu, unsigned int priority, + int cluster, int cluster_size, unsigned int priority, task_class_t cls, - budget_policy_t budget_policy, int set_cpu_set) + budget_policy_t budget_policy, int migrate) { struct rt_task param; int ret; @@ -116,15 +117,15 @@ int sporadic_task_ns(lt_t e, lt_t p, lt_t phase, param.exec_cost = e; param.period = p; param.relative_deadline = p; /* implicit deadline */ - param.cpu = cpu; + param.cpu = cluster_to_first_cpu(cluster, cluster_size); param.cls = cls; param.phase = phase; param.budget_policy = budget_policy; param.priority = priority; - if (set_cpu_set) { - ret = be_migrate_to_cpu(cpu); - check("migrate to cpu"); + if (migrate) { + ret = be_migrate_to_cluster(cluster, cluster_size); + check("migrate to cluster"); } return set_rt_task_param(gettid(), ¶m); } diff --git a/src/task.c b/src/task.c index ed1c6aa..9121f0c 100644 --- a/src/task.c +++ b/src/task.c @@ -40,11 +40,11 @@ int __launch_rt_task(rt_fn_t rt_prog, void *rt_arg, rt_setup_fn_t setup, return rt_task; } -int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, lt_t wcet, lt_t period, - unsigned int priority, task_class_t class) +int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, + lt_t wcet, lt_t period, unsigned int priority, task_class_t class) { struct rt_task params; - params.cpu = cpu; + params.cpu = cluster_to_first_cpu(cluster, cluster_size); params.period = period; params.exec_cost = wcet; params.cls = class; @@ -57,9 +57,11 @@ int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, lt_t wcet, lt_t period (rt_setup_fn_t) set_rt_task_param, ¶ms); } -int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, lt_t wcet, lt_t period, - unsigned int priority) { - return __create_rt_task(rt_prog, arg, cpu, wcet, period, priority, RT_CLASS_HARD); +int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, + lt_t wcet, lt_t period, unsigned int prio) +{ + return __create_rt_task(rt_prog, arg, cluster, cluster_size, wcet, period, + prio, RT_CLASS_HARD); } -- cgit v1.2.2