aboutsummaryrefslogtreecommitdiffstats
path: root/litmus
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2009-12-17 21:30:11 -0500
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-29 17:14:23 -0400
commit1d823f50678d7cc3bf72bf89ec0bddc7338e23d5 (patch)
treea614f7b7d0a23dbbaec29646c65c2729dbfa563e /litmus
parent59d8d4c53f1e9f6408b87fc22e319e78f664276f (diff)
[ported from 2008.3] Add synchronous task release API
Diffstat (limited to 'litmus')
-rw-r--r--litmus/Makefile1
-rw-r--r--litmus/litmus.c10
-rw-r--r--litmus/sync.c104
3 files changed, 111 insertions, 4 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 eb0d17e298d7..9254f1621af7 100644
--- a/litmus/litmus.c
+++ b/litmus/litmus.c
@@ -1,4 +1,6 @@
1/* litmus.c -- Implementation of the LITMUS syscalls, the LITMUS intialization code, 1/*
2 * litmus.c -- Implementation of the LITMUS syscalls,
3 * the LITMUS intialization code,
2 * and the procfs interface.. 4 * and the procfs interface..
3 */ 5 */
4#include <asm/uaccess.h> 6#include <asm/uaccess.h>
@@ -438,10 +440,10 @@ static struct sysrq_key_op sysrq_kill_rt_tasks_op = {
438 .help_msg = "quit-rt-tasks(X)", 440 .help_msg = "quit-rt-tasks(X)",
439 .action_msg = "sent SIGKILL to all LITMUS^RT real-time tasks", 441 .action_msg = "sent SIGKILL to all LITMUS^RT real-time tasks",
440}; 442};
441
442
443#endif 443#endif
444 444
445/* in litmus/sync.c */
446int count_tasks_waiting_for_release(void);
445 447
446static int proc_read_stats(char *page, char **start, 448static int proc_read_stats(char *page, char **start,
447 off_t off, int count, 449 off_t off, int count,
@@ -453,7 +455,7 @@ static int proc_read_stats(char *page, char **start,
453 "real-time tasks = %d\n" 455 "real-time tasks = %d\n"
454 "ready for release = %d\n", 456 "ready for release = %d\n",
455 atomic_read(&rt_task_count), 457 atomic_read(&rt_task_count),
456 0); 458 count_tasks_waiting_for_release());
457 return len; 459 return len;
458} 460}
459 461
diff --git a/litmus/sync.c b/litmus/sync.c
new file mode 100644
index 000000000000..bf75fde5450b
--- /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 unsigned 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 unsigned 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}