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

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Fri Jun 19 09:55:39 2015 +0200

cobalt/kernel: Rework thread debugging helpers

Factor out register/unregister_debugged_thread helpers to have a single
point where tasks related to preparing/cleaning up ptraced-base thread
debugging can be placed. Put all steps under nklock, which is required
anyway for manipulating xnthread::state and fixes a lurking race. The
timer lock counter can then be converted into a non-atomic variable.

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

---

 include/cobalt/kernel/clock.h |    2 +-
 kernel/cobalt/clock.c         |    6 +++---
 kernel/cobalt/posix/process.c |   35 ++++++++++++++++++++---------------
 3 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
index 35a07c1..70e1c15 100644
--- a/include/cobalt/kernel/clock.h
+++ b/include/cobalt/kernel/clock.h
@@ -89,7 +89,7 @@ extern struct xnclock nkclock;
 
 extern unsigned long nktimerlat;
 
-extern atomic_t nkclklk;
+extern unsigned int nkclock_lock;
 
 int xnclock_register(struct xnclock *clock);
 
diff --git a/kernel/cobalt/clock.c b/kernel/cobalt/clock.c
index 8b8d992..dfaa79e 100644
--- a/kernel/cobalt/clock.c
+++ b/kernel/cobalt/clock.c
@@ -34,7 +34,7 @@
  */
 unsigned long nktimerlat;
 
-atomic_t nkclklk;
+unsigned int nkclock_lock;
 
 static unsigned long long clockfreq;
 
@@ -471,7 +471,7 @@ void print_core_clock_status(struct xnclock *clock,
 {
        const char *tm_status, *wd_status = "";
 
-       tm_status = atomic_read(&nkclklk) > 0 ? "locked" : "on";
+       tm_status = nkclock_lock > 0 ? "locked" : "on";
 #ifdef CONFIG_XENO_OPT_WATCHDOG
        wd_status = "+watchdog";
 #endif /* CONFIG_XENO_OPT_WATCHDOG */
@@ -715,7 +715,7 @@ void xnclock_tick(struct xnclock *clock)
                }
 
                /* Check for a locked clock state (i.e. ptracing). */
-               if (unlikely(atomic_read(&nkclklk) > 0)) {
+               if (unlikely(nkclock_lock > 0)) {
                        if (timer->status & XNTIMER_NOBLCK)
                                goto fire;
                        if (timer->status & XNTIMER_PERIODIC)
diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index 6110da6..828e9e5 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -984,18 +984,26 @@ static inline void init_hostrt(void) { }
 
 #endif /* !CONFIG_XENO_OPT_HOSTRT */
 
-static inline void lock_timers(void)
+/* called with nklock held */
+static void register_debugged_thread(struct xnthread *thread)
 {
-       /* We are covered by the core lock: no barriers needed. */
-       atomic_inc(&nkclklk);
+       nkclock_lock++;
+
+       xnthread_set_state(thread, XNSSTEP);
 }
 
-static inline void unlock_timers(void)
+static void unregister_debugged_thread(struct xnthread *thread)
 {
-       XENO_BUG_ON(COBALT, atomic_read(&nkclklk) == 0);
-       smp_mb__before_atomic();
-       atomic_dec(&nkclklk);
-       smp_mb__after_atomic();
+       spl_t s;
+
+       xnlock_get_irqsave(&nklock, s);
+
+       xnthread_clear_state(thread, XNSSTEP);
+
+       XENO_BUG_ON(COBALT, nkclock_lock == 0);
+       nkclock_lock--;
+
+       xnlock_put_irqrestore(&nklock, s);
 }
 
 static int handle_taskexit_event(struct task_struct *p) /* p == current */
@@ -1014,7 +1022,7 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
        trace_cobalt_shadow_unmap(thread);
 
        if (xnthread_test_state(thread, XNSSTEP))
-               unlock_timers();
+               unregister_debugged_thread(thread);
 
        xnthread_run_handler_stack(thread, exit_thread);
        /* Waiters will receive EIDRM */
@@ -1093,8 +1101,7 @@ static int handle_schedule_event(struct task_struct 
*next_task)
                            sigismember(&pending, SIGINT))
                                goto no_ptrace;
                }
-               xnthread_clear_state(next, XNSSTEP);
-               unlock_timers();
+               unregister_debugged_thread(next);
        }
 
 no_ptrace:
@@ -1146,10 +1153,8 @@ static int handle_sigwake_event(struct task_struct *p)
 
                if (sigismember(&pending, SIGTRAP) ||
                    sigismember(&pending, SIGSTOP)
-                   || sigismember(&pending, SIGINT)) {
-                       xnthread_set_state(thread, XNSSTEP);
-                       lock_timers();
-               }
+                   || sigismember(&pending, SIGINT))
+                       register_debugged_thread(thread);
        }
 
        if (xnthread_test_state(thread, XNRELAX)) {


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

Reply via email to