blob: d05521c79eeaef05190160b216f1558db8055c3c (
plain) (
tree)
|
|
#include <sys/time.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#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;
}
|