#include #include #include #include #include #include #include #include #include #include "litmus.h" #include "common.h" #define __NR_request_mode 408 #define __NR_enact_mode 409 int main_job(void){ return syscall(__NR_enact_mode); } static char* progname; static void usage(char *error) { fprintf(stderr, "Error: %s\n", error); fprintf(stderr, "Usage:\n" " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" " rt_spin -l\n" "\n" "COMMON-OPTS = [-w] [-s SCALE]\n" " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" "\n" "WCET and PERIOD are microseconds, DURATION is seconds.\n"); exit(EXIT_FAILURE); } static int job(double program_end) { if (wctime() > program_end) return 0; else { main_job(); sleep_next_period(); return 1; } } #define OPTSTR "p:wvel:b:k:" int main(int argc, char** argv) { int ret; lt_t wcet; lt_t period; lt_t budget; double wcet_ms, period_ms, budget_ms; unsigned int priority = 0; //guarantee highest priority to this task int migrate = 0; int cluster = 0; int opt; int wait = 0; int want_enforcement = 0; task_class_t class = RT_CLASS_HARD; struct rt_task param; struct mc2_task mc2_param; struct reservation_config config; int res_type = PERIODIC_POLLING; uint32_t mode_mask = (1 << 0); int i; double duration = 0, start = 0; struct control_page* ctl_page = NULL; progname = argv[0]; /* default for reservation */ config.id = 0; config.priority = 1; config.cpu = -1; mc2_param.crit = CRIT_LEVEL_A; budget_ms = 10; while ((opt = getopt(argc, argv, OPTSTR)) != -1) { switch (opt) { case 'w': wait = 1; break; case 'p': cluster = atoi(optarg); migrate = 1; config.cpu = cluster; break; case 'e': want_enforcement = 1; break; case 'b': budget_ms = atof(optarg); break; case 'k': mode_mask = atoi(optarg); break; case ':': usage("Argument missing."); break; case '?': default: usage("Bad argument."); break; } } if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) usage("Bad criticailty level or priority"); if (argc - optind < 2) usage("Arguments missing."); wcet_ms = atof(argv[optind + 0]); period_ms = atof(argv[optind + 1]); wcet = ms2ns(wcet_ms); period = ms2ns(period_ms); budget = ms2ns(budget_ms); if (wcet <= 0) usage("The worst-case execution time must be a " "positive number."); if (period <= 0) usage("The period must be a positive number."); if (wcet > period) { usage("The worst-case execution time must not " "exceed the period."); } duration = atof(argv[optind + 2]); if (migrate) { ret = be_migrate_to_domain(cluster); if (ret < 0) bail_out("could not migrate to target partition or cluster."); } else{ bail_out("rt_mode_poll must be migrated."); } /* reservation config */ config.id = gettid(); config.polling_params.budget = budget; config.polling_params.period = period; config.polling_params.offset = 0; config.polling_params.relative_deadline = 0; if (config.polling_params.budget > config.polling_params.period) { usage("The budget must not exceed the period."); } /* create reservation's */ for( i = 0; i < 32; i++){ if ( !( (1 << i) & mode_mask ) ) continue; config.mode = i; ret = reservation_create(res_type, &config); if (ret < 0) { bail_out("failed to create reservation."); } } init_rt_task_param(¶m); param.exec_cost = wcet; param.period = period; param.priority = priority; param.cls = class; param.release_policy = TASK_PERIODIC; param.budget_policy = (want_enforcement) ? PRECISE_ENFORCEMENT : NO_ENFORCEMENT; if (migrate) { param.cpu = gettid(); } ret = set_rt_task_param(gettid(), ¶m); if (ret < 0) bail_out("could not setup rt task params"); mc2_param.res_id = gettid(); mc2_param.mode_mask = mode_mask; ret = set_mc2_task_param(gettid(), &mc2_param); if (ret < 0) bail_out("could not setup mc2 task params"); init_litmus(); ctl_page = get_ctrl_page(); if (!ctl_page) bail_out("could not get ctrl_page"); ctl_page->mode_poll_task = 1; start = wctime(); ret = task_mode(LITMUS_RT_TASK); if (ret != 0) bail_out("could not become RT task"); set_page_color(config.cpu); if (wait) { ret = wait_for_ts_release(); if (ret != 0) bail_out("wait_for_ts_release()"); start = wctime(); } while (job(start + duration)) {}; ret = task_mode(BACKGROUND_TASK); if (ret != 0) bail_out("could not become regular task (huh?)"); reservation_destroy(gettid(), config.cpu); return 0; }