aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2007-09-18 12:23:43 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2007-09-18 12:23:43 -0400
commit957ad72229186c5d21e44366f61d58a4dfa89bfe (patch)
tree2284b3f2f4c1ed7c81ba0ccda720997fab4dab85 /src
parent5760b6ad37c794a0dd5312206184d0b8ae8e8eda (diff)
Change liblitmus to have a more sane repository layout.
Diffstat (limited to 'src')
-rw-r--r--src/edf-hsb.c48
-rw-r--r--src/hrt.c78
-rw-r--r--src/iotest.c74
-rw-r--r--src/litmus.c295
-rw-r--r--src/np_test.c56
-rw-r--r--src/rt_launch.c83
-rw-r--r--src/run.c8
-rw-r--r--src/set_rt_mode.c22
-rw-r--r--src/show_scheduler.c10
-rw-r--r--src/timeout.c36
-rw-r--r--src/wait_test.c103
11 files changed, 813 insertions, 0 deletions
diff --git a/src/edf-hsb.c b/src/edf-hsb.c
new file mode 100644
index 0000000..9ace2ca
--- /dev/null
+++ b/src/edf-hsb.c
@@ -0,0 +1,48 @@
1#include "litmus.h"
2#include "edf-hsb.h"
3
4
5typedef enum {
6 EDF_HSB_SET_HRT,
7 EDF_HSB_GET_HRT,
8 EDF_HSB_CREATE_BE
9} edf_hsb_setup_cmds_t;
10
11typedef struct {
12 int cpu;
13 unsigned int wcet;
14 unsigned int period;
15} setup_hrt_param_t;
16
17typedef struct {
18 unsigned int wcet;
19 unsigned int period;
20} create_be_param_t;
21
22int 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, &param);
29}
30
31int 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, &param);
37 *wcet = param.wcet;
38 *period = param.period;
39 return ret;
40}
41
42int 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, &param);
48}
diff --git a/src/hrt.c b/src/hrt.c
new file mode 100644
index 0000000..224293c
--- /dev/null
+++ b/src/hrt.c
@@ -0,0 +1,78 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "edf-hsb.h"
6
7
8void 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
20int 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
47int 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
66int 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/src/iotest.c b/src/iotest.c
new file mode 100644
index 0000000..ac07e74
--- /dev/null
+++ b/src/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
12int 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
39int 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/src/litmus.c b/src/litmus.c
new file mode 100644
index 0000000..65ad294
--- /dev/null
+++ b/src/litmus.c
@@ -0,0 +1,295 @@
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#include <sys/mman.h>
9
10
11#include "litmus.h"
12
13
14/* this is missing in newer linux/unistd.h versions */
15
16#define _syscall0(type,name) \
17type name(void) \
18{\
19 return syscall(__NR_##name);\
20}
21
22#define _syscall1(type,name,type1,arg1) \
23type name(type1 arg1) \
24{\
25 return syscall(__NR_##name, arg1);\
26}
27
28
29#define _syscall2(type,name,type1,arg1,type2,arg2) \
30type name(type1 arg1,type2 arg2) \
31{\
32 return syscall(__NR_##name, arg1, arg2);\
33}
34
35
36/* clear the TID in the child */
37#define CLONE_CHILD_CLEARTID 0x00200000
38/* set the TID in the child */
39#define CLONE_CHILD_SETTID 0x01000000
40/* don't let the child run before we have completed setup */
41#define CLONE_STOPPED 0x02000000
42/* litmus clone flag */
43#define CLONE_REALTIME 0x10000000
44
45/* CLONE_REALTIME is necessary because CLONE_STOPPED will put a SIGSTOP in
46 * the pending signal queue. Thus the first thing a newly created task will
47 * do after it is released is to stop, which is not what we want
48 *
49 * CLONE_REALTIME just sets the status to TASK_STOPPED without queueing a
50 * signal.
51 */
52
53
54/* this is essentially a fork with CLONE_STOPPED */
55/* #define CLONE_LITMUS CLONE_STOPPED | CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID */
56#define CLONE_LITMUS CLONE_REALTIME | CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID
57
58/* we need to override libc because it wants to be clever
59 * and rejects our call without presenting it even to the kernel
60 */
61#define __NR_raw_clone 120
62
63
64_syscall2(int, raw_clone, unsigned long, flags, unsigned long, child_stack)
65
66
67const char* get_scheduler_name(spolicy scheduler)
68{
69 const char* name;
70
71 switch (scheduler){
72 case SCHED_LINUX :
73 name = "Linux";
74 break;
75 case SCHED_PFAIR:
76 name = "Pfair";
77 break;
78 case SCHED_PFAIR_STAGGER:
79 name = "Pfair (staggered)";
80 break;
81 case SCHED_PART_EDF:
82 name = "Partioned EDF";
83 break;
84 case SCHED_PART_EEVDF:
85 name = "Partioned EEVDF";
86 break;
87 case SCHED_GLOBAL_EDF:
88 name = "Global EDF";
89 break;
90 case SCHED_EDF_HSB:
91 name = "EDF-HSB";
92 break;
93 case SCHED_GSN_EDF:
94 name = "GSN-EDF";
95 break;
96 case SCHED_PSN_EDF:
97 name = "PSN-EDF";
98 break;
99 default:
100 name = "Unkown";
101 break;
102 }
103 return name;
104}
105
106int create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period) {
107 return __create_rt_task(rt_prog, arg, cpu, wcet, period, RT_CLASS_HARD);
108}
109
110int __create_rt_task(rt_fn_t rt_prog, void *arg, int cpu, int wcet, int period,
111 task_class_t class)
112{
113 int ret;
114 rt_param_t params;
115 int rt_task = raw_clone(CLONE_LITMUS, 0);
116
117 if (rt_task < 0)
118 return rt_task;
119
120 if (rt_task > 0) {
121 /* we are the controller task */
122 params.period = period;
123 params.exec_cost = wcet;
124 params.cpu = cpu;
125 params.cls = class;
126 ret = set_rt_task_param(rt_task, &params);
127 if (ret < 0) {
128 /* we have a problem: we created the task but
129 * for some stupid reason we cannot set the real-time
130 * parameters. We must clean up the stopped task.
131 */
132 kill(rt_task, SIGKILL);
133 /* syscall will have set errno, we don't have to do
134 * anything
135 */
136 return -1;
137 }
138 ret = prepare_rt_task(rt_task);
139 if (ret < 0) {
140 /* same problem as above*/
141 //kill(rt_task, SIGKILL);
142 rt_task = -1;
143 }
144 return rt_task;
145 }
146 else {
147 /* we are the real-time task
148 * launch task and die when it is done
149 */
150
151 exit(rt_prog(arg));
152 }
153}
154
155
156void show_rt_param(rt_param_t* tp)
157{
158 printf("rt params:\n\t"
159 "exec_cost:\t%ld\n\tperiod:\t\t%ld\n\tcpu:\t%d\n",
160 tp->exec_cost, tp->period, tp->cpu);
161}
162
163task_class_t str2class(const char* str)
164{
165 if (!strcmp(str, "hrt"))
166 return RT_CLASS_HARD;
167 else if (!strcmp(str, "srt"))
168 return RT_CLASS_SOFT;
169 else if (!strcmp(str, "be"))
170 return RT_CLASS_BEST_EFFORT;
171 else
172 return -1;
173}
174
175
176
177struct np_flag {
178 #define RT_PREEMPTIVE 0x2050 /* = NP */
179 #define RT_NON_PREEMPTIVE 0x4e50 /* = P */
180 unsigned short preemptivity;
181
182 #define RT_EXIT_NP_REQUESTED 0x5251 /* = RQ */
183 unsigned short request;
184
185 unsigned int ctr;
186};
187
188static struct np_flag np_flag;
189
190int register_np_flag(struct np_flag* flag);
191int signal_exit_np(void);
192
193
194static inline void barrier(void)
195{
196 __asm__ __volatile__("sfence": : :"memory");
197}
198
199void enter_np(void)
200{
201 if (++np_flag.ctr == 1)
202 {
203 np_flag.request = 0;
204 barrier();
205 np_flag.preemptivity = RT_NON_PREEMPTIVE;
206 }
207}
208
209
210void exit_np(void)
211{
212 if (--np_flag.ctr == 0)
213 {
214 np_flag.preemptivity = RT_PREEMPTIVE;
215 barrier();
216 if (np_flag.request == RT_EXIT_NP_REQUESTED)
217 signal_exit_np();
218 }
219}
220
221
222#define check(str) if (ret == -1) {perror(str); fprintf(stderr, \
223 "Could not initialize LITMUS^RT, aborting...\n"); exit(1);}
224
225void init_litmus(void)
226{
227 int ret;
228 np_flag.preemptivity = RT_PREEMPTIVE;
229 np_flag.ctr = 0;
230
231 ret = mlockall(MCL_CURRENT | MCL_FUTURE);
232 check("mlockall");
233 ret = register_np_flag(&np_flag);
234 check("register_np_flag");
235}
236
237
238
239/* Litmus syscalls definitions */
240#define __NR_sched_setpolicy 320
241#define __NR_sched_getpolicy 321
242#define __NR_set_rt_mode 322
243#define __NR_set_rt_task_param 323
244#define __NR_get_rt_task_param 324
245#define __NR_prepare_rt_task 325
246#define __NR_reset_stat 326
247#define __NR_sleep_next_period 327
248#define __NR_scheduler_setup 328
249#define __NR_register_np_flag 329
250#define __NR_signal_exit_np 330
251#define __NR_pi_sema_init 331
252#define __NR_pi_down 332
253#define __NR_pi_up 333
254#define __NR_pi_sema_free 334
255#define __NR_sema_init 335
256#define __NR_down 336
257#define __NR_up 337
258#define __NR_sema_free 338
259#define __NR_srp_sema_init 339
260#define __NR_srp_down 340
261#define __NR_srp_up 341
262#define __NR_reg_task_srp_sem 342
263#define __NR_srp_sema_free 343
264#define __NR_get_job_no 344
265#define __NR_wait_for_job_release 345
266
267
268/* Syscall stub for setting RT mode and scheduling options */
269_syscall1(spolicy, sched_setpolicy, spolicy, arg1);
270_syscall0(spolicy, sched_getpolicy);
271_syscall1(int, set_rt_mode, int, arg1);
272_syscall2(int, set_rt_task_param, pid_t, pid, rt_param_t*, arg1);
273_syscall2(int, get_rt_task_param, pid_t, pid, rt_param_t*, arg1);
274_syscall1(int, prepare_rt_task, pid_t, pid);
275_syscall0(int, reset_stat);
276_syscall0(int, sleep_next_period);
277_syscall2(int, scheduler_setup, int, cmd, void*, param);
278_syscall1(int, register_np_flag, struct np_flag*, flag);
279_syscall0(int, signal_exit_np);
280_syscall0(int, pi_sema_init);
281_syscall1(int, pi_down, pi_sema_id, sem_id);
282_syscall1(int, pi_up, pi_sema_id, sem_id);
283_syscall1(int, pi_sema_free, pi_sema_id, sem_id);
284_syscall0(int, sema_init);
285_syscall1(int, down, sema_id, sem_id);
286_syscall1(int, up, sema_id, sem_id);
287_syscall1(int, sema_free, sema_id, sem_id);
288_syscall0(int, srp_sema_init);
289_syscall1(int, srp_down, srp_sema_id, sem_id);
290_syscall1(int, srp_up, srp_sema_id, sem_id);
291_syscall2(int, reg_task_srp_sem, srp_sema_id, sem_id, pid_t, t_pid);
292_syscall1(int, srp_sema_free, srp_sema_id, sem_id);
293_syscall1(int, get_job_no, unsigned int*, job_no);
294_syscall1(int, wait_for_job_release, unsigned int, job_no);
295
diff --git a/src/np_test.c b/src/np_test.c
new file mode 100644
index 0000000..dad68aa
--- /dev/null
+++ b/src/np_test.c
@@ -0,0 +1,56 @@
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#include <sys/types.h>
8#include <sys/stat.h>
9#include <fcntl.h>
10
11#include "litmus.h"
12
13#define US_PER_MS 1000
14
15#define NUMTASKS 4
16
17int prefix(void)
18{
19 char field[1024];
20 int prefix[1024];
21 int i, sum = 0;
22
23 for (i = 0; i < 1024; i++) {
24 sum += field[i];
25 prefix[i] = sum;
26 }
27 return sum;
28}
29
30
31void do_stuff(void)
32{
33 int i =0, j =0;
34
35 for (; i < 50000; i++)
36 j += prefix();
37}
38
39#define CALL(sc) do { ret = sc; if (ret == -1) {perror(" (!!) " #sc " failed: "); /*exit(1)*/;}} while (0);
40
41
42int main(int argc, char** argv)
43{
44 int ret;
45
46 init_litmus();
47
48 enter_np();
49
50 do_stuff();
51
52 exit_np();
53
54
55 return 0;
56}
diff --git a/src/rt_launch.c b/src/rt_launch.c
new file mode 100644
index 0000000..31e6447
--- /dev/null
+++ b/src/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
7typedef struct {
8 char * exec_path;
9 char ** argv;
10} startup_info_t;
11
12
13int 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
21void 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
30int 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}
diff --git a/src/run.c b/src/run.c
new file mode 100644
index 0000000..3719d6f
--- /dev/null
+++ b/src/run.c
@@ -0,0 +1,8 @@
1
2
3int main(int argc, char** argv)
4{
5 int i;
6 for (i = 0; i < 500000000; i++);
7 return 0;
8}
diff --git a/src/set_rt_mode.c b/src/set_rt_mode.c
new file mode 100644
index 0000000..5936d7d
--- /dev/null
+++ b/src/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
7int 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/src/show_scheduler.c b/src/show_scheduler.c
new file mode 100644
index 0000000..7026e2a
--- /dev/null
+++ b/src/show_scheduler.c
@@ -0,0 +1,10 @@
1#include <sys/types.h>
2#include <stdio.h>
3
4#include "litmus.h"
5
6int main(int argc, char** argv) {
7 spolicy scheduler = sched_getpolicy();
8 printf("%s\n", get_scheduler_name(scheduler));
9 return 0;
10}
diff --git a/src/timeout.c b/src/timeout.c
new file mode 100644
index 0000000..ba513f9
--- /dev/null
+++ b/src/timeout.c
@@ -0,0 +1,36 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4
5#include "litmus.h"
6
7int 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}
diff --git a/src/wait_test.c b/src/wait_test.c
new file mode 100644
index 0000000..efd4d90
--- /dev/null
+++ b/src/wait_test.c
@@ -0,0 +1,103 @@
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#include <sys/types.h>
8#include <sys/stat.h>
9#include <fcntl.h>
10
11#include "litmus.h"
12
13#define US_PER_MS 1000
14
15#define NUMTASKS 4
16
17int prefix(void)
18{
19 char field[1024];
20 int prefix[1024];
21 int i, sum = 0;
22
23 for (i = 0; i < 1024; i++) {
24 sum += field[i];
25 prefix[i] = sum;
26 }
27 return sum;
28}
29
30
31void do_stuff(void)
32{
33 int i =0, j =0;
34
35 for (; i < 50000; i++)
36 j += prefix();
37}
38
39#define CALL(sc) do { ret = sc; if (ret == -1) {perror(" (!!) " #sc " failed: "); /*exit(1)*/;}} while (0);
40
41unsigned int job_no;
42
43
44void next(void)
45{
46 int ret;
47 unsigned int actual;
48 CALL(get_job_no(&actual));
49 CALL(wait_for_job_release(++job_no));
50 printf("Now executing job %u, waited for %u\n", actual, job_no);
51}
52
53void sync_jobs(void)
54{
55 int ret;
56 unsigned int actual;
57 CALL(get_job_no(&actual));
58 job_no = actual;
59}
60
61
62int main(int argc, char** argv)
63{
64 int ret;
65
66 init_litmus();
67
68 CALL(getpid());
69 printf("my pid is %d\n", ret);
70
71
72 CALL(get_job_no(&job_no));
73 printf("my job_no is %u", job_no);
74
75 next();
76 next();
77 next();
78
79 /* now overrun a job for good */
80 do_stuff();
81 do_stuff();
82 do_stuff();
83 do_stuff();
84 do_stuff();
85 do_stuff();
86 do_stuff();
87 do_stuff();
88 do_stuff();
89 do_stuff();
90
91
92 next();
93 next();
94 next();
95 next();
96 sync_jobs();
97 next();
98 next();
99 next();
100
101
102 return 0;
103}