[PATCH 4/4] score: _CPU_SMP_Get_current_processor()

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Feb 19 13:42:28 UTC 2014


Remove RTEMS_COMPILER_PURE_ATTRIBUTE from _SMP_Get_current_processor()
and all _CPU_SMP_Get_current_processor().  Make inline ASM statements
volatile again.  Test smptests/smpmigration01 showed that GCC optimizes
too much otherwise.
---
 cpukit/score/cpu/arm/rtems/score/cpu.h             |    5 +-
 cpukit/score/cpu/i386/rtems/score/cpu.h            |    2 +-
 cpukit/score/cpu/no_cpu/rtems/score/cpu.h          |    3 +-
 cpukit/score/cpu/powerpc/rtems/score/cpu.h         |    5 +-
 cpukit/score/cpu/sparc/rtems/score/cpu.h           |    6 +--
 cpukit/score/cpu/sparc/rtems/score/sparc.h         |    2 +-
 cpukit/score/include/rtems/score/smp.h             |    3 +-
 testsuites/smptests/smpmigration01/init.c          |   50 +++++++++++++++++--
 .../smptests/smpmigration01/smpmigration01.scn     |   32 ++++++++-----
 9 files changed, 74 insertions(+), 34 deletions(-)

diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h
index a58fa9e..d0ed61f 100644
--- a/cpukit/score/cpu/arm/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/rtems/score/cpu.h
@@ -469,13 +469,12 @@ void _CPU_Context_validate( uintptr_t pattern );
 #ifdef RTEMS_SMP
   uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
 
-  RTEMS_COMPILER_PURE_ATTRIBUTE static inline uint32_t
-    _CPU_SMP_Get_current_processor( void )
+  static inline uint32_t _CPU_SMP_Get_current_processor( void )
   {
     uint32_t mpidr;
 
     /* Use ARMv7 Multiprocessor Affinity Register (MPIDR) */
-    __asm__ (
+    __asm__ volatile (
       "mrc p15, 0, %[mpidr], c0, c0, 5\n"
       : [mpidr] "=&r" (mpidr)
     );
diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h
index 3c37006..047ab69 100644
--- a/cpukit/score/cpu/i386/rtems/score/cpu.h
+++ b/cpukit/score/cpu/i386/rtems/score/cpu.h
@@ -464,7 +464,7 @@ uint32_t   _CPU_ISR_Get_level( void );
 #if defined(RTEMS_SMP)
   uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
 
-  RTEMS_COMPILER_PURE_ATTRIBUTE uint32_t _CPU_SMP_Get_current_processor( void );
+  uint32_t _CPU_SMP_Get_current_processor( void );
 
   void _CPU_SMP_Send_interrupt( uint32_t target_processor_index );
 
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
index e250639..5c34e17 100644
--- a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
+++ b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
@@ -1486,8 +1486,7 @@ CPU_Counter_ticks _CPU_Counter_difference(
    * current processor in the system.  The set of processor indices is the
    * range of integers starting with zero up to the processor count minus one.
    */
-  RTEMS_COMPILER_PURE_ATTRIBUTE static inline uint32_t
-    _CPU_SMP_Get_current_processor( void )
+  static inline uint32_t _CPU_SMP_Get_current_processor( void )
   {
     return 123;
   }
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
index 5e9e5f9..4e6fc74 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
@@ -1036,13 +1036,12 @@ void _CPU_Context_validate( uintptr_t pattern );
 #ifdef RTEMS_SMP
   uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
 
-  RTEMS_COMPILER_PURE_ATTRIBUTE static inline uint32_t
-    _CPU_SMP_Get_current_processor( void )
+  static inline uint32_t _CPU_SMP_Get_current_processor( void )
   {
     uint32_t pir;
 
     /* Use Book E Processor ID Register (PIR) */
-    __asm__ (
+    __asm__ volatile (
       "mfspr %[pir], 286"
       : [pir] "=&r" (pir)
     );
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
index 19454a6..d68b0c0 100644
--- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -1164,14 +1164,12 @@ void _CPU_Context_restore(
   uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
 
   #if defined(__leon__)
-    RTEMS_COMPILER_PURE_ATTRIBUTE static inline uint32_t
-      _CPU_SMP_Get_current_processor( void )
+    static inline uint32_t _CPU_SMP_Get_current_processor( void )
     {
       return _LEON3_Get_current_processor();
     }
   #else
-    RTEMS_COMPILER_PURE_ATTRIBUTE uint32_t
-      _CPU_SMP_Get_current_processor( void );
+    uint32_t _CPU_SMP_Get_current_processor( void );
   #endif
 
   void _CPU_SMP_Send_interrupt( uint32_t target_processor_index );
diff --git a/cpukit/score/cpu/sparc/rtems/score/sparc.h b/cpukit/score/cpu/sparc/rtems/score/sparc.h
index 4539e7d..e52c274 100644
--- a/cpukit/score/cpu/sparc/rtems/score/sparc.h
+++ b/cpukit/score/cpu/sparc/rtems/score/sparc.h
@@ -298,7 +298,7 @@ static inline uint32_t _LEON3_Get_current_processor( void )
 {
   uint32_t asr17;
 
-  __asm__ (
+  __asm__ volatile (
     "rd %%asr17, %0"
     : "=&r" (asr17)
   );
diff --git a/cpukit/score/include/rtems/score/smp.h b/cpukit/score/include/rtems/score/smp.h
index 521cd7b..fcf2036 100644
--- a/cpukit/score/include/rtems/score/smp.h
+++ b/cpukit/score/include/rtems/score/smp.h
@@ -46,8 +46,7 @@ extern "C" {
 #endif
 
 #if defined( RTEMS_SMP )
-  RTEMS_COMPILER_PURE_ATTRIBUTE static inline uint32_t
-    _SMP_Get_current_processor( void )
+  static inline uint32_t _SMP_Get_current_processor( void )
   {
     return _CPU_SMP_Get_current_processor();
   }
diff --git a/testsuites/smptests/smpmigration01/init.c b/testsuites/smptests/smpmigration01/init.c
index 1500dba..2422466 100644
--- a/testsuites/smptests/smpmigration01/init.c
+++ b/testsuites/smptests/smpmigration01/init.c
@@ -16,9 +16,11 @@
   #include "config.h"
 #endif
 
+#define TESTS_USE_PRINTF
 #include "tmacros.h"
 
 #include <stdio.h>
+#include <math.h>
 #include <inttypes.h>
 
 #define CPU_COUNT 2
@@ -102,6 +104,11 @@ static void stopper(rtems_task_argument arg)
   }
 }
 
+static uint32_t abs_delta(uint32_t a, uint32_t b)
+{
+  return a > b ?  a - b : b - a;
+}
+
 static void test(void)
 {
   test_context *ctx = &ctx_instance;
@@ -110,6 +117,8 @@ static void test(void)
   rtems_id stopper_id;
   uint32_t expected_tokens;
   uint32_t total_delta;
+  uint64_t total_cycles;
+  uint32_t average_cycles;
 
   sc = rtems_task_create(
     rtems_build_name('S', 'T', 'O', 'P'),
@@ -144,21 +153,49 @@ static void test(void)
   sc = rtems_task_start(stopper_id, stopper, 0);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
+  total_cycles = 0;
   for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) {
-    test_counters *counters = &ctx->counters[runner_index];
+    const test_counters *counters = &ctx->counters[runner_index];
+    size_t cpu;
+
+    for (cpu = 0; cpu < CPU_COUNT; ++cpu) {
+      total_cycles += counters->cycles_per_cpu[cpu].counter;
+    }
+  }
+  average_cycles = (uint32_t) (total_cycles / (RUNNER_COUNT * CPU_COUNT));
+
+  printf(
+    "total cycles %" PRIu64 "\n"
+    "average cycles %" PRIu32 "\n",
+    total_cycles,
+    average_cycles
+  );
+
+  for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) {
+    const test_counters *counters = &ctx->counters[runner_index];
     size_t cpu;
 
     printf("runner %" PRIuPTR "\n", runner_index);
 
     for (cpu = 0; cpu < CPU_COUNT; ++cpu) {
+      uint32_t tokens = counters->tokens_per_cpu[cpu].counter;
+      uint32_t cycles = counters->cycles_per_cpu[cpu].counter;
+      double cycle_deviation = ((double) cycles - average_cycles)
+        / average_cycles;
+
       printf(
         "\tcpu %zu tokens %" PRIu32 "\n"
-        "\tcpu %zu cycles %" PRIu32 "\n",
+        "\tcpu %zu cycles %" PRIu32 "\n"
+        "\tcpu %zu cycle deviation %f\n",
+        cpu,
+        tokens,
         cpu,
-        counters->tokens_per_cpu[cpu].counter,
+        cycles,
         cpu,
-        counters->cycles_per_cpu[cpu].counter
+        cycle_deviation
       );
+
+      rtems_test_assert(fabs(cycle_deviation) < 0.5);
     }
   }
 
@@ -170,8 +207,7 @@ static void test(void)
 
     for (cpu = 0; cpu < CPU_COUNT; ++cpu) {
       uint32_t tokens = counters->tokens_per_cpu[cpu].counter;
-      uint32_t delta = tokens > expected_tokens ?
-        tokens - expected_tokens : expected_tokens - tokens;
+      uint32_t delta = abs_delta(tokens, expected_tokens);
 
       rtems_test_assert(delta <= 1);
 
@@ -204,6 +240,8 @@ static void Init(rtems_task_argument arg)
 
 #define CONFIGURE_MAXIMUM_TASKS (2 + RUNNER_COUNT)
 
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
 
 #define CONFIGURE_INIT
diff --git a/testsuites/smptests/smpmigration01/smpmigration01.scn b/testsuites/smptests/smpmigration01/smpmigration01.scn
index b2b56ff..ba42cd4 100644
--- a/testsuites/smptests/smpmigration01/smpmigration01.scn
+++ b/testsuites/smptests/smpmigration01/smpmigration01.scn
@@ -1,17 +1,25 @@
 *** TEST SMPMIGRATION 1 ***
+total cycles 94476101
+average cycles 15746016
 runner 0
-        cpu 0 tokens 453284
-        cpu 0 cycles 14955317
-        cpu 1 tokens 453283
-        cpu 1 cycles 14978390
+        cpu 0 tokens 456994
+        cpu 0 cycles 16451659
+        cpu 0 cycle deviation 0.044814
+        cpu 1 tokens 456994
+        cpu 1 cycles 16895680
+        cpu 1 cycle deviation 0.073013
 runner 1
-        cpu 0 tokens 453283
-        cpu 0 cycles 21302793
-        cpu 1 tokens 453283
-        cpu 1 cycles 21318817
+        cpu 0 tokens 456993
+        cpu 0 cycles 20561545
+        cpu 0 cycle deviation 0.305825
+        cpu 1 tokens 456994
+        cpu 1 cycles 20548432
+        cpu 1 cycle deviation 0.304992
 runner 2
-        cpu 0 tokens 453283
-        cpu 0 cycles 19973312
-        cpu 1 tokens 453283
-        cpu 1 cycles 21315227
+        cpu 0 tokens 456994
+        cpu 0 cycles 10007206
+        cpu 0 cycle deviation -0.364461
+        cpu 1 tokens 456993
+        cpu 1 cycles 10011579
+        cpu 1 cycle deviation -0.364183
 *** END OF TEST SMPMIGRATION 1 ***
-- 
1.7.7




More information about the devel mailing list