Module: xenomai-jki Branch: for-upstream Commit: e6b0910e2eb0178120b9f8170420e760516c3cbb URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=e6b0910e2eb0178120b9f8170420e760516c3cbb
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..84d5164 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