Module: xenomai-forge
Branch: next
Commit: 2f85a852aec47f91646b9bbeb4b5a35ef0bcf3e6
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=2f85a852aec47f91646b9bbeb4b5a35ef0bcf3e6

Author: Jorge Ramirez-Ortiz <j...@xenomai.org>
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..6cc2e2e 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 spin_ns,
+                       nanosecs_rel_t sleep_ns);
+
 #endif /* DOXYGEN_CPP */
 
 int __rtdm_task_sleep(xnticks_t timeout, xntmode_t mode)


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to