aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-12-08 10:11:25 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-12-08 12:44:53 -0500
commit20cb895345f3c868a6d192ffa3634cd80481bb77 (patch)
treedb6dde8159db701107fa92a81f1e4521b1fc9fbf
parent735a96eeb485018d53ffb9548dacc8a9ab143582 (diff)
add synchronous task release API
-rw-r--r--litmus/Makefile1
-rw-r--r--litmus/litmus.c4
-rw-r--r--litmus/sync.c104
3 files changed, 108 insertions, 1 deletions
diff --git a/litmus/Makefile b/litmus/Makefile
index f4c2d564cd0b..e93f19bb2016 100644
--- a/litmus/Makefile
+++ b/litmus/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-y = sched_plugin.o litmus.o \ 5obj-y = sched_plugin.o litmus.o \
6 jobs.o \ 6 jobs.o \
7 sync.o \
7 heap.o 8 heap.o
8 9
9obj-$(CONFIG_FEATHER_TRACE) += ft_event.o ftdev.o 10obj-$(CONFIG_FEATHER_TRACE) += ft_event.o ftdev.o
diff --git a/litmus/litmus.c b/litmus/litmus.c
index dd3867715af6..871eb64a8dd5 100644
--- a/litmus/litmus.c
+++ b/litmus/litmus.c
@@ -435,6 +435,8 @@ static struct sysrq_key_op sysrq_kill_rt_tasks_op = {
435 435
436#endif 436#endif
437 437
438/* in sync.c */
439int count_tasks_waiting_for_release(void);
438 440
439static int proc_read_stats(char *page, char **start, 441static int proc_read_stats(char *page, char **start,
440 off_t off, int count, 442 off_t off, int count,
@@ -446,7 +448,7 @@ static int proc_read_stats(char *page, char **start,
446 "real-time tasks = %d\n" 448 "real-time tasks = %d\n"
447 "ready for release = %d\n", 449 "ready for release = %d\n",
448 atomic_read(&rt_task_count), 450 atomic_read(&rt_task_count),
449 0); 451 count_tasks_waiting_for_release());
450 return len; 452 return len;
451} 453}
452 454
diff --git a/litmus/sync.c b/litmus/sync.c
new file mode 100644
index 000000000000..bd2c677d640b
--- /dev/null
+++ b/litmus/sync.c
@@ -0,0 +1,104 @@
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/sched_plugin.h>
15#include <litmus/jobs.h>
16
17#include <litmus/sched_trace.h>
18
19static DECLARE_COMPLETION(ts_release);
20
21static long do_wait_for_ts_release(void)
22{
23 long ret = 0;
24
25 /* If the interruption races with a release, the completion object
26 * may have a non-zero counter. To avoid this problem, this should
27 * be replaced by wait_for_completion().
28 *
29 * For debugging purposes, this is interruptible for now.
30 */
31 ret = wait_for_completion_interruptible(&ts_release);
32
33 return ret;
34}
35
36int count_tasks_waiting_for_release(void)
37{
38 long flags;
39 int task_count = 0;
40 struct list_head *pos;
41
42 spin_lock_irqsave(&ts_release.wait.lock, flags);
43 list_for_each(pos, &ts_release.wait.task_list) {
44 task_count++;
45 }
46 spin_unlock_irqrestore(&ts_release.wait.lock, flags);
47
48 return task_count;
49}
50
51static long do_release_ts(lt_t start)
52{
53 int task_count = 0;
54 long flags;
55 struct list_head *pos;
56 struct task_struct *t;
57
58
59 spin_lock_irqsave(&ts_release.wait.lock, flags);
60 TRACE("<<<<<< synchronous task system release >>>>>>\n");
61
62 sched_trace_sys_release(&start);
63 list_for_each(pos, &ts_release.wait.task_list) {
64 t = (struct task_struct*) list_entry(pos,
65 struct __wait_queue,
66 task_list)->private;
67 task_count++;
68 litmus->release_at(t, start + t->rt_param.task_params.phase);
69 sched_trace_task_release(t);
70 }
71
72 spin_unlock_irqrestore(&ts_release.wait.lock, flags);
73
74 complete_n(&ts_release, task_count);
75
76 return task_count;
77}
78
79
80asmlinkage long sys_wait_for_ts_release(void)
81{
82 long ret = -EPERM;
83 struct task_struct *t = current;
84
85 if (is_realtime(t))
86 ret = do_wait_for_ts_release();
87
88 return ret;
89}
90
91
92asmlinkage long sys_release_ts(lt_t __user *__delay)
93{
94 long ret;
95 lt_t delay;
96
97 /* FIXME: check capabilities... */
98
99 ret = copy_from_user(&delay, __delay, sizeof(delay));
100 if (ret == 0)
101 ret = do_release_ts(litmus_clock() + delay);
102
103 return ret;
104}