From 8a256a9f6f277be1a2fe266b4578e7e0b403ee92 Mon Sep 17 00:00:00 2001 From: "Bjoern B. Brandenburg" Date: Tue, 19 Feb 2008 13:13:57 -0500 Subject: 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. --- include/litmus/rt_param.h | 1 + litmus/sync.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 litmus/sync.c 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 { struct rt_task { lt_t exec_cost; lt_t period; + lt_t phase; unsigned int cpu; task_class_t cls; }; 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 @@ +/* litmus/sync.c - Support for synchronous and asynchronous task system releases. + * + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +static DECLARE_COMPLETION(ts_release); + +static long do_wait_for_ts_release(void) +{ + long ret = 0; + + /* If the interruption races with a release, the completion object + * may have a non-zero counter. To avoid this problem, this should + * be replaced by wait_for_completion(). + * + * For debugging purposes, this is interruptible for now. + */ + ret = wait_for_completion_interruptible(&ts_release); + + return ret; +} + + +static long do_release_ts(lt_t start) +{ + long ret = 0; + int task_count = 0; + long flags; + struct list_head *pos; + struct task_struct *t; + + + spin_lock_irqsave(&ts_release.wait.lock, flags); + + list_for_each(pos, &ts_release.wait.task_list) { + t = (struct task_struct*) list_entry(pos, + struct __wait_queue, + task_list)->private; + task_count++; + release_at(t, start + t->rt_param.task_params.phase); + } + + spin_unlock_irqrestore(&ts_release.wait.lock, flags); + + complete_n(&ts_release, task_count); + + return ret; +} + + +asmlinkage long sys_wait_for_ts_release(void) +{ + long ret = -EPERM; + struct task_struct *t = current; + + if (is_realtime(t)) + ret = do_wait_for_ts_release(); + + return ret; +} + + +asmlinkage long sys_release_ts(lt_t __user *__delay) +{ + long ret; + lt_t delay; + + /* FIXME: check capabilities... */ + + ret = copy_from_user(&delay, __delay, sizeof(lt_t)); + if (ret == 0) + ret = do_release_ts(sched_clock() + delay); + + return ret; +} -- cgit v1.2.2