Module: xenomai-3 Branch: stable-3.0.x Commit: 8318c85025458d96f5d73050f29c937da4d54a5e URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=8318c85025458d96f5d73050f29c937da4d54a5e
Author: Philippe Gerum <[email protected]> Date: Mon Apr 25 11:47:21 2016 +0200 cobalt/rtdm: expose wait_context API from the core threads --- include/cobalt/kernel/rtdm/driver.h | 25 +++++++++++ kernel/cobalt/rtdm/drvlib.c | 82 +++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 7d62f13..edd92ee 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -1114,6 +1114,31 @@ static inline int __deprecated rtdm_task_sleep_until(nanosecs_abs_t wakeup_time) __ret; \ }) +#define rtdm_wait_context xnthread_wait_context + +static inline +void rtdm_wait_complete(struct rtdm_wait_context *wc) +{ + xnthread_complete_wait(wc); +} + +static inline +int rtdm_wait_is_completed(struct rtdm_wait_context *wc) +{ + return xnthread_wait_complete_p(wc); +} + +static inline void rtdm_wait_prepare(struct rtdm_wait_context *wc) +{ + xnthread_prepare_wait(wc); +} + +static inline +struct rtdm_wait_context *rtdm_wait_get_context(rtdm_task_t *task) +{ + return xnthread_get_wait_context(task); +} + #endif /* !DOXYGEN_CPP */ /* --- event services --- */ diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c index 481ad83..629c555 100644 --- a/kernel/cobalt/rtdm/drvlib.c +++ b/kernel/cobalt/rtdm/drvlib.c @@ -343,6 +343,88 @@ int rtdm_task_sleep_abs(nanosecs_abs_t wakeup_time, enum rtdm_timer_mode mode); int rtdm_task_busy_wait(bool condition, nanosecs_rel_t spin_ns, nanosecs_rel_t sleep_ns); +/** + * @brief Register wait context + * + * rtdm_wait_prepare() registers a wait context structure for the + * caller, which can be later retrieved by a call to + * rtdm_wait_get_context(). This call is normally issued before the + * current task blocks on a wait object, waiting for some (producer) + * code to wake it up. Arbitrary data can be exchanged between both + * sites via the wait context structure, which is allocated by the + * waiter (consumer) side. + * + * @a wc is the address of an anchor object which is commonly embedded + * into a larger structure with arbitrary contents, which needs to be + * shared between the consumer (waiter) and the producer for + * implementing the wait code. + * + * A typical implementation pattern for the wait side is: + * + * @code + * struct rtdm_waitqueue wq; + * struct some_wait_context { + * int input_value; + * int output_value; + * struct rtdm_wait_context wc; + * } wait_context; + * + * wait_context.input_value = 42; + * rtdm_wait_prepare(&wait_context); + * ret = rtdm_wait_condition(&wq, rtdm_wait_is_completed(&wait_context)); + * if (ret) + * goto wait_failed; + * handle_event(wait_context.output_value); + * @endcode + * + * On the producer side, the implementation would look like: + * + * @code + * struct rtdm_waitqueue wq; + * struct some_wait_context { + * int input_value; + * int output_value; + * struct rtdm_wait_context wc; + * } *wait_context_ptr; + * struct rtdm_wait_context *wc; + * rtdm_task_t *task; + * + * rtdm_for_each_waiter(task, &wq) { + * wc = rtdm_wait_get_context(task); + * wait_context_ptr = container_of(wc, struct some_wait_context, wc); + * wait_context_ptr->output_value = 12; + * } + * rtdm_waitqueue_broadcast(&wq); + * @endcode + * + * @param wc Wait context to register. + */ +void rtdm_wait_prepare(struct rtdm_wait_context *wc); + +/** + * @brief Mark completion for a wait context + * + * rtdm_complete_wait() marks a wait context as completed, so that + * rtdm_wait_is_completed() returns true for such context. + * + * @param wc Wait context to complete. + */ +void rtdm_wait_complete(struct rtdm_wait_context *wc); + +/** + * @brief Test completion of a wait context + * + * rtdm_wait_is_completed() returns true if rtdm_complete_wait() was + * called for @a wc. The completion mark is reset each time + * rtdm_wait_prepare() is called for a wait context. + * + * @param wc Wait context to check for completion. + * + * @return non-zero/true if rtdm_wait_complete() was called for @a wc, + * zero otherwise. + */ +int rtdm_wait_is_completed(struct rtdm_wait_context *wc); + #endif /* DOXYGEN_CPP */ int __rtdm_task_sleep(xnticks_t timeout, xntmode_t mode) _______________________________________________ Xenomai-git mailing list [email protected] https://xenomai.org/mailman/listinfo/xenomai-git
