[rtems commit] bsps/clock: Fix fast idle clock tick support

Sebastian Huber sebh at rtems.org
Thu Jul 23 08:57:41 UTC 2020


Module:    rtems
Branch:    master
Commit:    33314eb60acc23e4a98c9f037631b6f35513d511
Changeset: http://git.rtems.org/rtems/commit/?id=33314eb60acc23e4a98c9f037631b6f35513d511

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Jul 23 08:42:59 2020 +0200

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.

---

 bsps/powerpc/shared/clock/clock-ppc-dec.c | 12 +++++++++---
 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 798cf2a..a1f9ebd 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 f3b2565..dad7130 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;
 



More information about the vc mailing list