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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Oct  2 16:13:11 2013 +0200

cobalt/thread: introduce mode bit for disabling lock breaking

This commit introduces XNTRAPLB, a new thread mode bit for disabling
the scheduler lock breaking feature.

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 immediately with XNBREAK set from
xnthread_suspend().

The consequence of disabling the lock breaking feature may range from
-EINTR received by the offending API service, to entering an infinite
loop if the userland code restarts the syscall upon -EINTR. In the
latter case, the watchdog should trigger.

---

 include/cobalt/kernel/thread.h      |    2 +-
 include/cobalt/uapi/kernel/thread.h |    3 +-
 kernel/cobalt/thread.c              |   43 ++++++++++++++++++++++-------------
 3 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h
index 3434536..4539c15 100644
--- a/include/cobalt/kernel/thread.h
+++ b/include/cobalt/kernel/thread.h
@@ -34,7 +34,7 @@
 #include <asm/xenomai/thread.h>
 
 #define XNTHREAD_BLOCK_BITS   
(XNSUSP|XNPEND|XNDELAY|XNDORMANT|XNRELAX|XNMIGRATE|XNHELD)
-#define XNTHREAD_MODE_BITS    (XNLOCK|XNRRB|XNTRAPSW)
+#define XNTHREAD_MODE_BITS    (XNLOCK|XNRRB|XNTRAPSW|XNTRAPLB)
 
 struct xnthread;
 struct xnsched;
diff --git a/include/cobalt/uapi/kernel/thread.h 
b/include/cobalt/uapi/kernel/thread.h
index b359f7a..a5f6e24 100644
--- a/include/cobalt/uapi/kernel/thread.h
+++ b/include/cobalt/uapi/kernel/thread.h
@@ -50,6 +50,7 @@
 #define XNWEAK    0x00020000 /**< Non real-time shadow (from the WEAK class) */
 #define XNUSER    0x00040000 /**< Shadow thread running in userland */
 #define XNJOINED  0x00080000 /**< Another thread waits for joining this thread 
*/
+#define XNTRAPLB  0x00100000 /**< Trap lock break (i.e. may not sleep with 
XNLOCK) */
 
 /** @} */
 
@@ -91,7 +92,7 @@
  * 'r' -> Undergoes round-robin.
  * 't' -> Mode switches trapped.
  */
-#define XNTHREAD_STATE_LABELS  "SWDRU..X.HbTlrt...."
+#define XNTHREAD_STATE_LABELS  "SWDRU..X.HbTlrt.....L"
 
 /**
  * @brief Structure containing thread information.
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index fbc7e84..c5825ef 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -702,6 +702,11 @@ EXPORT_SYMBOL_GPL(xnthread_start);
  * switches to secondary mode. This is a debugging aid for detecting
  * spurious relaxes.
  *
+ * - XNTRAPLB 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 immediately with XNBREAK set from xnthread_suspend().
+ *
  * Environments:
  *
  * This service can be called from:
@@ -862,19 +867,16 @@ void xnthread_suspend(xnthread_t *thread, int mask,
         * task in the root context, to collect and act upon the
         * pending Linux signal (see handle_sigwake_event()).
         */
-       if (!xnthread_test_state(thread, XNTHREAD_BLOCK_BITS)) {
-               if ((mask & XNRELAX) == 0 &&
-                   xnthread_test_info(thread, XNKICKED)) {
-                       if (wchan) {
-                               thread->wchan = wchan;
-                               xnsynch_forget_sleeper(thread);
-                       }
-                       xnthread_clear_info(thread, XNRMID | XNTIMEO);
-                       xnthread_set_info(thread, XNBREAK);
-                       xnlock_put_irqrestore(&nklock, s);
-                       return;
+       if ((oldstate & XNTHREAD_BLOCK_BITS) == 0) {
+               if ((mask & XNRELAX) == 0) {
+                       if (xnthread_test_info(thread, XNKICKED))
+                               goto abort;
+                       if (thread == sched->curr &&
+                           (oldstate & (XNTRAPLB|XNLOCK)) == (XNTRAPLB|XNLOCK))
+                               goto abort;
                }
-               xnthread_clear_info(thread, XNRMID | XNTIMEO | XNBREAK | 
XNWAKEN | XNROBBED);
+               xnthread_clear_info(thread,
+                                   XNRMID|XNTIMEO|XNBREAK|XNWAKEN|XNROBBED);
        }
 
        /*
@@ -890,12 +892,12 @@ void xnthread_suspend(xnthread_t *thread, int mask,
                                xnsynch_forget_sleeper(thread);
                        }
                        xnthread_set_info(thread, XNTIMEO);
-                       goto unlock_and_exit;
+                       goto out;
                }
                xnthread_set_state(thread, XNDELAY);
        }
 
-       if (xnthread_test_state(thread, XNREADY)) {
+       if (oldstate & XNREADY) {
                xnsched_dequeue(thread);
                xnthread_clear_state(thread, XNREADY);
        }
@@ -937,7 +939,7 @@ void xnthread_suspend(xnthread_t *thread, int mask,
                 * xnsched_run will trigger the IPI as required.
                 */
                xnsched_run();
-               goto unlock_and_exit;
+               goto out;
        }
 
        /*
@@ -984,8 +986,17 @@ void xnthread_suspend(xnthread_t *thread, int mask,
        if (((oldstate & (XNTHREAD_BLOCK_BITS|XNUSER)) == (XNRELAX|XNUSER)) &&
            (mask & (XNDELAY | XNSUSP | XNHELD)) != 0)
                xnshadow_send_sig(thread, SIGSHADOW, SIGSHADOW_ACTION_HARDEN);
+out:
+       xnlock_put_irqrestore(&nklock, s);
+       return;
 
-unlock_and_exit:
+abort:
+       if (wchan) {
+               thread->wchan = wchan;
+               xnsynch_forget_sleeper(thread);
+       }
+       xnthread_clear_info(thread, XNRMID | XNTIMEO);
+       xnthread_set_info(thread, XNBREAK);
        xnlock_put_irqrestore(&nklock, s);
 }
 EXPORT_SYMBOL_GPL(xnthread_suspend);


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

Reply via email to