[Xenomai-git] Philippe Gerum : cobalt/thread: generalize usage of -> lock_count for preemption control
Module: xenomai-3 Branch: master Commit: 14b92fe692c930178a31bacc6f01c73f6d455dbf URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=14b92fe692c930178a31bacc6f01c73f6d455dbf Author: Philippe Gerum Date: Tue Jun 30 20:36:25 2015 +0200 cobalt/thread: generalize usage of ->lock_count for preemption control XNLOCK is uselessly mirroring only part of the information ->lock_count conveys. We only need to keep XNLOCK as a mode bit in the ABI between the Cobalt core and lib/cobalt for switching the lock from user-space, using ->lock_count internally for testing the current preemption state. --- include/cobalt/kernel/sched.h |5 +++-- include/cobalt/kernel/thread.h |2 +- include/cobalt/uapi/kernel/thread.h |8 kernel/cobalt/posix/thread.c|2 ++ kernel/cobalt/sched-rt.c|9 - kernel/cobalt/sched.c | 14 +++--- kernel/cobalt/thread.c | 25 + 7 files changed, 38 insertions(+), 27 deletions(-) diff --git a/include/cobalt/kernel/sched.h b/include/cobalt/kernel/sched.h index 1a2c6eb..ecd9605 100644 --- a/include/cobalt/kernel/sched.h +++ b/include/cobalt/kernel/sched.h @@ -359,7 +359,7 @@ static inline int xnsched_interrupt_p(void) static inline int xnsched_locked_p(void) { - return xnthread_test_state(xnsched_current_thread(), XNLOCK); + return xnsched_current_thread()->lock_count > 0; } static inline int xnsched_root_p(void) @@ -526,7 +526,8 @@ static inline void xnsched_tick(struct xnsched *sched) */ if (sched_class == curr->base_class && sched_class->sched_tick && - xnthread_test_state(curr, XNTHREAD_BLOCK_BITS|XNLOCK|XNRRB) == XNRRB) + xnthread_test_state(curr, XNTHREAD_BLOCK_BITS|XNRRB) == XNRRB && + curr->lock_count == 0) sched_class->sched_tick(sched); } diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h index 45a9e6f..cc2e32c 100644 --- a/include/cobalt/kernel/thread.h +++ b/include/cobalt/kernel/thread.h @@ -38,7 +38,7 @@ * @{ */ #define XNTHREAD_BLOCK_BITS (XNSUSP|XNPEND|XNDELAY|XNDORMANT|XNRELAX|XNMIGRATE|XNHELD) -#define XNTHREAD_MODE_BITS(XNLOCK|XNRRB|XNWARN|XNTRAPLB) +#define XNTHREAD_MODE_BITS(XNRRB|XNWARN|XNTRAPLB) struct xnthread; struct xnsched; diff --git a/include/cobalt/uapi/kernel/thread.h b/include/cobalt/uapi/kernel/thread.h index eba9c01..474271f 100644 --- a/include/cobalt/uapi/kernel/thread.h +++ b/include/cobalt/uapi/kernel/thread.h @@ -39,10 +39,9 @@ #define XNRELAX 0x0080 /**< Relaxed shadow thread (blocking bit) */ #define XNMIGRATE 0x0100 /**< Thread is currently migrating to another CPU. */ #define XNHELD0x0200 /**< Thread is held to process emergency. */ - #define XNBOOST 0x0400 /**< Undergoes a PIP boost */ #define XNSSTEP 0x0800 /**< Single-stepped by debugger */ -#define XNLOCK0x1000 /**< Holds the scheduler lock (i.e. not preemptible) */ +#define XNLOCK0x1000 /**< Scheduler lock control (pseudo-bit, not in ->state) */ #define XNRRB 0x2000 /**< Undergoes a round-robin scheduling */ #define XNWARN0x4000 /**< Issue SIGDEBUG on error detection */ #define XNFPU 0x8000 /**< Thread uses FPU */ @@ -50,7 +49,7 @@ #define XNWEAK0x0002 /**< Non real-time shadow (from the WEAK class) */ #define XNUSER0x0004 /**< Shadow thread running in userland */ #define XNJOINED 0x0008 /**< Another thread waits for joining this thread */ -#define XNTRAPLB 0x0010 /**< Trap lock break (i.e. may not sleep with XNLOCK) */ +#define XNTRAPLB 0x0010 /**< Trap lock break (i.e. may not sleep with sched lock) */ #define XNDEBUG 0x0020 /**< User-level debugging enabled */ /** @} */ @@ -94,8 +93,9 @@ * 'r' -> Undergoes round-robin. * 't' -> Mode switches trapped. * 'L' -> Lock breaks trapped. + * 'd' -> Debug mode turned on. */ -#define XNTHREAD_STATE_LABELS "SWDRU..X.HbTlrt.L" +#define XNTHREAD_STATE_LABELS "SWDRU..X.HbTlrt.Ld" struct xnthread_user_window { __u32 state; diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c index ad694aa..00397fc 100644 --- a/kernel/cobalt/posix/thread.c +++ b/kernel/cobalt/posix/thread.c @@ -822,6 +822,8 @@ COBALT_SYSCALL(thread_getstat, current, stat.xsc = xnstat_counter_get(&thread->stat.xsc); stat.pf = xnstat_counter_get(&thread->stat.pf); stat.status = xnthread_get_state(thread); + if (thread->lock_count > 0) + stat.status |= XNLOCK; stat.timeout = xnthread_get_timeout(thread, xnclock_read_monotonic(&nkclock)); strcpy(stat.name, thread->name); diff --git a/kernel/cobalt/sched-rt.c b/kernel/cobalt/sched-rt.c index 3bd9308..1973863 100644 --- a/kernel/cobalt/sched-rt.c +++ b/kernel/cobalt/sched-rt.c @@ -73,11 +73,
[Xenomai-git] Philippe Gerum : cobalt/thread: generalize usage of -> lock_count for preemption control
Module: xenomai-3 Branch: next Commit: 14b92fe692c930178a31bacc6f01c73f6d455dbf URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=14b92fe692c930178a31bacc6f01c73f6d455dbf Author: Philippe Gerum Date: Tue Jun 30 20:36:25 2015 +0200 cobalt/thread: generalize usage of ->lock_count for preemption control XNLOCK is uselessly mirroring only part of the information ->lock_count conveys. We only need to keep XNLOCK as a mode bit in the ABI between the Cobalt core and lib/cobalt for switching the lock from user-space, using ->lock_count internally for testing the current preemption state. --- include/cobalt/kernel/sched.h |5 +++-- include/cobalt/kernel/thread.h |2 +- include/cobalt/uapi/kernel/thread.h |8 kernel/cobalt/posix/thread.c|2 ++ kernel/cobalt/sched-rt.c|9 - kernel/cobalt/sched.c | 14 +++--- kernel/cobalt/thread.c | 25 + 7 files changed, 38 insertions(+), 27 deletions(-) diff --git a/include/cobalt/kernel/sched.h b/include/cobalt/kernel/sched.h index 1a2c6eb..ecd9605 100644 --- a/include/cobalt/kernel/sched.h +++ b/include/cobalt/kernel/sched.h @@ -359,7 +359,7 @@ static inline int xnsched_interrupt_p(void) static inline int xnsched_locked_p(void) { - return xnthread_test_state(xnsched_current_thread(), XNLOCK); + return xnsched_current_thread()->lock_count > 0; } static inline int xnsched_root_p(void) @@ -526,7 +526,8 @@ static inline void xnsched_tick(struct xnsched *sched) */ if (sched_class == curr->base_class && sched_class->sched_tick && - xnthread_test_state(curr, XNTHREAD_BLOCK_BITS|XNLOCK|XNRRB) == XNRRB) + xnthread_test_state(curr, XNTHREAD_BLOCK_BITS|XNRRB) == XNRRB && + curr->lock_count == 0) sched_class->sched_tick(sched); } diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h index 45a9e6f..cc2e32c 100644 --- a/include/cobalt/kernel/thread.h +++ b/include/cobalt/kernel/thread.h @@ -38,7 +38,7 @@ * @{ */ #define XNTHREAD_BLOCK_BITS (XNSUSP|XNPEND|XNDELAY|XNDORMANT|XNRELAX|XNMIGRATE|XNHELD) -#define XNTHREAD_MODE_BITS(XNLOCK|XNRRB|XNWARN|XNTRAPLB) +#define XNTHREAD_MODE_BITS(XNRRB|XNWARN|XNTRAPLB) struct xnthread; struct xnsched; diff --git a/include/cobalt/uapi/kernel/thread.h b/include/cobalt/uapi/kernel/thread.h index eba9c01..474271f 100644 --- a/include/cobalt/uapi/kernel/thread.h +++ b/include/cobalt/uapi/kernel/thread.h @@ -39,10 +39,9 @@ #define XNRELAX 0x0080 /**< Relaxed shadow thread (blocking bit) */ #define XNMIGRATE 0x0100 /**< Thread is currently migrating to another CPU. */ #define XNHELD0x0200 /**< Thread is held to process emergency. */ - #define XNBOOST 0x0400 /**< Undergoes a PIP boost */ #define XNSSTEP 0x0800 /**< Single-stepped by debugger */ -#define XNLOCK0x1000 /**< Holds the scheduler lock (i.e. not preemptible) */ +#define XNLOCK0x1000 /**< Scheduler lock control (pseudo-bit, not in ->state) */ #define XNRRB 0x2000 /**< Undergoes a round-robin scheduling */ #define XNWARN0x4000 /**< Issue SIGDEBUG on error detection */ #define XNFPU 0x8000 /**< Thread uses FPU */ @@ -50,7 +49,7 @@ #define XNWEAK0x0002 /**< Non real-time shadow (from the WEAK class) */ #define XNUSER0x0004 /**< Shadow thread running in userland */ #define XNJOINED 0x0008 /**< Another thread waits for joining this thread */ -#define XNTRAPLB 0x0010 /**< Trap lock break (i.e. may not sleep with XNLOCK) */ +#define XNTRAPLB 0x0010 /**< Trap lock break (i.e. may not sleep with sched lock) */ #define XNDEBUG 0x0020 /**< User-level debugging enabled */ /** @} */ @@ -94,8 +93,9 @@ * 'r' -> Undergoes round-robin. * 't' -> Mode switches trapped. * 'L' -> Lock breaks trapped. + * 'd' -> Debug mode turned on. */ -#define XNTHREAD_STATE_LABELS "SWDRU..X.HbTlrt.L" +#define XNTHREAD_STATE_LABELS "SWDRU..X.HbTlrt.Ld" struct xnthread_user_window { __u32 state; diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c index ad694aa..00397fc 100644 --- a/kernel/cobalt/posix/thread.c +++ b/kernel/cobalt/posix/thread.c @@ -822,6 +822,8 @@ COBALT_SYSCALL(thread_getstat, current, stat.xsc = xnstat_counter_get(&thread->stat.xsc); stat.pf = xnstat_counter_get(&thread->stat.pf); stat.status = xnthread_get_state(thread); + if (thread->lock_count > 0) + stat.status |= XNLOCK; stat.timeout = xnthread_get_timeout(thread, xnclock_read_monotonic(&nkclock)); strcpy(stat.name, thread->name); diff --git a/kernel/cobalt/sched-rt.c b/kernel/cobalt/sched-rt.c index 3bd9308..1973863 100644 --- a/kernel/cobalt/sched-rt.c +++ b/kernel/cobalt/sched-rt.c @@ -73,11 +73,10
[Xenomai-git] Philippe Gerum : cobalt/thread: generalize usage of -> lock_count for preemption control
Module: xenomai-3 Branch: next Commit: 97e32440e9675ba91cdf80b320a35979b935dd8c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=97e32440e9675ba91cdf80b320a35979b935dd8c Author: Philippe Gerum Date: Tue Jun 30 20:36:25 2015 +0200 cobalt/thread: generalize usage of ->lock_count for preemption control XNLOCK is uselessly mirroring only part of the information ->lock_count conveys. We only need to keep XNLOCK as a mode bit in the ABI between the Cobalt core and lib/cobalt for switching the lock from user-space, using ->lock_count internally for testing the current preemption state. --- include/cobalt/kernel/sched.h |5 +++-- include/cobalt/kernel/thread.h |2 +- include/cobalt/uapi/kernel/thread.h |5 ++--- kernel/cobalt/sched-rt.c|9 - kernel/cobalt/sched.c | 10 +++--- kernel/cobalt/thread.c | 25 + 6 files changed, 30 insertions(+), 26 deletions(-) diff --git a/include/cobalt/kernel/sched.h b/include/cobalt/kernel/sched.h index 1a2c6eb..ecd9605 100644 --- a/include/cobalt/kernel/sched.h +++ b/include/cobalt/kernel/sched.h @@ -359,7 +359,7 @@ static inline int xnsched_interrupt_p(void) static inline int xnsched_locked_p(void) { - return xnthread_test_state(xnsched_current_thread(), XNLOCK); + return xnsched_current_thread()->lock_count > 0; } static inline int xnsched_root_p(void) @@ -526,7 +526,8 @@ static inline void xnsched_tick(struct xnsched *sched) */ if (sched_class == curr->base_class && sched_class->sched_tick && - xnthread_test_state(curr, XNTHREAD_BLOCK_BITS|XNLOCK|XNRRB) == XNRRB) + xnthread_test_state(curr, XNTHREAD_BLOCK_BITS|XNRRB) == XNRRB && + curr->lock_count == 0) sched_class->sched_tick(sched); } diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h index 45a9e6f..cc2e32c 100644 --- a/include/cobalt/kernel/thread.h +++ b/include/cobalt/kernel/thread.h @@ -38,7 +38,7 @@ * @{ */ #define XNTHREAD_BLOCK_BITS (XNSUSP|XNPEND|XNDELAY|XNDORMANT|XNRELAX|XNMIGRATE|XNHELD) -#define XNTHREAD_MODE_BITS(XNLOCK|XNRRB|XNWARN|XNTRAPLB) +#define XNTHREAD_MODE_BITS(XNRRB|XNWARN|XNTRAPLB) struct xnthread; struct xnsched; diff --git a/include/cobalt/uapi/kernel/thread.h b/include/cobalt/uapi/kernel/thread.h index eba9c01..6c714f7 100644 --- a/include/cobalt/uapi/kernel/thread.h +++ b/include/cobalt/uapi/kernel/thread.h @@ -39,10 +39,9 @@ #define XNRELAX 0x0080 /**< Relaxed shadow thread (blocking bit) */ #define XNMIGRATE 0x0100 /**< Thread is currently migrating to another CPU. */ #define XNHELD0x0200 /**< Thread is held to process emergency. */ - #define XNBOOST 0x0400 /**< Undergoes a PIP boost */ #define XNSSTEP 0x0800 /**< Single-stepped by debugger */ -#define XNLOCK0x1000 /**< Holds the scheduler lock (i.e. not preemptible) */ +#define XNLOCK0x1000 /**< Scheduler lock control (pseudo-bit, not in ->state) */ #define XNRRB 0x2000 /**< Undergoes a round-robin scheduling */ #define XNWARN0x4000 /**< Issue SIGDEBUG on error detection */ #define XNFPU 0x8000 /**< Thread uses FPU */ @@ -50,7 +49,7 @@ #define XNWEAK0x0002 /**< Non real-time shadow (from the WEAK class) */ #define XNUSER0x0004 /**< Shadow thread running in userland */ #define XNJOINED 0x0008 /**< Another thread waits for joining this thread */ -#define XNTRAPLB 0x0010 /**< Trap lock break (i.e. may not sleep with XNLOCK) */ +#define XNTRAPLB 0x0010 /**< Trap lock break (i.e. may not sleep with sched lock) */ #define XNDEBUG 0x0020 /**< User-level debugging enabled */ /** @} */ diff --git a/kernel/cobalt/sched-rt.c b/kernel/cobalt/sched-rt.c index 3bd9308..1973863 100644 --- a/kernel/cobalt/sched-rt.c +++ b/kernel/cobalt/sched-rt.c @@ -73,11 +73,10 @@ static void xnsched_rt_rotate(struct xnsched *sched, * before we were called. The same goes if the current thread * holds the scheduler lock. */ - if (thread == curr && - xnthread_test_state(curr, XNTHREAD_BLOCK_BITS | XNLOCK)) - return; - - xnsched_putback(thread); + if (thread != curr || + (!xnthread_test_state(curr, XNTHREAD_BLOCK_BITS) && +curr->lock_count == 0)) + xnsched_putback(thread); } void xnsched_rt_tick(struct xnsched *sched) diff --git a/kernel/cobalt/sched.c b/kernel/cobalt/sched.c index d394ce8..bda61a6 100644 --- a/kernel/cobalt/sched.c +++ b/kernel/cobalt/sched.c @@ -252,7 +252,7 @@ struct xnthread *xnsched_pick_next(struct xnsched *sched) * Do not preempt the current thread if it holds the * scheduler lock. */ - if (xnthread_test_state(curr, XNLOCK)) { + if (curr->lock_count > 0) {