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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sat Jul 11 17:25:15 2015 +0200

cobalt/kernel: make most SIGDEBUG notifications depend on XNWARN

Only two situations are still unconditionally reported via SIGDEBUG,
regardless of XNWARN being set or not:

- lack of process memory locking when binding to the core
- mayday trigger

---

 include/cobalt/kernel/thread.h      |    5 ++-
 include/cobalt/uapi/kernel/thread.h |    5 +--
 kernel/cobalt/rtdm/core.c           |    6 +--
 kernel/cobalt/synch.c               |    4 +-
 kernel/cobalt/thread.c              |   17 ++++++---
 lib/cobalt/thread.c                 |   71 ++++++++++++++++++++++++-----------
 6 files changed, 73 insertions(+), 35 deletions(-)

diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h
index ef7de04..8a9236a 100644
--- a/include/cobalt/kernel/thread.h
+++ b/include/cobalt/kernel/thread.h
@@ -502,9 +502,10 @@ static inline void xnthread_get_resource(struct xnthread 
*thread)
 
 static inline int xnthread_put_resource(struct xnthread *thread)
 {
-       if (xnthread_test_state(thread, XNWEAK|XNDEBUG)) {
+       if (xnthread_test_state(thread, XNWEAK) ||
+           IS_ENABLED(CONFIG_XENO_OPT_DEBUG_USER)) {
                if (unlikely(thread->res_count == 0)) {
-                       if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_USER))
+                       if (xnthread_test_state(thread, XNWARN))
                                xnthread_signal(thread, SIGDEBUG,
                                                SIGDEBUG_RESCNT_IMBALANCE);
                        return -EPERM;
diff --git a/include/cobalt/uapi/kernel/thread.h 
b/include/cobalt/uapi/kernel/thread.h
index c053472..89853e8 100644
--- a/include/cobalt/uapi/kernel/thread.h
+++ b/include/cobalt/uapi/kernel/thread.h
@@ -94,11 +94,10 @@
  * 'T' -> Ptraced and stopped.
  * 'l' -> Locks scheduler.
  * 'r' -> Undergoes round-robin.
- * 't' -> Mode switches trapped.
+ * 't' -> Runtime mode errors notified.
  * 'L' -> Lock breaks trapped.
- * 'd' -> Debug mode turned on.
  */
-#define XNTHREAD_STATE_LABELS  "SWDRU..X.HbTlrt.....Ld"
+#define XNTHREAD_STATE_LABELS  "SWDRU..X.HbTlrt.....L."
 
 struct xnthread_user_window {
        __u32 state;
diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c
index d00b0c4..fda3dab 100644
--- a/kernel/cobalt/rtdm/core.c
+++ b/kernel/cobalt/rtdm/core.c
@@ -104,12 +104,12 @@ open_devnode(struct rtdm_device *dev, const char *path, 
int oflag)
        struct file *filp;
        char *filename;
 
-#ifdef CONFIG_XENO_OPT_DEBUG_USER
-       if (strncmp(path, "/dev/rtdm/", 10))
+       if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_USER) &&
+           strncmp(path, "/dev/rtdm/", 10))
                printk(XENO_WARNING
                       "%s[%d] opens obsolete device path: %s\n",
                       current->comm, current->pid, path);
-#endif
+
        filename = kasprintf(GFP_KERNEL, "/dev/rtdm/%s", dev->name);
        if (filename == NULL)
                return ERR_PTR(-ENOMEM);
diff --git a/kernel/cobalt/synch.c b/kernel/cobalt/synch.c
index 536e0a7..f3c9d31 100644
--- a/kernel/cobalt/synch.c
+++ b/kernel/cobalt/synch.c
@@ -171,7 +171,9 @@ int xnsynch_sleep_on(struct xnsynch *synch, xnticks_t 
timeout,
 
        thread = xnthread_current();
 
-       if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_USER) && thread->res_count > 0)
+       if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_USER) &&
+           thread->res_count > 0 &&
+           xnthread_test_state(thread, XNWARN))
                xnthread_signal(thread, SIGDEBUG, SIGDEBUG_RESCNT_SLEEP);
        
        xnlock_get_irqsave(&nklock, s);
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index fa2fffd..acaf1a3 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -166,6 +166,11 @@ int __xnthread_init(struct xnthread *thread,
                ksformat(thread->name,
                         sizeof(thread->name), "@%p", thread);
 
+       /*
+        * We mirror the global user debug state into the per-thread
+        * state, to speed up branch taking in lib/cobalt wherever
+        * this needs to be tested.
+        */
        if (IS_ENABLED(CONFIG_XENO_OPT_DEBUG_USER))
                flags |= XNDEBUG;
 
@@ -706,8 +711,8 @@ EXPORT_SYMBOL_GPL(xnthread_start);
  *
  * - XNLOCK makes the current thread non-preemptible by other threads.
  * Unless XNTRAPLB is also set for the thread, the latter may still
- * block, in which case, the lock will be reacquired automatically
- * when it is scheduled back in.
+ * block, dropping the lock temporarily, in which case, the lock will
+ * be reacquired automatically when the thread resumes execution.
  *
  * - XNWARN enables debugging notifications for the current thread.  A
  * SIGDEBUG (Linux-originated) signal is sent when the following
@@ -718,13 +723,15 @@ EXPORT_SYMBOL_GPL(xnthread_start);
  *
  * - the current thread is about to sleep on a Cobalt mutex currently
  * owned by a thread running in secondary mode, which reveals a
- * priority inversion case.
+ * priority inversion.
  *
  * - the current thread is about to sleep while holding a Cobalt
- * mutex. Blocking on a mutex does not trigger such signal though.
+ * mutex, and CONFIG_XENO_OPT_DEBUG_USER is enabled in the kernel
+ * configuration. Blocking for acquiring a mutex does not trigger such
+ * signal though.
  *
  * - the current thread has both XNTRAPLB and XNLOCK set, and attempts
- * to block on a Cobalt service, causing a lock break.
+ * to block on a Cobalt service, which would cause a lock break.
  *
  * - XNTRAPLB disallows breaking the scheduler lock. In the default
  * case, a thread which holds the scheduler lock is allowed to drop it
diff --git a/lib/cobalt/thread.c b/lib/cobalt/thread.c
index 580c254..2d0023f 100644
--- a/lib/cobalt/thread.c
+++ b/lib/cobalt/thread.c
@@ -332,30 +332,55 @@ COBALT_IMPL(int, pthread_create, (pthread_t *ptid_r,
 /**
  * Set the mode of the current thread.
  *
- * This service sets the mode of the calling thread. @a clrmask and @a setmask
- * are two bit masks which are respectively cleared and set in the calling
- * thread status. They are a bitwise OR of the following values:
- * - PTHREAD_LOCK_SCHED, when set, locks the scheduler, which prevents the
- *   current thread from being switched out until the scheduler
- *   is unlocked;
- * - PTHREAD_WARNSW, when set, causes the signal SIGDEBUG to be sent to the
- *   current thread, whenever it involontary switches to secondary mode;
- * - PTHREAD_CONFORMING can be passed in @a setmask to switch the
- * current user-space task to its preferred runtime mode. The only
- * meaningful use of this switch is to force a real-time shadow back
- * to primary mode. Any other use leads to a nop.
+ * This service sets the mode of the calling thread, which affects its
+ * behavior under particular circumstances. @a clrmask and @a setmask
+ * are two masks of mode bits which are respectively cleared and set
+ * by pthread_setmode_np():
+ *
+ * - PTHREAD_LOCK_SCHED, when set, locks the scheduler, which prevents
+ *   the current thread from being switched out until the scheduler is
+ *   unlocked. Unless PTHREAD_DISABLE_LOCKBREAK is also set, the
+ *   thread may still block, dropping the lock temporarily, in which
+ *   case, the lock will be reacquired automatically when the thread
+ *   resumes execution. When PTHREAD_LOCK_SCHED is cleared, the
+ *   current thread drops the scheduler lock, and the rescheduling
+ *   procedure is initiated.
+ *
+ * - When set, PTHREAD_WARNSW enables debugging notifications for the
+ *   current thread.  A SIGDEBUG (Linux-originated) signal is sent when
+ *   the following atypical or abnormal behavior is detected:
+ *
+ *   - the current thread switches to secondary mode. Such
+ *     notification comes in handy for detecting spurious relaxes.
+ *
+ *   - the current thread is about to sleep on a Cobalt mutex
+ *     currently owned by a thread running in secondary mode, which
+ *     reveals a priority inversion.
+ *
+ *   - the current thread is about to sleep while holding a Cobalt
+ *     mutex, and CONFIG_XENO_OPT_DEBUG_USER is enabled in the kernel
+ *     configuration. Blocking for acquiring a mutex does not trigger
+ *     such signal though.
+ *
+ *   - the current thread has enabled PTHREAD_DISABLE_LOCKBREAK and
+ *     PTHREAD_LOCK_SCHED, then attempts to block on a Cobalt service,
+ *     which would cause a lock break.
+ *
  * - PTHREAD_DISABLE_LOCKBREAK disallows breaking the scheduler
- * lock. In the default case, a thread which holds the scheduler lock
- * is allowed to drop it temporarily for sleeping. If this mode bit is set,
- * such thread would return with EINTR immediately from any blocking call.
+ *   lock. Normally, the scheduler lock is dropped implicitly when the
+ *   current owner blocks, then reacquired automatically when the
+ *   owner resumes execution. If PTHREAD_DISABLE_LOCKBREAK is set, the
+ *   scheduler lock owner would return with EINTR immediately from any
+ *   blocking call instead (see PTHREAD_WARNSW notifications).
  *
- * PTHREAD_LOCK_SCHED and PTHREAD_DISABLE_LOCKBREAK are valid for any
- * Xenomai thread, other bits are valid for Xenomai user-space threads
- * only.
+ * - PTHREAD_CONFORMING can be passed in @a setmask to switch the
+ *   current user-space task to its preferred runtime mode. The only
+ *   meaningful use of this switch is to force a real-time thread back
+ *   to primary mode eagerly. Other usages have no effect.
  *
  * This service is a non-portable extension of the POSIX interface.
  *
- * @param clrmask set of bits to be cleared;
+ * @param clrmask set of bits to be cleared.
  *
  * @param setmask set of bits to be set.
  *
@@ -364,12 +389,16 @@ COBALT_IMPL(int, pthread_create, (pthread_t *ptid_r,
  * of active mode bits. If NULL, the previous set of active mode bits
  * will not be returned.
  *
- * @return 0 on success;
- * @return an error number if:
+ * @return 0 on success, otherwise:
+ *
  * - EINVAL, some bit in @a clrmask or @a setmask is invalid.
  *
  * @note Setting @a clrmask and @a setmask to zero leads to a nop,
  * only returning the previous mode if @a mode_r is a valid address.
+ *
+ * @caution Issuing PTHREAD_CONFORMING is most likely useless or even
+ * introduces pure overhead in regular applications, since the Cobalt
+ * kernel performs the necessary mode switches, only when required.
  */
 int pthread_setmode_np(int clrmask, int setmask, int *mode_r)
 {


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

Reply via email to