diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-07-23 08:42:59 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-07-23 08:56:06 +0200 |
commit | 33314eb60acc23e4a98c9f037631b6f35513d511 (patch) | |
tree | a8c2de7e0af2e160de11390785e416ae382d2b3e | |
parent | score: Improve _Thread_Start() description (diff) | |
download | rtems-33314eb60acc23e4a98c9f037631b6f35513d511.tar.bz2 |
bsps/clock: Fix fast idle clock tick support
If we interrupt a thread dispatch critical section (thread dispatch
disable level != ISR nest level), then we should not do the fast idle
mode since this may delay an ongoing system call forever.
-rw-r--r-- | bsps/powerpc/shared/clock/clock-ppc-dec.c | 12 | ||||
-rw-r--r-- | bsps/shared/dev/clock/clockimpl.h | 19 |
2 files changed, 22 insertions, 9 deletions
diff --git a/bsps/powerpc/shared/clock/clock-ppc-dec.c b/bsps/powerpc/shared/clock/clock-ppc-dec.c index 798cf2a75b..a1f9ebd599 100644 --- a/bsps/powerpc/shared/clock/clock-ppc-dec.c +++ b/bsps/powerpc/shared/clock/clock-ppc-dec.c @@ -98,15 +98,21 @@ void clockOn(void* unused) static void clockHandler(void) { #if (CLOCK_DRIVER_USE_FAST_IDLE == 1) - rtems_interrupt_level level; - uint32_t tb; + rtems_interrupt_level level; + uint32_t tb; + Per_CPU_Control *cpu_self; rtems_interrupt_disable(level); tb = ppc_time_base(); rtems_timecounter_tick(); + cpu_self = _Per_CPU_Get(); - while ( _Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle ) { + while ( + cpu_self->thread_dispatch_disable_level == cpu_self->isr_nest_level + && cpu_self->heir == cpu_self->executing + && cpu_self->executing->is_idle + ) { tb += Clock_Decrementer_value; ppc_set_time_base( tb ); rtems_timecounter_tick(); diff --git a/bsps/shared/dev/clock/clockimpl.h b/bsps/shared/dev/clock/clockimpl.h index f3b2565c56..dad71307f4 100644 --- a/bsps/shared/dev/clock/clockimpl.h +++ b/bsps/shared/dev/clock/clockimpl.h @@ -143,16 +143,23 @@ rtems_isr Clock_isr( #if CLOCK_DRIVER_USE_FAST_IDLE { - struct timecounter *tc = _Timecounter; - uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); - uint32_t interval = (uint32_t) - ((tc->tc_frequency * us_per_tick) / 1000000); - Clock_driver_timecounter_tick(); if (_SMP_Get_processor_maximum() == 1) { + struct timecounter *tc; + uint64_t us_per_tick; + uint32_t interval; + Per_CPU_Control *cpu_self; + + cpu_self = _Per_CPU_Get(); + tc = _Timecounter; + us_per_tick = rtems_configuration_get_microseconds_per_tick(); + interval = (uint32_t) ((tc->tc_frequency * us_per_tick) / 1000000); + while ( - _Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle + cpu_self->thread_dispatch_disable_level == cpu_self->isr_nest_level + && cpu_self->heir == cpu_self->executing + && cpu_self->executing->is_idle ) { ISR_lock_Context lock_context; |