Module: xenomai-head
Branch: master
Commit: 834766db37076e444f7fc1acd8bcffd9975c710c
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=834766db37076e444f7fc1acd8bcffd9975c710c

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Wed Nov 11 10:35:27 2009 +0100

nucleus: Fix endless loop of DEBUG_SYNCH_RELAX

When a thread is about to block on a mutex resource that is currently
held by a relaxed thread, it will receive SIGXCPU if the relaxed owner
debugging feature is enable. But after the signal is delivered and
handled, the sleeper will restart the mutex service and then receive the
same signal over and over again.

Fix this fatal loop by temporarily disabling the warning for the sleeper
after the first delivery, but also rearming it for the next run right
after that. This will still cause re-deliveries for the same blocking
call if the sleeper may fall out due to a different signal delivery. But
endless loops will be avoided and the solution is kept simple.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 include/nucleus/thread.h |    1 +
 ksrc/nucleus/synch.c     |   11 ++++++++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/nucleus/thread.h b/include/nucleus/thread.h
index 389a12b..1124eb4 100644
--- a/include/nucleus/thread.h
+++ b/include/nucleus/thread.h
@@ -62,6 +62,7 @@
 #define XNFPU     0x00100000 /**< Thread uses FPU */
 #define XNSHADOW  0x00200000 /**< Shadow thread */
 #define XNROOT    0x00400000 /**< Root thread (that is, Linux/IDLE) */
+#define XNSWREP   0x00800000 /**< Mode switch already reported */
 
 /*! @} */ /* Ends doxygen comment group: nucleus_state_flags */
 
diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c
index 816c7ab..1a9bbb4 100644
--- a/ksrc/nucleus/synch.c
+++ b/ksrc/nucleus/synch.c
@@ -987,9 +987,12 @@ EXPORT_SYMBOL_GPL(xnsynch_release_all_ownerships);
  */
 void xnsynch_detect_relaxed_owner(struct xnsynch *synch, struct xnthread 
*sleeper)
 {
-       if (xnthread_test_state(sleeper, XNTRAPSW) &&
-           xnthread_test_state(synch->owner, XNRELAX))
+       if (xnthread_test_state(sleeper, XNTRAPSW|XNSWREP) == XNTRAPSW &&
+           xnthread_test_state(synch->owner, XNRELAX)) {
+               xnthread_set_state(sleeper, XNSWREP);
                xnshadow_send_sig(sleeper, SIGXCPU, 0, 1);
+       } else
+               xnthread_clear_state(sleeper,  XNSWREP);
 }
 
 /*
@@ -1010,8 +1013,10 @@ void xnsynch_detect_claimed_relax(struct xnthread *owner)
                for (ht = getheadpq(&synch->pendq); ht != NULL;
                     ht = nextpq(&synch->pendq, ht)) {
                        sleeper = link2thread(ht, plink);
-                       if (xnthread_test_state(sleeper, XNRELAX))
+                       if (xnthread_test_state(sleeper, XNRELAX)) {
+                               xnthread_set_state(sleeper, XNSWREP);
                                xnshadow_send_sig(sleeper, SIGXCPU, 0, 1);
+                       }
                }
        }
 }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to