aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2008-02-19 13:13:57 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2008-02-19 13:13:57 -0500
commit8a256a9f6f277be1a2fe266b4578e7e0b403ee92 (patch)
tree67a5fb9d85a917a6d8441f35d475dfe284fc142f
parent265952f112a27c8fbe47560b23a531f8baaf1898 (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.h1
-rw-r--r--litmus/sync.c85
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 {
30struct rt_task { 30struct 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
16static DECLARE_COMPLETION(ts_release);
17
18static 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
34static 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
61asmlinkage 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
73asmlinkage 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}