diff options
author | Bjoern B. Brandenburg <bbb@jupiter-cs.cs.unc.edu> | 2007-02-05 18:31:20 -0500 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@jupiter-cs.cs.unc.edu> | 2007-02-05 18:31:20 -0500 |
commit | b32b21bd57b21b249447e2944c4473e0d196bb4f (patch) | |
tree | fea9e8712fbc97f30003065074a1ff180f3e1de4 |
liblitmus essential tools
liblitmus should consist only of the litmus library and the essential
tools.
-rw-r--r-- | Makefile | 28 | ||||
-rw-r--r-- | edf-hsb.c | 48 | ||||
-rw-r--r-- | edf-hsb.h | 10 | ||||
-rw-r--r-- | hrt.c | 78 | ||||
-rw-r--r-- | iotest.c | 74 | ||||
-rw-r--r-- | litmus.c | 188 | ||||
-rw-r--r-- | litmus.h | 80 | ||||
-rw-r--r-- | rt_launch.c | 83 | ||||
-rw-r--r-- | run.c | 7 | ||||
-rw-r--r-- | set_rt_mode.c | 22 | ||||
-rw-r--r-- | show_scheduler.c | 11 | ||||
-rw-r--r-- | timeout.c | 36 |
12 files changed, 665 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5157fdf --- /dev/null +++ b/Makefile | |||
@@ -0,0 +1,28 @@ | |||
1 | CFLAGS=-Wall -g | ||
2 | CPPFLAGS=-Wall -g | ||
3 | |||
4 | |||
5 | all: showsched iotest set_rt_mode run timeout rt_launch edfhsb | ||
6 | |||
7 | |||
8 | iotest: iotest.o litmus.h litmus.o | ||
9 | cc -static -o iotest litmus.o iotest.o | ||
10 | |||
11 | run: run.o | ||
12 | cc -o run run.o | ||
13 | |||
14 | set_rt_mode: litmus.o set_rt_mode.o | ||
15 | cc -o set_rt_mode litmus.o set_rt_mode.o | ||
16 | |||
17 | showsched: show_scheduler.o litmus.o litmus.h | ||
18 | cc -o showsched show_scheduler.o litmus.o | ||
19 | |||
20 | timeout: litmus.o timeout.o litmus.h | ||
21 | cc -static -o timeout litmus.o timeout.o | ||
22 | |||
23 | rt_launch: litmus.o litmus.h rt_launch.o | ||
24 | cc -static -o rt_launch litmus.o rt_launch.o | ||
25 | |||
26 | edfhsb: litmus.o edf-hsb.o litmus.h edf-hsb.h hrt.o | ||
27 | cc -o edfhsb hrt.o litmus.o edf-hsb.o | ||
28 | |||
diff --git a/edf-hsb.c b/edf-hsb.c new file mode 100644 index 0000000..9ace2ca --- /dev/null +++ b/edf-hsb.c | |||
@@ -0,0 +1,48 @@ | |||
1 | #include "litmus.h" | ||
2 | #include "edf-hsb.h" | ||
3 | |||
4 | |||
5 | typedef enum { | ||
6 | EDF_HSB_SET_HRT, | ||
7 | EDF_HSB_GET_HRT, | ||
8 | EDF_HSB_CREATE_BE | ||
9 | } edf_hsb_setup_cmds_t; | ||
10 | |||
11 | typedef struct { | ||
12 | int cpu; | ||
13 | unsigned int wcet; | ||
14 | unsigned int period; | ||
15 | } setup_hrt_param_t; | ||
16 | |||
17 | typedef struct { | ||
18 | unsigned int wcet; | ||
19 | unsigned int period; | ||
20 | } create_be_param_t; | ||
21 | |||
22 | int set_hrt(int cpu, unsigned int wcet, unsigned int period) | ||
23 | { | ||
24 | setup_hrt_param_t param; | ||
25 | param.cpu = cpu; | ||
26 | param.wcet = wcet; | ||
27 | param.period = period; | ||
28 | return scheduler_setup(EDF_HSB_SET_HRT, ¶m); | ||
29 | } | ||
30 | |||
31 | int get_hrt(int cpu, unsigned int *wcet, unsigned int *period) | ||
32 | { | ||
33 | setup_hrt_param_t param; | ||
34 | int ret; | ||
35 | param.cpu = cpu; | ||
36 | ret = scheduler_setup(EDF_HSB_GET_HRT, ¶m); | ||
37 | *wcet = param.wcet; | ||
38 | *period = param.period; | ||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | int create_be(unsigned int wcet, unsigned int period) | ||
43 | { | ||
44 | create_be_param_t param; | ||
45 | param.wcet = wcet; | ||
46 | param.period = period; | ||
47 | return scheduler_setup(EDF_HSB_CREATE_BE, ¶m); | ||
48 | } | ||
diff --git a/edf-hsb.h b/edf-hsb.h new file mode 100644 index 0000000..0ac3d4f --- /dev/null +++ b/edf-hsb.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef EDF_HSB_H | ||
2 | #define EDF_HSB_H | ||
3 | |||
4 | |||
5 | int set_hrt(int cpu, unsigned int wcet, unsigned int period); | ||
6 | int get_hrt(int cpu, unsigned int *wcet, unsigned int *period); | ||
7 | int create_be(unsigned int wcet, unsigned int period); | ||
8 | |||
9 | |||
10 | #endif | ||
@@ -0,0 +1,78 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | |||
5 | #include "edf-hsb.h" | ||
6 | |||
7 | |||
8 | void usage(char *name) | ||
9 | { | ||
10 | fprintf(stderr, | ||
11 | "EDF-HSB server setup utility\n" | ||
12 | "Usage: %s hrt show <#cpu>\n" | ||
13 | " %s hrt set <#cpu> <wcet> <period>\n" | ||
14 | " %s be create <wcet> <period>\n", | ||
15 | name, name, name); | ||
16 | exit(1); | ||
17 | } | ||
18 | |||
19 | |||
20 | int hrt(int argc, char** argv) | ||
21 | { | ||
22 | int wcet, period, cpu; | ||
23 | |||
24 | if (argc == 2 && !strcmp(argv[0], "show")) { | ||
25 | cpu = atoi(argv[1]); | ||
26 | if (!get_hrt(cpu, &wcet, &period)) | ||
27 | printf("HRT/%d = (%d, %d)\n", cpu, wcet, period); | ||
28 | else | ||
29 | perror("cannot read HRT settings"); | ||
30 | } else if (argc == 4 && !strcmp(argv[0], "set")) { | ||
31 | cpu = atoi(argv[1]); | ||
32 | wcet = atoi(argv[2]); | ||
33 | period = atoi(argv[3]); | ||
34 | printf("Setting HRT/%d to (%d, %d)", cpu, wcet, period); | ||
35 | if (!set_hrt(cpu, wcet, period)) | ||
36 | printf(" OK.\n"); | ||
37 | else { | ||
38 | printf("\n"); | ||
39 | perror("cannot write HRT settings"); | ||
40 | } | ||
41 | } else | ||
42 | return 1; | ||
43 | |||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | int be(int argc, char** argv) | ||
48 | { | ||
49 | int wcet, period; | ||
50 | if (argc == 3 && !strcmp(argv[0], "create")) { | ||
51 | wcet = atoi(argv[1]); | ||
52 | period = atoi(argv[2]); | ||
53 | printf("Creating BE with (%d, %d)", wcet, period); | ||
54 | if (!create_be(wcet, period)) | ||
55 | printf(" OK.\n"); | ||
56 | else { | ||
57 | printf("\n"); | ||
58 | perror("cannot create BE server"); | ||
59 | } | ||
60 | return 0; | ||
61 | } | ||
62 | else | ||
63 | return 1; | ||
64 | } | ||
65 | |||
66 | int main(int argc, char** argv) | ||
67 | { | ||
68 | int ret = 1; | ||
69 | if (argc > 1) { | ||
70 | if (!strcmp(argv[1], "hrt")) | ||
71 | ret = hrt(argc - 2, argv + 2); | ||
72 | else if (!strcmp(argv[1], "be")) | ||
73 | ret = be(argc - 2, argv + 2); | ||
74 | } | ||
75 | if (ret) | ||
76 | usage(argv[0]); | ||
77 | return ret; | ||
78 | } | ||
diff --git a/iotest.c b/iotest.c new file mode 100644 index 0000000..ac07e74 --- /dev/null +++ b/iotest.c | |||
@@ -0,0 +1,74 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <signal.h> | ||
4 | #include <unistd.h> | ||
5 | #include <sys/time.h> | ||
6 | #include <sys/wait.h> | ||
7 | |||
8 | #include "litmus.h" | ||
9 | |||
10 | #define US_PER_MS 1000 | ||
11 | |||
12 | int iotest(void *nil) { | ||
13 | int id = getpid(); | ||
14 | FILE* file; | ||
15 | char str[255]; | ||
16 | unsigned long last = 0; | ||
17 | struct timeval time; | ||
18 | |||
19 | printf("I'am real time task %d doing IO!\n", id); | ||
20 | snprintf(str, sizeof(str), "rt-io-%d.txt", id); | ||
21 | file = fopen(str, "w"); | ||
22 | if (!file) { | ||
23 | perror("could not open file for output"); | ||
24 | exit(1); | ||
25 | } | ||
26 | while (1) { | ||
27 | gettimeofday(&time, NULL); | ||
28 | if (time.tv_usec - last > US_PER_MS) { | ||
29 | fprintf(file, "ran at %lus %lums\n", time.tv_sec, time.tv_usec / US_PER_MS); | ||
30 | last = time.tv_usec; | ||
31 | } | ||
32 | fflush(file); | ||
33 | } | ||
34 | return id; | ||
35 | } | ||
36 | |||
37 | #define NUMTASKS 4 | ||
38 | |||
39 | int main(int argc, char** argv) | ||
40 | { | ||
41 | int rt_task[NUMTASKS]; | ||
42 | int i; | ||
43 | int ret, pid; | ||
44 | |||
45 | for (i = 0; i < NUMTASKS; i++) { | ||
46 | /* func arg cpu wcet period */ | ||
47 | rt_task[i] = create_rt_task(iotest, NULL, 0, 25, 100); | ||
48 | if (rt_task[i] < 0) { | ||
49 | perror("Could not create rt child process"); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | sync(); | ||
54 | sync(); | ||
55 | |||
56 | printf(":: Starting real-time mode.\n"); | ||
57 | set_rt_mode(MODE_RT_RUN); | ||
58 | |||
59 | printf(":: Sleeping...\n"); | ||
60 | sleep(120); | ||
61 | |||
62 | printf("Killing real-time tasks.\n"); | ||
63 | for (i = 0; i < NUMTASKS; i++) { | ||
64 | printf(":: sending SIGKILL to %d\n", rt_task[i]); | ||
65 | kill(rt_task[i], SIGKILL); | ||
66 | } | ||
67 | for (i = 0; i < NUMTASKS; i++) { | ||
68 | pid = wait(&ret); | ||
69 | printf(":: %d exited with status %d\n", pid, ret); | ||
70 | } | ||
71 | printf(":: Leaving real-time mode.\n"); | ||
72 | set_rt_mode(MODE_NON_RT); | ||
73 | return 0; | ||
74 | } | ||
diff --git a/litmus.c b/litmus.c new file mode 100644 index 0000000..6f4aa18 --- /dev/null +++ b/litmus.c | |||
@@ -0,0 +1,188 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <stdio.h> | ||
3 | #include <string.h> | ||
4 | #include <sys/types.h> | ||
5 | #include <unistd.h> | ||
6 | #include <errno.h> | ||
7 | #include <signal.h> | ||
8 | |||
9 | #include "litmus.h" | ||
10 | |||
11 | /* this is missing in newer linux/unistd.h versions */ | ||
12 | |||
13 | #define _syscall0(type,name) \ | ||
14 | type name(void) \ | ||
15 | {\ | ||
16 | return syscall(__NR_##name);\ | ||
17 | } | ||
18 | |||
19 | #define _syscall1(type,name,type1,arg1) \ | ||
20 | type name(type1 arg1) \ | ||
21 | {\ | ||
22 | return syscall(__NR_##name, arg1);\ | ||
23 | } | ||
24 | |||
25 | |||
26 | #define _syscall2(type,name,type1,arg1,type2,arg2) \ | ||
27 | type name(type1 arg1,type2 arg2) \ | ||
28 | {\ | ||
29 | return syscall(__NR_##name, arg1, arg2);\ | ||
30 | } | ||
31 | |||
32 | |||
33 | /* clear the TID in the child */ | ||
34 | #define CLONE_CHILD_CLEARTID 0x00200000 | ||
35 | /* set the TID in the child */ | ||
36 | #define CLONE_CHILD_SETTID 0x01000000 | ||
37 | /* don't let the child run before we have completed setup */ | ||
38 | #define CLONE_STOPPED 0x02000000 | ||
39 | /* litmus clone flag */ | ||
40 | #define CLONE_REALTIME 0x10000000 | ||
41 | |||
42 | /* CLONE_REALTIME is necessary because CLONE_STOPPED will put a SIGSTOP in | ||
43 | * the pending signal queue. Thus the first thing a newly created task will | ||
44 | * do after it is released is to stop, which is not what we want | ||
45 | * | ||
46 | * CLONE_REALTIME just sets the status to TASK_STOPPED without queueing a | ||
47 | * signal. | ||
48 | */ | ||
49 | |||
50 | |||
51 | /* this is essentially a fork with CLONE_STOPPED */ | ||
52 | /* #define CLONE_LITMUS CLONE_STOPPED | CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID */ | ||
53 | #define CLONE_LITMUS CLONE_REALTIME | CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | ||
54 | |||
55 | /* we need to override libc because it wants to be clever | ||
56 | * and rejects our call without presenting it even to the kernel | ||
57 | */ | ||
58 | #define __NR_raw_clone 120 | ||
59 | |||
60 | |||
61 | _syscall2(int, raw_clone, unsigned long, flags, unsigned long, child_stack) | ||
62 | |||
63 | |||
64 | const char* get_scheduler_name(spolicy scheduler) | ||
65 | { | ||
66 | const char* name; | ||
67 | |||
68 | switch (scheduler){ | ||
69 | case SCHED_LINUX : | ||
70 | name = "Linux"; | ||
71 | break; | ||
72 | case SCHED_PFAIR: | ||
73 | name = "Pfair"; | ||
74 | break; | ||
75 | case SCHED_PFAIR_STAGGER: | ||
76 | name = "Pfair (staggered)"; | ||
77 | break; | ||
78 | case SCHED_PART_EDF: | ||
79 | name = "Partioned EDF"; | ||
80 | break; | ||
81 | case SCHED_PART_EEVDF: | ||
82 | name = "Partioned EEVDF"; | ||
83 | break; | ||
84 | case SCHED_GLOBAL_EDF: | ||
85 | name = "Global EDF"; | ||
86 | break; | ||
87 | case SCHED_EDF_HSB: | ||
88 | name = "EDF-HSB"; | ||
89 | break; | ||
90 | default: | ||
91 | name = "Unkown"; | ||
92 | break; | ||
93 | } | ||
94 | return name; | ||
95 | } | ||
96 | |||
97 | int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period) { | ||
98 | return __create_rt_task(rt_prog, arg, cpu, wcet, period, RT_CLASS_HARD); | ||
99 | } | ||
100 | |||
101 | int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period, | ||
102 | task_class_t class) | ||
103 | { | ||
104 | int ret; | ||
105 | rt_param_t params; | ||
106 | int rt_task = raw_clone(CLONE_LITMUS, 0); | ||
107 | |||
108 | if (rt_task < 0) | ||
109 | return rt_task; | ||
110 | |||
111 | if (rt_task > 0) { | ||
112 | /* we are the controller task */ | ||
113 | params.period = period; | ||
114 | params.exec_cost = wcet; | ||
115 | params.cpu = cpu; | ||
116 | params.cls = class; | ||
117 | ret = set_rt_task_param(rt_task, ¶ms); | ||
118 | if (ret < 0) { | ||
119 | /* we have a problem: we created the task but | ||
120 | * for some stupid reason we cannot set the real-time | ||
121 | * parameters. We must clean up the stopped task. | ||
122 | */ | ||
123 | kill(rt_task, SIGKILL); | ||
124 | /* syscall will have set errno, we don't have to do | ||
125 | * anything | ||
126 | */ | ||
127 | return -1; | ||
128 | } | ||
129 | ret = prepare_rt_task(rt_task); | ||
130 | if (ret < 0) { | ||
131 | /* same problem as above*/ | ||
132 | //kill(rt_task, SIGKILL); | ||
133 | rt_task = -1; | ||
134 | } | ||
135 | return rt_task; | ||
136 | } | ||
137 | else { | ||
138 | /* we are the real-time task | ||
139 | * launch task and die when it is done | ||
140 | */ | ||
141 | |||
142 | exit(rt_prog(arg)); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | |||
147 | void show_rt_param(rt_param_t* tp) | ||
148 | { | ||
149 | printf("rt params:\n\t" | ||
150 | "exec_cost:\t%ld\n\tperiod:\t\t%ld\n\tcpu:\t%d\n", | ||
151 | tp->exec_cost, tp->period, tp->cpu); | ||
152 | } | ||
153 | |||
154 | task_class_t str2class(const char* str) | ||
155 | { | ||
156 | if (!strcmp(str, "hrt")) | ||
157 | return RT_CLASS_HARD; | ||
158 | else if (!strcmp(str, "srt")) | ||
159 | return RT_CLASS_SOFT; | ||
160 | else if (!strcmp(str, "be")) | ||
161 | return RT_CLASS_BEST_EFFORT; | ||
162 | else | ||
163 | return -1; | ||
164 | } | ||
165 | |||
166 | |||
167 | /* Litmus syscalls definitions */ | ||
168 | #define __NR_sched_setpolicy 320 | ||
169 | #define __NR_sched_getpolicy 321 | ||
170 | #define __NR_set_rt_mode 322 | ||
171 | #define __NR_set_rt_task_param 323 | ||
172 | #define __NR_get_rt_task_param 324 | ||
173 | #define __NR_prepare_rt_task 325 | ||
174 | #define __NR_reset_stat 326 | ||
175 | #define __NR_sleep_next_period 327 | ||
176 | #define __NR_scheduler_setup 328 | ||
177 | |||
178 | |||
179 | /* Syscall stub for setting RT mode and scheduling options */ | ||
180 | _syscall1(spolicy, sched_setpolicy, spolicy, arg1); | ||
181 | _syscall0(spolicy, sched_getpolicy); | ||
182 | _syscall1(int, set_rt_mode, int, arg1); | ||
183 | _syscall2(int, set_rt_task_param, pid_t, pid, rt_param_t*, arg1); | ||
184 | _syscall2(int, get_rt_task_param, pid_t, pid, rt_param_t*, arg1); | ||
185 | _syscall1(int, prepare_rt_task, pid_t, pid); | ||
186 | _syscall0(int, reset_stat); | ||
187 | _syscall0(int, sleep_next_period); | ||
188 | _syscall2(int, scheduler_setup, int, cmd, void*, param); | ||
diff --git a/litmus.h b/litmus.h new file mode 100644 index 0000000..8b92383 --- /dev/null +++ b/litmus.h | |||
@@ -0,0 +1,80 @@ | |||
1 | #ifndef LITMUS_H | ||
2 | #define LITMUS_H | ||
3 | |||
4 | #include <sys/types.h> | ||
5 | |||
6 | /* This flag is needed to start new RT tasks in STOPPED state */ | ||
7 | /* Task is going to run in realtime mode */ | ||
8 | #define CLONE_REALTIME 0x10000000 | ||
9 | |||
10 | typedef int (*rt_fn_t)(void*); | ||
11 | |||
12 | /* Litmus scheduling policies */ | ||
13 | typedef enum { | ||
14 | SCHED_LINUX = 0, | ||
15 | SCHED_PFAIR = 1, | ||
16 | SCHED_PFAIR_STAGGER = 2, | ||
17 | SCHED_PART_EDF = 3, | ||
18 | SCHED_PART_EEVDF = 4, | ||
19 | SCHED_GLOBAL_EDF = 5, | ||
20 | SCHED_PFAIR_DESYNC = 6, | ||
21 | SCHED_GLOBAL_EDF_NP = 7, | ||
22 | SCHED_CUSTOM = 8, | ||
23 | SCHED_EDF_HSB = 9, | ||
24 | } spolicy; | ||
25 | |||
26 | /* different types of clients */ | ||
27 | typedef enum { | ||
28 | RT_CLASS_HARD, | ||
29 | RT_CLASS_SOFT, | ||
30 | RT_CLASS_BEST_EFFORT | ||
31 | } task_class_t; | ||
32 | |||
33 | /* Task RT params for schedulers */ | ||
34 | /* RT task parameters for scheduling extensions | ||
35 | * These parameters are inherited during clone and therefore must | ||
36 | * be explicitly set up before the task set is launched. | ||
37 | */ | ||
38 | typedef struct rt_param { | ||
39 | /* Execution cost */ | ||
40 | unsigned long exec_cost; | ||
41 | /* Period */ | ||
42 | unsigned long period; | ||
43 | /* Partition */ | ||
44 | unsigned int cpu; | ||
45 | /* type of task */ | ||
46 | task_class_t cls; | ||
47 | } rt_param_t; | ||
48 | |||
49 | #define set_param(t,p,e) do{\ | ||
50 | (t).is_realtime=1;\ | ||
51 | (t).exec_cost=(e);\ | ||
52 | (t).period=(p);\ | ||
53 | }while(0); | ||
54 | |||
55 | /* scheduler modes */ | ||
56 | #define MODE_NON_RT 0 | ||
57 | #define MODE_RT_RUN 1 | ||
58 | |||
59 | spolicy sched_setpolicy(spolicy policy); | ||
60 | spolicy sched_getpolicy(void); | ||
61 | int set_rt_mode(int mode); | ||
62 | int set_rt_task_param(pid_t pid, rt_param_t* param); | ||
63 | int get_rt_task_param(pid_t pid, rt_param_t* param); | ||
64 | int prepare_rt_task(pid_t pid); | ||
65 | int tear_down_task(pid_t pid, int sig); | ||
66 | int reset_stat(void); | ||
67 | int sleep_next_period(void); | ||
68 | int scheduler_setup(int cmd, void* param); | ||
69 | |||
70 | |||
71 | /* library functions */ | ||
72 | int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period); | ||
73 | int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, | ||
74 | int period, task_class_t cls); | ||
75 | const char* get_scheduler_name(spolicy scheduler); | ||
76 | void show_rt_param(rt_param_t* tp); | ||
77 | task_class_t str2class(const char* str); | ||
78 | |||
79 | |||
80 | #endif | ||
diff --git a/rt_launch.c b/rt_launch.c new file mode 100644 index 0000000..31e6447 --- /dev/null +++ b/rt_launch.c | |||
@@ -0,0 +1,83 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <unistd.h> | ||
4 | |||
5 | #include "litmus.h" | ||
6 | |||
7 | typedef struct { | ||
8 | char * exec_path; | ||
9 | char ** argv; | ||
10 | } startup_info_t; | ||
11 | |||
12 | |||
13 | int launch(void *task_info_p) { | ||
14 | startup_info_t *info = (startup_info_t*) task_info_p; | ||
15 | int ret; | ||
16 | ret = execv(info->exec_path, info->argv); | ||
17 | perror("execv failed"); | ||
18 | return ret; | ||
19 | } | ||
20 | |||
21 | void usage(char *error) { | ||
22 | fprintf(stderr, "%s\nUsage: launch_rt [-c {hrt|srt|be}] [-p <cpu>]" | ||
23 | "<wcet> <period> program arg1 arg2 ...\n", | ||
24 | error); | ||
25 | exit(1); | ||
26 | } | ||
27 | |||
28 | #define OPTSTR "p:c:" | ||
29 | |||
30 | int main(int argc, char** argv) | ||
31 | { | ||
32 | int ret; | ||
33 | int wcet; | ||
34 | int period; | ||
35 | int cpu = 0; | ||
36 | int opt; | ||
37 | startup_info_t info; | ||
38 | task_class_t class = RT_CLASS_HARD; | ||
39 | |||
40 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
41 | switch (opt) { | ||
42 | case 'p': | ||
43 | cpu = atoi(optarg); | ||
44 | break; | ||
45 | case 'c': | ||
46 | class = str2class(optarg); | ||
47 | if (class == -1) | ||
48 | usage("Unknown task class."); | ||
49 | break; | ||
50 | |||
51 | case ':': | ||
52 | usage("Argument missing."); | ||
53 | break; | ||
54 | case '?': | ||
55 | default: | ||
56 | usage("Unknown flag."); | ||
57 | break; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | if (argc - optind < 3) | ||
62 | { | ||
63 | printf("argc: %d optind: %d\n", argc, optind); | ||
64 | usage("Arguments missing."); | ||
65 | } | ||
66 | wcet = atoi(argv[optind + 0]); | ||
67 | period = atoi(argv[optind + 1]); | ||
68 | if (wcet <= 0) | ||
69 | usage("The worst-case execution time must be a positive number."); | ||
70 | if (period <= 0) | ||
71 | usage("The period must be a positive number."); | ||
72 | if (wcet > period) { | ||
73 | usage("The worst-case execution time must not exceed the period."); | ||
74 | } | ||
75 | info.exec_path = argv[optind + 2]; | ||
76 | info.argv = argv + optind + 2; | ||
77 | ret = __create_rt_task(launch, &info, cpu, wcet, period, class); | ||
78 | if (ret < 0) { | ||
79 | perror("Could not create rt child process"); | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
@@ -0,0 +1,7 @@ | |||
1 | |||
2 | |||
3 | int main(int argc, char** argv) | ||
4 | { | ||
5 | while (1); | ||
6 | return 0; | ||
7 | } | ||
diff --git a/set_rt_mode.c b/set_rt_mode.c new file mode 100644 index 0000000..5936d7d --- /dev/null +++ b/set_rt_mode.c | |||
@@ -0,0 +1,22 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <strings.h> | ||
3 | #include <stdlib.h> | ||
4 | #include "litmus.h" | ||
5 | |||
6 | |||
7 | int main(int argc, char** argv) | ||
8 | { | ||
9 | if (argc == 2) { | ||
10 | if (!strcmp(argv[1], "on")) { | ||
11 | printf("Enabling real-time mode.\n"); | ||
12 | set_rt_mode(MODE_RT_RUN); | ||
13 | exit(0); | ||
14 | } else if (!strcmp(argv[1], "off")) { | ||
15 | printf("Disabling real-time mode.\n"); | ||
16 | set_rt_mode(MODE_NON_RT); | ||
17 | exit(0); | ||
18 | } | ||
19 | } | ||
20 | printf("Usage: %s {on|off}\n", argv[0]); | ||
21 | return 1; | ||
22 | } | ||
diff --git a/show_scheduler.c b/show_scheduler.c new file mode 100644 index 0000000..9bd4072 --- /dev/null +++ b/show_scheduler.c | |||
@@ -0,0 +1,11 @@ | |||
1 | #include <sys/types.h> | ||
2 | #include <stdio.h> | ||
3 | |||
4 | #include "litmus.h" | ||
5 | |||
6 | int main(int argc, char** argv) { | ||
7 | spolicy scheduler = sched_getpolicy(); | ||
8 | printf("Current scheduler: %s (%d)\n", get_scheduler_name(scheduler), | ||
9 | scheduler); | ||
10 | return 0; | ||
11 | } | ||
diff --git a/timeout.c b/timeout.c new file mode 100644 index 0000000..ba513f9 --- /dev/null +++ b/timeout.c | |||
@@ -0,0 +1,36 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <unistd.h> | ||
4 | |||
5 | #include "litmus.h" | ||
6 | |||
7 | int main(int argc, char** argv) | ||
8 | { | ||
9 | int timeout; | ||
10 | rt_param_t my_param; | ||
11 | |||
12 | if (argc != 2) | ||
13 | { | ||
14 | printf("Usage: %s <timeout in seconds>\n", argv[0]); | ||
15 | exit(1); | ||
16 | } | ||
17 | timeout = atoi(argv[1]); | ||
18 | if (timeout <= 0) { | ||
19 | printf("Timeout must be a positive number.\n"); | ||
20 | exit(1); | ||
21 | } | ||
22 | |||
23 | /* printf("This is the kill real-time mode task.\n" | ||
24 | "Expected end of real %u seconds.\n", timeout); | ||
25 | */ | ||
26 | /* get_rt_task_param(getpid(), &my_param); | ||
27 | show_rt_param(&my_param); | ||
28 | */ | ||
29 | |||
30 | sleep(timeout); | ||
31 | |||
32 | |||
33 | set_rt_mode(MODE_NON_RT); | ||
34 | printf("End of real-time mode.\n"); | ||
35 | return 0; | ||
36 | } | ||