aboutsummaryrefslogtreecommitdiffstats
path: root/bin/rt_launch_edffm.c
blob: ddde7dd1a0a16b5480f897614d33948e94649e5a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <signal.h>

#include "litmus.h"
#include "common.h"

typedef struct {
	int  wait;
	char * exec_path;
	char ** argv;
} startup_info_t;


int launch(void *task_info_p) {
	startup_info_t *info = (startup_info_t*) task_info_p;
	int ret;
	if (info->wait) {
		ret = wait_for_ts_release();
		if (ret != 0)
			perror("wait_for_ts_release()");
	}
	ret = execvp(info->exec_path, info->argv);
	perror("execv failed");
	return ret;
}

void usage(char *error) {
	fprintf(stderr, "%s\nUsage: rt_launch [-w][-v][-p cpu][-c hrt | srt | be] wcet period"
			" fracnum1 fracden1 cpu1 fracnum2 fracden2 cpu2 program [arg1 arg2 ...]\n"
			"\t-w\tSynchronous release\n"
			"\t-v\tVerbose\n"
			"\t-p\tcpu (or initial cpu)\n"
			"\t-c\tClass\n"
			"\twcet, period in ms\n"
			"\tprogram to be launched\n",
			error);
	exit(1);
}


#define OPTSTR "p:c:vw"

int main(int argc, char** argv) 
{
	int ret;
	lt_t wcet;
	lt_t period;
	/* [num,den] */
	lt_t frac1[2], frac2[2];
	int cpu1, cpu2;
	int migrate = 0;
	int cpu = 0;
	int opt;
	int verbose = 0;
	int wait = 0;
	startup_info_t info;
	task_class_t class = RT_CLASS_HARD;

	while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
		switch (opt) {
		case 'w':
			wait = 1;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'p':
			cpu = atoi(optarg);
			migrate = 1;
			break;
		case 'c':
			class = str2class(optarg);
			if (class == -1)
				usage("Unknown task class.");
			break;

		case ':':
			usage("Argument missing.");
			break;
		case '?':
		default:
			usage("Bad argument.");
			break;
		}
	}

	signal(SIGUSR1, SIG_IGN);

	if (argc - optind < 8)
		usage("Arguments missing.");
	wcet   = ms2lt(atoi(argv[optind + 0]));
	period = ms2lt(atoi(argv[optind + 1]));
	/* frac num, den = 0 means fixed task */
	frac1[0]  = atoi(argv[optind + 2]);
	frac1[1]  = atoi(argv[optind + 3]);
	cpu1 	  = atoi(argv[optind + 4]);
	frac2[0]  = atoi(argv[optind + 5]);
	frac2[1]  = atoi(argv[optind + 6]);
	cpu2	  = atoi(argv[optind + 7]);
	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.");
	}
	info.exec_path = argv[optind + 8];
	info.argv      = argv + optind + 8;
	info.wait      = wait;
	if (migrate) {
		ret = be_migrate_to(cpu);
		if (ret < 0)
			bail_out("could not migrate to target partition");
	}
	/* create in src/task.c a new wrapper for the __launch_rt_task
	 * which takes the fraction and the cpus */
	ret = __create_rt_task_edffm(launch, &info, cpu, wcet, period, frac1,
			frac2, cpu1, cpu2, class);


	if (ret < 0)
		bail_out("could not create rt child process");
	else if (verbose)
		printf("%d\n", ret);

	return 0;
}