diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-02-19 13:13:57 -0500 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-02-19 13:13:57 -0500 |
commit | 8a256a9f6f277be1a2fe266b4578e7e0b403ee92 (patch) | |
tree | 67a5fb9d85a917a6d8441f35d475dfe284fc142f | |
parent | 265952f112a27c8fbe47560b23a531f8baaf1898 (diff) |
litmus: synchronous task release API
This adds the internals for two new systems calls:
- sys_wait_for_ts_release()
- sys_release_ts()
The first system call suspends a task until the task systems is
released with the second system call.
-rw-r--r-- | include/litmus/rt_param.h | 1 | ||||
-rw-r--r-- | litmus/sync.c | 85 |
2 files changed, 86 insertions, 0 deletions
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index 9fb5b19b78..1f94e45578 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
@@ -30,6 +30,7 @@ typedef enum { | |||
30 | struct rt_task { | 30 | struct rt_task { |
31 | lt_t exec_cost; | 31 | lt_t exec_cost; |
32 | lt_t period; | 32 | lt_t period; |
33 | lt_t phase; | ||
33 | unsigned int cpu; | 34 | unsigned int cpu; |
34 | task_class_t cls; | 35 | task_class_t cls; |
35 | }; | 36 | }; |
diff --git a/litmus/sync.c b/litmus/sync.c new file mode 100644 index 0000000000..fccde19236 --- /dev/null +++ b/litmus/sync.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* litmus/sync.c - Support for synchronous and asynchronous task system releases. | ||
2 | * | ||
3 | * | ||
4 | */ | ||
5 | |||
6 | #include <asm/atomic.h> | ||
7 | #include <asm/uaccess.h> | ||
8 | #include <linux/spinlock.h> | ||
9 | #include <linux/list.h> | ||
10 | #include <linux/sched.h> | ||
11 | #include <linux/completion.h> | ||
12 | |||
13 | #include <litmus/litmus.h> | ||
14 | #include <litmus/jobs.h> | ||
15 | |||
16 | static DECLARE_COMPLETION(ts_release); | ||
17 | |||
18 | static long do_wait_for_ts_release(void) | ||
19 | { | ||
20 | long ret = 0; | ||
21 | |||
22 | /* If the interruption races with a release, the completion object | ||
23 | * may have a non-zero counter. To avoid this problem, this should | ||
24 | * be replaced by wait_for_completion(). | ||
25 | * | ||
26 | * For debugging purposes, this is interruptible for now. | ||
27 | */ | ||
28 | ret = wait_for_completion_interruptible(&ts_release); | ||
29 | |||
30 | return ret; | ||
31 | } | ||
32 | |||
33 | |||
34 | static long do_release_ts(lt_t start) | ||
35 | { | ||
36 | long ret = 0; | ||
37 | int task_count = 0; | ||
38 | long flags; | ||
39 | struct list_head *pos; | ||
40 | struct task_struct *t; | ||
41 | |||
42 | |||
43 | spin_lock_irqsave(&ts_release.wait.lock, flags); | ||
44 | |||
45 | list_for_each(pos, &ts_release.wait.task_list) { | ||
46 | t = (struct task_struct*) list_entry(pos, | ||
47 | struct __wait_queue, | ||
48 | task_list)->private; | ||
49 | task_count++; | ||
50 | release_at(t, start + t->rt_param.task_params.phase); | ||
51 | } | ||
52 | |||
53 | spin_unlock_irqrestore(&ts_release.wait.lock, flags); | ||
54 | |||
55 | complete_n(&ts_release, task_count); | ||
56 | |||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | |||
61 | asmlinkage long sys_wait_for_ts_release(void) | ||
62 | { | ||
63 | long ret = -EPERM; | ||
64 | struct task_struct *t = current; | ||
65 | |||
66 | if (is_realtime(t)) | ||
67 | ret = do_wait_for_ts_release(); | ||
68 | |||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | |||
73 | asmlinkage long sys_release_ts(lt_t __user *__delay) | ||
74 | { | ||
75 | long ret; | ||
76 | lt_t delay; | ||
77 | |||
78 | /* FIXME: check capabilities... */ | ||
79 | |||
80 | ret = copy_from_user(&delay, __delay, sizeof(lt_t)); | ||
81 | if (ret == 0) | ||
82 | ret = do_release_ts(sched_clock() + delay); | ||
83 | |||
84 | return ret; | ||
85 | } | ||