[PATCH] smptests/smpcache01: Test the SMP cache manager

Daniel Cederman cederman at gaisler.com
Mon Jul 14 15:40:19 UTC 2014


Invokes SMP cache management routines under different scenarios.
---
 testsuites/smptests/Makefile.am               |    1 +
 testsuites/smptests/configure.ac              |    1 +
 testsuites/smptests/smpcache01/Makefile.am    |   19 ++
 testsuites/smptests/smpcache01/init.c         |  291 +++++++++++++++++++++++++
 testsuites/smptests/smpcache01/smpcache01.doc |   16 ++
 testsuites/smptests/smpcache01/smpcache01.scn |   14 ++
 6 files changed, 342 insertions(+)
 create mode 100644 testsuites/smptests/smpcache01/Makefile.am
 create mode 100644 testsuites/smptests/smpcache01/init.c
 create mode 100644 testsuites/smptests/smpcache01/smpcache01.doc
 create mode 100644 testsuites/smptests/smpcache01/smpcache01.scn

diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am
index 70a53a7..9076b8e 100644
--- a/testsuites/smptests/Makefile.am
+++ b/testsuites/smptests/Makefile.am
@@ -11,6 +11,7 @@ SUBDIRS += smp08
 SUBDIRS += smp09
 SUBDIRS += smpaffinity01
 SUBDIRS += smpatomic01
+SUBDIRS += smpcache01
 SUBDIRS += smpfatal01
 SUBDIRS += smpfatal02
 SUBDIRS += smpfatal03
diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac
index 79b3bf8..c53a460 100644
--- a/testsuites/smptests/configure.ac
+++ b/testsuites/smptests/configure.ac
@@ -66,6 +66,7 @@ smp08/Makefile
 smp09/Makefile
 smpaffinity01/Makefile
 smpatomic01/Makefile
+smpcache01/Makefile
 smpfatal01/Makefile
 smpfatal02/Makefile
 smpfatal03/Makefile
diff --git a/testsuites/smptests/smpcache01/Makefile.am b/testsuites/smptests/smpcache01/Makefile.am
new file mode 100644
index 0000000..3b092bc
--- /dev/null
+++ b/testsuites/smptests/smpcache01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smpcache01
+smpcache01_SOURCES = init.c
+
+dist_rtems_tests_DATA = smpcache01.scn smpcache01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(smpcache01_OBJECTS)
+LINK_LIBS = $(smpcache01_LDLIBS)
+
+smpcache01$(EXEEXT): $(smpcache01_OBJECTS) $(smpcache01_DEPENDENCIES)
+	@rm -f smpcache01$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smpcache01/init.c b/testsuites/smptests/smpcache01/init.c
new file mode 100644
index 0000000..dd2f9f1
--- /dev/null
+++ b/testsuites/smptests/smpcache01/init.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2014 Aeroflex Gaisler AB.  All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/score/atomic.h>
+#include <rtems/score/smpbarrier.h>
+#include <rtems.h>
+#include <limits.h>
+#include <string.h>
+
+#include "tmacros.h"
+
+const char rtems_test_name[] = "SMPCACHE 1";
+
+#define CPU_COUNT 32
+
+#define WORKER_PRIORITY 100
+
+typedef void (*Cache_manager_Function_ptr)(const void *d_addr, size_t n_bytes);
+
+void
+_Cache_manager_Send_smp_msg(
+    const size_t setsize,
+    const cpu_set_t *set,
+    Cache_manager_Function_ptr func,
+    const void * addr,
+    size_t size
+  );
+
+typedef struct {
+  SMP_barrier_Control barrier;
+  uint32_t count[CPU_COUNT];
+} test_context;
+
+static test_context ctx = {
+  .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
+};
+
+static void test_cache_message( const void *d_addr, size_t n_bytes )
+{
+  rtems_test_assert(n_bytes == 123);
+  rtems_test_assert(d_addr == 0);
+
+  ctx.count[rtems_get_current_processor()]++;
+}
+
+static void all_cache_manager_smp_functions( size_t set_size,
+    cpu_set_t *cpu_set )
+{
+  rtems_cache_flush_multiple_data_lines_processor_set( 0, 10, set_size,
+      cpu_set );
+  rtems_cache_invalidate_multiple_data_lines_processor_set( 0, 10, set_size,
+      cpu_set );
+  rtems_cache_flush_entire_data_processor_set( set_size, cpu_set );
+  rtems_cache_invalidate_entire_data_processor_set( set_size, cpu_set );
+  rtems_cache_invalidate_entire_instruction();
+  rtems_cache_invalidate_multiple_instruction_lines( 0, 10 );
+}
+
+static void standard_funcs_test( size_t set_size, cpu_set_t *cpu_set )
+{
+  all_cache_manager_smp_functions( set_size, cpu_set );
+}
+
+static void standard_funcs_isrdisabled_test( size_t set_size,
+    cpu_set_t *cpu_set, SMP_barrier_State *bs  )
+{
+  ISR_Level isr_level;
+
+  _ISR_Disable_without_giant( isr_level );
+
+  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
+
+  all_cache_manager_smp_functions( set_size, cpu_set );
+
+  _ISR_Enable_without_giant( isr_level );
+}
+
+static void standard_funcs_giant_taken_test( size_t set_size,
+    cpu_set_t *cpu_set, SMP_barrier_State *bs )
+{
+  if ( rtems_get_current_processor() == 0)
+    _Giant_Acquire();
+
+  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
+
+  all_cache_manager_smp_functions( set_size, cpu_set );
+
+  if ( rtems_get_current_processor() == 0)
+    _Giant_Release();
+}
+
+static void test_func_test( size_t set_size, cpu_set_t *cpu_set,
+    SMP_barrier_State *bs )
+{
+  ctx.count[rtems_get_current_processor()] = 0;
+  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
+
+  _Cache_manager_Send_smp_msg( set_size, cpu_set, test_cache_message, 0, 123 );
+
+  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
+
+  rtems_test_assert( ctx.count[rtems_get_current_processor()] ==
+      rtems_get_processor_count() );
+}
+
+static void test_func_isrdisabled_test( size_t set_size, cpu_set_t *cpu_set,
+    SMP_barrier_State *bs )
+{
+  ISR_Level isr_level;
+
+  ctx.count[rtems_get_current_processor()] = 0;
+  _ISR_Disable_without_giant( isr_level );
+
+  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
+
+  _Cache_manager_Send_smp_msg( set_size, cpu_set, test_cache_message, 0, 123 );
+
+  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
+
+  rtems_test_assert( ctx.count[rtems_get_current_processor()] ==
+      rtems_get_processor_count() );
+
+  _ISR_Enable_without_giant( isr_level );
+}
+
+static void test_func_giant_taken_test( size_t set_size, cpu_set_t *cpu_set,
+    SMP_barrier_State *bs )
+{
+  ctx.count[rtems_get_current_processor()] = 0;
+
+  if ( rtems_get_current_processor() == 0)
+    _Giant_Acquire();
+
+  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
+
+  _Cache_manager_Send_smp_msg( set_size, cpu_set, test_cache_message, 0, 123 );
+
+  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
+
+  rtems_test_assert( ctx.count[rtems_get_current_processor()] ==
+      rtems_get_processor_count() );
+
+  if ( rtems_get_current_processor() == 0)
+    _Giant_Release();
+}
+
+static void cmlog(  const char* str )
+{
+  if ( rtems_get_current_processor() == 0 )
+    printf( "%s", str );
+}
+
+static void all_tests( void )
+{
+  uint32_t cpu_count = rtems_get_processor_count();
+  size_t set_size = CPU_ALLOC_SIZE( rtems_get_processor_count() );
+  cpu_set_t *cpu_set = CPU_ALLOC( rtems_get_processor_count() );
+  SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER;
+
+  /* Send message to all available CPUs */
+  CPU_FILL_S( set_size, cpu_set );
+
+  /* Call all SMP cache manager functions */
+  cmlog( "Calling all standard SMP cache functions\n" );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  standard_funcs_test( set_size, cpu_set );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  cmlog( "Done!\n");
+
+  /* Call all SMP cache manager functions with ISR disabled */
+  cmlog( "Calling all standard SMP cache functions. With ISR disabled\n" );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  standard_funcs_isrdisabled_test( set_size, cpu_set, &bs );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  cmlog( "Done!\n" );
+
+  /* Call all SMP cache manager functions with core 0 holding the giant lock */
+  cmlog( "Calling all standard SMP cache functions. With CPU0 holding "
+      "the giant lock\n" );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  standard_funcs_giant_taken_test( set_size, cpu_set, &bs );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  cmlog( "Done!\n");
+
+  /* Call a test function using SMP cache manager and verify that all
+   * cores invoke the function */
+  cmlog( "Calling a test function using the SMP cache manager to "
+      "verify that all CPUs receive the SMP message\n" );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  test_func_test( set_size, cpu_set, &bs );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  cmlog( "Done!\n");
+
+  /* Call a test function using SMP cache manager and verify that all
+   * cores invoke the function. ISR disabled. */
+  cmlog( "Calling a test function using the SMP cache manager to "
+      "verify that all CPUs receive the SMP message. With ISR disabled\n" );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  test_func_isrdisabled_test( set_size, cpu_set, &bs );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  cmlog( "Done!\n" );
+
+  /* Call a test function using SMP cache manager and verify that all
+   * cores invoke the function. Core 0 holding giant lock. */
+  cmlog( "Calling a test function using the SMP cache manager to "
+      "verify that all CPUs receive the SMP message. With CPU0 "
+      "holding the giant lock\n" );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  test_func_giant_taken_test( set_size, cpu_set, &bs );
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
+  cmlog( "Done!\n" );
+
+  /* Done. Free up memory. */
+  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count);
+  CPU_FREE( cpu_set );
+}
+
+static void worker_task(rtems_task_argument arg)
+{
+  rtems_status_code sc;
+
+  all_tests();
+
+  sc = rtems_task_suspend(RTEMS_SELF);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_smp_cache_manager( void )
+{
+  rtems_status_code sc;
+  size_t worker_index;
+  uint32_t cpu_count = rtems_get_processor_count();
+
+  for (worker_index = 1; worker_index < cpu_count; ++worker_index) {
+    rtems_id worker_id;
+
+    sc = rtems_task_create(
+      rtems_build_name('W', 'R', 'K', '0'+worker_index),
+      WORKER_PRIORITY,
+      RTEMS_MINIMUM_STACK_SIZE,
+      RTEMS_DEFAULT_MODES,
+      RTEMS_DEFAULT_ATTRIBUTES,
+      &worker_id
+    );
+    rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+
+    sc = rtems_task_start( worker_id, worker_task, 0 );
+    rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+  }
+
+  all_tests();
+}
+
+
+static void Init(rtems_task_argument arg)
+{
+  TEST_BEGIN();
+
+  test_smp_cache_manager();
+
+  TEST_END();
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_SMP_APPLICATION
+
+#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
+
+#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
+
+#define CONFIGURE_MAXIMUM_TIMERS 1
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/smptests/smpcache01/smpcache01.doc b/testsuites/smptests/smpcache01/smpcache01.doc
new file mode 100644
index 0000000..f6041b2
--- /dev/null
+++ b/testsuites/smptests/smpcache01/smpcache01.doc
@@ -0,0 +1,16 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpcache01
+
+directives:
+
+  - rtems_cache_flush_multiple_data_lines_processor_set
+  - rtems_cache_invalidate_multiple_data_lines_processor_set
+  - rtems_cache_flush_entire_data_processor_set
+  - rtems_cache_invalidate_entire_data_processor_set
+  - rtems_cache_invalidate_entire_instruction
+  - rtems_cache_invalidate_multiple_instruction_lines
+
+concepts:
+
+  - Ensure that cache related SMP messages are delivered properly.
diff --git a/testsuites/smptests/smpcache01/smpcache01.scn b/testsuites/smptests/smpcache01/smpcache01.scn
new file mode 100644
index 0000000..5964d3e
--- /dev/null
+++ b/testsuites/smptests/smpcache01/smpcache01.scn
@@ -0,0 +1,14 @@
+*** BEGIN OF TEST SMPCACHE 1 ***
+Calling all standard SMP cache functions
+Done!
+Calling all standard SMP cache functions. With ISR disabled
+Done!
+Calling all standard SMP cache functions. With CPU0 holding the giant lock
+Done!
+Calling a test function using the SMP cache manager to verify that all CPUs receive the SMP message
+Done!
+Calling a test function using the SMP cache manager to verify that all CPUs receive the SMP message. With ISR disabled
+Done!
+Calling a test function using the SMP cache manager to verify that all CPUs receive the SMP message. With CPU0 holding the giant lock
+Done!
+*** END OF TEST SMPCACHE 1 ***
-- 
1.7.9.5




More information about the devel mailing list