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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Sep 25 11:19:03 2014 +0200

copperplate, alchemy: do not restrict CLOCK_COPPERPLATE over Cobalt

If we can't set the clock for condvar timeouts because of a legacy
threading library (e.g. linuxthreads), then we have to restrict the
Copperplate clock to CLOCK_REALTIME over Mercury unconditionally.

Cobalt is different: although we may not have
pthread_condattr_setclock() available from the threading library,
Copperplate is still able to attach Cobalt condvars to specific clocks
internally, therefore we don't have to use a restricted clock in
Copperplate. However, lack of pthread_condattr_setclock() will still
affect explicit calls to pthread_cond_timedwait() over Cobalt like
timed services from Alchemy's RT_COND.

---

 configure                      |    5 +++-
 configure.ac                   |   23 ++++++++++++++----
 include/copperplate/clockobj.h |   18 +-------------
 lib/alchemy/cond.c             |   14 +++++++++++
 lib/copperplate/clockobj.c     |   52 +++++++++++-----------------------------
 5 files changed, 51 insertions(+), 61 deletions(-)

diff --git a/configure b/configure
index b809a29..3ac9d4f 100755
--- a/configure
+++ b/configure
@@ -13832,7 +13832,9 @@ done
 
 LIBS="$save_LIBS"
 
-ac_fn_c_check_func "$LINENO" "pthread_condattr_setclock" 
"ac_cv_func_pthread_condattr_setclock"
+
+if test $rtcore_type = mercury; then
+   ac_fn_c_check_func "$LINENO" "pthread_condattr_setclock" 
"ac_cv_func_pthread_condattr_setclock"
 if test "x$ac_cv_func_pthread_condattr_setclock" = xyes; then :
 
 else
@@ -13841,6 +13843,7 @@ $as_echo "#define 
CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED 1" >>confdefs.h
 
 fi
 
+fi
 
 if test x$use_pshared = xy;  then
   ac_fn_c_check_func "$LINENO" "shm_open" "ac_cv_func_shm_open"
diff --git a/configure.ac b/configure.ac
index 5f913e6..e04e5bd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -528,10 +528,20 @@ AC_CHECK_FUNCS([pthread_mutexattr_setprotocol     \
 LIBS="$save_LIBS"
 
 dnl If we can't set the clock for condvar timeouts, then
-dnl we have to restrict the Copperplate clock to CLOCK_REALTIME.
+dnl we have to restrict the Copperplate clock to CLOCK_REALTIME over
+dnl Mercury unconditionally. Cobalt is different: although we may not
+dnl have pthread_condattr_setclock() available from the threading library,
+dnl Copperplate is still able to attach Cobalt condvars to specific clocks
+dnl internally, therefore we don't have to use a restricted clock in
+dnl Copperplate.
+dnl
 dnl In effect this means that updating the host system date may affect
-dnl wait times of blocking services. This is a provision for running
-dnl over legacy threading libraries such as linuxthreads.
+dnl wait times of all blocking services implemented by Copperplate over
+dnl Mercury, but will only affect explicit calls to pthread_cond_timedwait()
+dnl over Cobalt.
+dnl
+dnl This is a provision for running over legacy threading libraries
+dnl such as linuxthreads.
 dnl
 dnl CAUTION: the CLOCK_COPPERPLATE value is part of the ABI between
 dnl the Xenomai core libraries and the applications. Therefore it shall
@@ -539,8 +549,11 @@ dnl remain stable even if applications depend on a 
different libc
 dnl than Xenomai libraries were built against originally. Hence the
 dnl built-in CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED flag, which
 dnl won't vary for a given Xenomai installation.
-AC_CHECK_FUNC(pthread_condattr_setclock,,
-    [AC_DEFINE(CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED, 1,[config])])
+
+if test $rtcore_type = mercury; then
+   AC_CHECK_FUNC(pthread_condattr_setclock,,
+        [AC_DEFINE(CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED, 1,[config])])
+fi
 
 dnl Check that Copperplate can implement a shared heap if
 dnl --enable-pshared was given.
diff --git a/include/copperplate/clockobj.h b/include/copperplate/clockobj.h
index f480214..736463f 100644
--- a/include/copperplate/clockobj.h
+++ b/include/copperplate/clockobj.h
@@ -30,7 +30,7 @@
 /*
  * We normally define the Copperplate clock as a monotonic,
  * non-adjustable one, unless the threading library has restrictions
- * to support this.
+ * to support this over Mercury.
  *
  * In the normal case, this means that ongoing delays and timeouts
  * won't be affected when the host system date is changed. In the
@@ -119,20 +119,6 @@ int clockobj_destroy(struct clockobj *clkobj);
  * equivalent to Copperplate TSC units, and Copperplate ticks are
  * periods of the reference clockobj which Cobalt does not know about.
  */
-#ifdef CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED
-
-static inline sticks_t clockobj_ns_to_tsc(sticks_t ns)
-{
-       return ns;
-}
-
-static inline sticks_t clockobj_tsc_to_ns(sticks_t tsc)
-{
-       return tsc;
-}
-
-#else /* !CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED */
-
 static inline sticks_t clockobj_ns_to_tsc(sticks_t ns)
 {
        return cobalt_ns_to_ticks(ns);
@@ -143,8 +129,6 @@ static inline sticks_t clockobj_tsc_to_ns(sticks_t tsc)
        return cobalt_ticks_to_ns(tsc);
 }
 
-#endif /* !CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED */
-
 static inline
 void clockobj_ns_to_timespec(ticks_t ns, struct timespec *ts)
 {
diff --git a/lib/alchemy/cond.c b/lib/alchemy/cond.c
index 376189b..00c2852 100644
--- a/lib/alchemy/cond.c
+++ b/lib/alchemy/cond.c
@@ -102,6 +102,13 @@ static struct registry_operations registry_ops;
  *
  * @note Condition variables can be shared by multiple processes which
  * belong to the same Xenomai session.
+ *
+ * @attention If the underlying threading library does not support
+ * pthread_condattr_setclock(), timings with Alchemy condition
+ * variables will be based on CLOCK_REALTIME, and may therefore be
+ * affected by updates to the system date (e.g. NTP). This typically
+ * concerns legacy setups based on the linuxthreads library.
+ * In the normal case, timings are based on CLOCK_MONOTONIC.
  */
 int rt_cond_create(RT_COND *cond, const char *name)
 {
@@ -128,6 +135,13 @@ int rt_cond_create(RT_COND *cond, const char *name)
        generate_name(ccb->name, name, &cond_namegen);
        pthread_condattr_init(&cattr);
        pthread_condattr_setpshared(&cattr, mutex_scope_attribute);
+       /*
+        * pthread_condattr_setclock() may return ENOSYS over Cobalt
+        * if not actually implemented by the threading library, but
+        * only by the compat placeholder. In such a case, timings
+        * will be based on CLOCK_REALTIME, which is an accepted
+        * restriction.
+        */
        pthread_condattr_setclock(&cattr, CLOCK_COPPERPLATE);
        __RT(pthread_cond_init(&ccb->cond, &cattr));
        pthread_condattr_destroy(&cattr);
diff --git a/lib/copperplate/clockobj.c b/lib/copperplate/clockobj.c
index 8ee3ed7..b908fd7 100644
--- a/lib/copperplate/clockobj.c
+++ b/lib/copperplate/clockobj.c
@@ -232,26 +232,8 @@ int clockobj_set_resolution(struct clockobj *clkobj, 
unsigned int resolution_ns)
 #include <asm/xenomai/tsc.h>
 
 #ifdef CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED
-
-ticks_t clockobj_get_tsc(void)
-{
-       struct timespec now;
-
-       /*
-        * Rare case with legacy uClibc+linuxthreads combo over
-        * Cobalt, we actually return nanoseconds just like in the
-        * Mercury case.
-        */
-       __RT(clock_gettime(CLOCK_REALTIME, &now));
-       return xnarch_ullmul(now.tv_sec, 1000000000) + now.tv_nsec;
-}
-
-ticks_t clockobj_get_time(struct clockobj *clkobj)
-{
-       return clockobj_ns_to_ticks(clkobj, clockobj_get_tsc());
-}
-
-#else /* !CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED */
+#error "restricted CLOCK_COPPERPLATE not available"
+#endif
 
 /*
  * NOTE: we can't inline this routine, as we don't want to expose
@@ -269,8 +251,6 @@ ticks_t clockobj_get_time(struct clockobj *clkobj)
        return clockobj_ns_to_ticks(clkobj, ns);
 }
 
-#endif /* !CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED */
-
 #ifndef CONFIG_XENO_LORES_CLOCK_DISABLED
 
 sticks_t clockobj_ns_to_ticks(struct clockobj *clkobj, sticks_t ns)
@@ -303,10 +283,20 @@ void clockobj_get_date(struct clockobj *clkobj, ticks_t 
*pticks)
 ticks_t clockobj_get_tsc(void)
 {
        struct timespec now;
-       __RT(clock_gettime(CLOCK_COPPERPLATE, &now));
+       clock_gettime(CLOCK_COPPERPLATE, &now);
        return (ticks_t)now.tv_sec * 1000000000ULL + now.tv_nsec;
 }
 
+ticks_t clockobj_get_time(struct clockobj *clkobj)
+{
+       ticks_t ns = clockobj_get_tsc();
+
+       if (clockobj_get_resolution(clkobj) > 1)
+               return ns / clockobj_get_resolution(clkobj);
+
+       return ns;
+}
+
 #ifndef CONFIG_XENO_LORES_CLOCK_DISABLED
 
 sticks_t clockobj_ns_to_ticks(struct clockobj *clkobj, sticks_t ns)
@@ -316,27 +306,13 @@ sticks_t clockobj_ns_to_ticks(struct clockobj *clkobj, 
sticks_t ns)
 
 #endif /* !CONFIG_XENO_LORES_CLOCK_DISABLED */
 
-ticks_t clockobj_get_time(struct clockobj *clkobj)
-{
-       struct timespec now;
-
-       __RT(clock_gettime(CLOCK_COPPERPLATE, &now));
-
-       /* Convert the time value to ticks, with no offset. */
-       if (clockobj_get_resolution(clkobj) > 1)
-               return (ticks_t)now.tv_sec * clockobj_get_frequency(clkobj)
-                       + (ticks_t)now.tv_nsec / 
clockobj_get_resolution(clkobj);
-
-       return timespec_scalar(&now);
-}
-
 void clockobj_get_date(struct clockobj *clkobj, ticks_t *pticks)
 {
        struct timespec now, date;
 
        read_lock_nocancel(&clkobj->lock);
 
-       __RT(clock_gettime(CLOCK_COPPERPLATE, &now));
+       clock_gettime(CLOCK_COPPERPLATE, &now);
 
        /* Add offset from epoch to current system time. */
        timespec_add(&date, &clkobj->offset, &now);


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

Reply via email to