[PATCH 2/7] spcache01: Add test for multiprocessor extensions
Ralf Kirchner
ralf.kirchner at embedded-brains.de
Wed Apr 30 08:01:20 UTC 2014
Add test which ensures that a cache invalidate executed by one processor is seen by another processor
---
testsuites/sptests/spcache01/init.c | 143 ++++++++++++++++++++++++++++++++++-
1 Datei geändert, 141 Zeilen hinzugefügt(+), 2 Zeilen entfernt(-)
diff --git a/testsuites/sptests/spcache01/init.c b/testsuites/sptests/spcache01/init.c
index 303f7f6..57dd0e7 100644
--- a/testsuites/sptests/spcache01/init.c
+++ b/testsuites/sptests/spcache01/init.c
@@ -21,6 +21,7 @@
#include <rtems.h>
#include <rtems/counter.h>
+#include <rtems/score/smpbarrier.h>
#define TESTS_USE_PRINTF
#include "tmacros.h"
@@ -35,8 +36,140 @@ const char rtems_test_name[] = "SPCACHE 1";
#define I512() I64(); I64(); I64(); I64(); I64(); I64(); I64(); I64()
+#if defined( RTEMS_SMP )
+ #define TEST_SMP_TASK_COUNT 1
+#else
+ #define TEST_SMP_TASK_COUNT 0
+#endif /* defined( RTEMS_SMP ) */
+
+#define TEST_SMP_PROCESSOR_COUNT 2
+
+#define TASK_PRIORITY 1
+
CPU_STRUCTURE_ALIGNMENT static int data[1024];
+#if defined( RTEMS_SMP )
+typedef enum {
+ TEST_STATUS_INITIALIZING,
+ TEST_STATUS_EVALUATING,
+ TEST_STATUS_FINISHED
+} test_status;
+
+typedef struct {
+ SMP_barrier_Control barrier;
+ test_status status;
+ volatile int *vdata;
+} test_context;
+
+static test_context test_instance = {
+ SMP_BARRIER_CONTROL_INITIALIZER,
+ TEST_STATUS_INITIALIZING,
+ &data[0] /* Verification start address */
+};
+
+static rtems_task test_multiprocessor_extensions_task( rtems_task_argument arg )
+{
+ SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER;
+ rtems_interrupt_lock lock;
+ rtems_interrupt_lock_context lock_context;
+ int *tdata = &data[0];
+
+ (void)arg;
+ rtems_interrupt_lock_initialize(&lock, "test");
+ rtems_interrupt_lock_acquire(&lock, &lock_context);
+
+ _SMP_barrier_Wait(&test_instance.barrier, &bs, TEST_SMP_PROCESSOR_COUNT);
+
+ /* Make sure we don't have the cache line cached */
+ rtems_cache_invalidate_multiple_data_lines(
+ &tdata[0],
+ sizeof(tdata[0])
+ );
+
+ _SMP_barrier_Wait(&test_instance.barrier, &bs, TEST_SMP_PROCESSOR_COUNT);
+
+ /* Now the other task should also get the cache line invalidated */
+ rtems_cache_invalidate_multiple_data_lines(
+ &tdata[0],
+ sizeof(tdata[0])
+ );
+ test_instance.status = TEST_STATUS_FINISHED;
+
+ _SMP_barrier_Wait(&test_instance.barrier, &bs, TEST_SMP_PROCESSOR_COUNT);
+
+ rtems_interrupt_lock_release(&lock, &lock_context);
+ rtems_interrupt_lock_destroy(&lock);
+
+ rtems_task_delete(RTEMS_SELF);
+}
+#endif /* defined( RTEMS_SMP ) */
+
+static void test_multiprocessor_extensions( void )
+{
+#if defined( RTEMS_SMP )
+ rtems_interrupt_lock lock;
+ rtems_interrupt_lock_context lock_context;
+ SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER;
+ rtems_id id_work1 = RTEMS_ID_NONE;
+ int *tdata = &data[0];
+ rtems_status_code sc;
+ const int PATTERN = 0x89ABCDEF;
+
+ printf("test for multiprocessor extensions handling\n");
+
+
+ rtems_interrupt_lock_initialize(&lock, "test");
+ rtems_interrupt_lock_acquire(&lock, &lock_context);
+
+ sc = rtems_task_create(
+ rtems_build_name('W', 'R', 'K', '1'),
+ TASK_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id_work1
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(id_work1, test_multiprocessor_extensions_task, 0);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ _SMP_barrier_Wait(&test_instance.barrier, &bs, TEST_SMP_PROCESSOR_COUNT);
+
+ /* Make sure we don't have the cache line cached */
+ rtems_cache_invalidate_multiple_data_lines(
+ &tdata[0],
+ sizeof(tdata[0])
+ );
+
+ /* Initialize */
+ tdata[0] = PATTERN;
+
+ /* Flush initialized cache line to RAM */
+ rtems_cache_flush_multiple_data_lines(
+ &tdata[0],
+ sizeof(tdata[0])
+ );
+
+ /* Modify cache line in cache only */
+ tdata[0] = ~PATTERN;
+
+ /* Have the other task invalidate the cache line */
+ test_instance.status = TEST_STATUS_EVALUATING;
+ _SMP_barrier_Wait(&test_instance.barrier, &bs, TEST_SMP_PROCESSOR_COUNT);
+
+ _SMP_barrier_Wait(&test_instance.barrier, &bs, TEST_SMP_PROCESSOR_COUNT);
+
+ /* The other task has invalidated the cache, thus we should read what was flushed to RAM */
+ rtems_test_assert(test_instance.vdata[0] == PATTERN);
+
+ rtems_interrupt_lock_release(&lock, &lock_context);
+ rtems_interrupt_lock_destroy(&lock);
+
+ printf("test for multiprocessor extensions passed\n");
+#endif /* defined( RTEMS_SMP ) */
+}
+
static void test_misalignment( const bool write_through )
{
if (rtems_cache_get_data_line_size() > 0) {
@@ -647,18 +780,24 @@ static void Init(rtems_task_argument arg)
write_through = test_data_flush_and_invalidate();
test_misalignment( write_through );
test_timing();
+ test_multiprocessor_extensions();
TEST_END();
rtems_test_exit(0);
}
-#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#if defined( RTEMS_SMP )
+ #define CONFIGURE_SMP_APPLICATION
+ #define CONFIGURE_SMP_MAXIMUM_PROCESSORS 32
+#endif /* defined( RTEMS_SMP ) */
+#define CONFIGURE_INIT_TASK_PRIORITY TASK_PRIORITY
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
-#define CONFIGURE_MAXIMUM_TASKS 1
+#define CONFIGURE_MAXIMUM_TASKS (1 + TEST_SMP_TASK_COUNT)
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
--
1.7.10.4
More information about the devel
mailing list