Module: xenomai-forge Branch: next Commit: 9c06965c474d3f51c65ef4f9205f32a05d46b2fa URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=9c06965c474d3f51c65ef4f9205f32a05d46b2fa
Author: Jorge Ramirez-Ortiz <[email protected]> Date: Tue Jul 15 14:18:26 2014 -0400 cobalt/rtdm: introduce rtdm_task_busy_wait() --- include/cobalt/kernel/rtdm/driver.h | 22 ++++++++++++++++++++++ kernel/cobalt/rtdm/drvlib.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 053405e..f639651 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -1060,6 +1060,28 @@ static inline int __deprecated rtdm_task_sleep_until(nanosecs_abs_t wakeup_time) { return __rtdm_task_sleep(wakeup_time, XN_REALTIME); } + +#define rtdm_task_busy_wait(__condition, __spin_ns, __sleep_ns) \ + ({ \ + __label__ done; \ + nanosecs_abs_t __end; \ + int __ret = 0; \ + for (;;) { \ + __end = rtdm_clock_read_monotonic() + __spin_ns; \ + for (;;) { \ + if (__condition) \ + goto done; \ + if (rtdm_clock_read_monotonic() >= __end) \ + break; \ + } \ + __ret = rtdm_task_sleep(__sleep_ns); \ + if (__ret) \ + break; \ + } \ + done: \ + __ret; \ + }) + #endif /* !DOXYGEN_CPP */ /* --- event services --- */ diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c index b120d8f..39e09c0 100644 --- a/kernel/cobalt/rtdm/drvlib.c +++ b/kernel/cobalt/rtdm/drvlib.c @@ -297,6 +297,38 @@ int rtdm_task_sleep_until(nanosecs_abs_t wakeup_time); */ int rtdm_task_sleep_abs(nanosecs_abs_t wakeup_time, enum rtdm_timer_mode mode); +/** + * @brief Safe busy waiting + * + * This service alternates active spinning and sleeping within a wait + * loop, until a condition is satisfied. While sleeping, a task is + * scheduled out and does not consume any CPU time. + * + * rtdm_task_busy_wait() is particularly useful for waiting for a + * state change reading an I/O register, which usually happens shortly + * after the wait starts, without incurring the adverse effects of + * long busy waiting if it doesn't. + * + * @param[in] condition The C expression to be tested for detecting + * completion. + * @param[in] spin_ns The time to spin on @a condition before + * sleeping, expressed as a count of nanoseconds. + * @param[in] sleep_ns The time to sleep for before spinning again, + * expressed as a count of nanoseconds. + * + * @return 0 on success if @a condition is satisfied, otherwise: + * + * - -EINTR is returned if the calling task has been unblocked by a + * Linux signal or explicitly via rtdm_task_unblock(). + * + * - -EPERM may be returned if an illegal invocation environment is + * detected. + * + * @coretags{primary-only, might-switch} + */ +int rtdm_task_busy_wait(bool condition, nanosecs_rel_t busy_time, + nanosecs_rel_t sleep_time); + #endif /* DOXYGEN_CPP */ int __rtdm_task_sleep(xnticks_t timeout, xntmode_t mode) _______________________________________________ Xenomai-git mailing list [email protected] http://www.xenomai.org/mailman/listinfo/xenomai-git
