This spcache01 test is getting quite large. Does it make sense to split it up?
On Tue, May 27, 2014 at 10:44 AM, Ralf Kirchner <ralf.kirch...@embedded-brains.de> wrote: > Add test which ensures that a cache invalidate executed by one processor is > seen by another processor > --- > testsuites/sptests/spcache01/init.c | 209 > +++++++++++++++++++++++++++++++---- > 1 Datei geändert, 185 Zeilen hinzugefügt(+), 24 Zeilen entfernt(-) > > diff --git a/testsuites/sptests/spcache01/init.c > b/testsuites/sptests/spcache01/init.c > index 303f7f6..99f5ec4 100644 > --- a/testsuites/sptests/spcache01/init.c > +++ b/testsuites/sptests/spcache01/init.c > @@ -21,6 +21,8 @@ > > #include <rtems.h> > #include <rtems/counter.h> > +#include <rtems/score/smpbarrier.h> > +#include <rtems/rtems/smp.h> > > #define TESTS_USE_PRINTF > #include "tmacros.h" > @@ -35,7 +37,145 @@ const char rtems_test_name[] = "SPCACHE 1"; > > #define I512() I64(); I64(); I64(); I64(); I64(); I64(); I64(); I64() > > -CPU_STRUCTURE_ALIGNMENT static int data[1024]; > +#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 > + > +typedef struct { > +#if defined( RTEMS_SMP ) > + SMP_barrier_Control barrier; > +#endif /* defined( RTEMS_SMP ) */ > + CPU_STRUCTURE_ALIGNMENT int data[1024]; > +} test_context; > + > +static test_context test_instance; > + > +#if defined( RTEMS_SMP ) > +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 *data = &test_instance.data[0]; > + > + (void)arg; > + > + > + rtems_interrupt_lock_initialize(&lock, "test"); > + rtems_interrupt_lock_acquire(&lock, &lock_context); > + > + /* Wait for the other task to start it's initialization */ > + _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( > + &data[0], > + sizeof(data[0]) > + ); > + > + /* Wait for the other task to complete it's initialization */ > + _SMP_barrier_Wait(&test_instance.barrier, &bs, TEST_SMP_PROCESSOR_COUNT); > + > + /* Wait for the other task to complete preparations for the invalidation */ > + _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( > + &data[0], > + sizeof(data[0]) > + ); > + > + /* Signal that we have completed the invalidation */ > + _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( const bool write_through ) > +{ > +#if defined( RTEMS_SMP ) > + if( ( ! write_through ) && ( rtems_get_processor_count() > 1 ) ) { > + 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 = &test_instance.data[0]; > + volatile int *vdata = &test_instance.data[0]; > + rtems_status_code sc; > + const int PATTERN = 0x89ABCDEF; > + > + printf("test for multiprocessor extensions handling\n"); > + > + _SMP_barrier_Control_initialize( &test_instance.barrier ); > + > + rtems_interrupt_lock_initialize(&lock, "test"); > + rtems_interrupt_lock_acquire(&lock, &lock_context); > + > + /* Create and start another task for our test. As we are under SMP > conditions, > + * this new task will be operating on another processor */ > + 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); > + > + /* Permit the other task to start it's initialization */ > + _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]) > + ); > + > + /* Wait for the other task to complete it's initialization */ > + _SMP_barrier_Wait(&test_instance.barrier, &bs, TEST_SMP_PROCESSOR_COUNT); > + > + /* Initialize */ > + vdata[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 */ > + vdata[0] = ~PATTERN; > + > + /* Have the other task invalidate the cache line */ > + _SMP_barrier_Wait(&test_instance.barrier, &bs, TEST_SMP_PROCESSOR_COUNT); > + > + /* Wait for the complation of the invalidation by the other task */ > + _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(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 ) > { > @@ -43,12 +183,20 @@ static void test_misalignment( const bool write_through ) > rtems_interrupt_lock lock; > rtems_interrupt_lock_context lock_context; > const uint32_t LINE_SIZE = rtems_cache_get_data_line_size(); > - volatile int *vdata = &data[0]; /* Verification start address */ > - int *tdata = &data[LINE_SIZE / sizeof(data[0])]; /* test start address > (first word in second cache line) */ > + int *data = &data[0]; > + /* Verification start address */ > + volatile int *vdata = data; > + /* test start address (first word in second cache line) */ > + int *tdata = &data[LINE_SIZE / sizeof(data[0])]; > int tcount = 1; /* Words to be tested */ > - size_t tdata_bytes = tcount * sizeof(data[0]); /* Bytes to be tested */ > - size_t vdata_bytes = LINE_SIZE; /* Bytes expected to be affected by > cache maintenance */ > - int vcount = (vdata_bytes / sizeof(data[0])) + (2 * LINE_SIZE / > sizeof(data[0])); /* Words to be verified (Words affected + 2 adjacent cache > lines) */ > + /* Bytes to be tested */ > + size_t tdata_bytes = tcount * sizeof(data[0]); > + /* Bytes expected to be affected by cache maintenance */ > + size_t vdata_bytes = LINE_SIZE; > + /* Words to be verified (Words affected + 2 adjacent cache lines) */ > + int vcount = > + (vdata_bytes / sizeof(data[0])) > + + (2 * LINE_SIZE / sizeof(data[0])); > int i; > int end; > > @@ -174,7 +322,8 @@ static void test_misalignment( const bool write_through ) > * The modified line shall get invalidated/flushed entirely, > * adjacent cache lines shall remain unchanged. > */ > - tdata = &data[(LINE_SIZE / sizeof(data[0])) + ((LINE_SIZE / > sizeof(data[0])) -1)]; > + tdata = &data[(LINE_SIZE / sizeof(data[0])) > + + ((LINE_SIZE / sizeof(data[0])) -1)]; > > for (i = 0; i < vcount; ++i) { > vdata[i] = i; > @@ -232,10 +381,12 @@ static void test_misalignment( const bool write_through > ) > * The modified lines shall get invalidated/flushed entirely, > * adjacent cache lines shall remain unchanged. > */ > - tdata = &data[(LINE_SIZE / sizeof(data[0])) + ((LINE_SIZE / > sizeof(data[0])) -1)]; > + tdata = &data[(LINE_SIZE / sizeof(data[0])) > + + ((LINE_SIZE / sizeof(data[0])) -1)]; > vdata_bytes = LINE_SIZE * 2; > tcount = 2; > - vcount = (vdata_bytes / sizeof(data[0])) + (2 * LINE_SIZE / > sizeof(data[0])); > + vcount = (vdata_bytes / sizeof(data[0])) > + + (2 * LINE_SIZE / sizeof(data[0])); > tdata_bytes = tcount * sizeof(data[0]); > > for (i = 0; i < vcount; ++i) { > @@ -292,13 +443,14 @@ static void test_misalignment( const bool write_through > ) > rtems_interrupt_lock_destroy(&lock); > > printf( > - "data cache operations with misaligned addresses passed the test (%s > cache detected)\n", > - write_through ? "write-through" : "copy-back" > + "data cache operations with misaligned addresses passed the test " > + "(%s cache detected)\n", > + write_through ? "write-through" : "copy-back" > ); > } else { > printf( > - "skip data cache flush and invalidate test with misaligned addresses" > - " due to cache line size of zero\n" > + "skip data cache flush and invalidate test with " > + "misaligned addresses due to cache line size of zero\n" > ); > } > } > @@ -309,7 +461,8 @@ static bool test_data_flush_and_invalidate(void) > if (rtems_cache_get_data_line_size() > 0) { > rtems_interrupt_lock lock; > rtems_interrupt_lock_context lock_context; > - volatile int *vdata = &data[0]; > + int *data = &test_instance.data[0]; > + volatile int *vdata = data; > int n = 32; > int i; > size_t data_size = n * sizeof(data[0]); > @@ -397,7 +550,8 @@ static uint64_t load(void) > rtems_counter_ticks b; > rtems_counter_ticks d; > size_t i; > - volatile int *vdata = &data[0]; > + int *data = &test_instance.data[0]; > + volatile int *vdata = data; > > a = rtems_counter_read(); > for (i = 0; i < RTEMS_ARRAY_SIZE(data); ++i) { > @@ -416,10 +570,10 @@ static uint64_t store(void) > rtems_counter_ticks b; > rtems_counter_ticks d; > size_t i; > - volatile int *vdata = &data[0]; > + volatile int *vdata = &test_instance.data[0]; > > a = rtems_counter_read(); > - for (i = 0; i < RTEMS_ARRAY_SIZE(data); ++i) { > + for (i = 0; i < RTEMS_ARRAY_SIZE(test_instance.data); ++i) { > vdata[i] = 0; > } > b = rtems_counter_read(); > @@ -433,7 +587,8 @@ static void test_timing(void) > { > rtems_interrupt_lock lock; > rtems_interrupt_lock_context lock_context; > - size_t data_size = sizeof(data); > + int *data = &test_instance.data[0]; > + size_t data_size = sizeof(test_instance.data); > uint64_t d[3]; > uint32_t cache_level; > size_t cache_size; > @@ -483,7 +638,7 @@ static void test_timing(void) > > d[0] = load(); > d[1] = load(); > - rtems_cache_flush_multiple_data_lines(&data[0], sizeof(data)); > + rtems_cache_flush_multiple_data_lines(data, sizeof(test_instance.data)); > d[2] = load(); > > rtems_interrupt_lock_release(&lock, &lock_context); > @@ -503,7 +658,7 @@ static void test_timing(void) > > d[0] = load(); > d[1] = load(); > - rtems_cache_invalidate_multiple_data_lines(&data[0], sizeof(data)); > + rtems_cache_invalidate_multiple_data_lines(data, > sizeof(test_instance.data)); > d[2] = load(); > > rtems_interrupt_lock_release(&lock, &lock_context); > @@ -543,7 +698,7 @@ static void test_timing(void) > > d[0] = store(); > d[1] = store(); > - rtems_cache_flush_multiple_data_lines(&data[0], sizeof(data)); > + rtems_cache_flush_multiple_data_lines(data, sizeof(test_instance.data)); > d[2] = store(); > > rtems_interrupt_lock_release(&lock, &lock_context); > @@ -563,7 +718,7 @@ static void test_timing(void) > > d[0] = store(); > d[1] = store(); > - rtems_cache_invalidate_multiple_data_lines(&data[0], sizeof(data)); > + rtems_cache_invalidate_multiple_data_lines(data, > sizeof(test_instance.data)); > d[2] = store(); > > rtems_interrupt_lock_release(&lock, &lock_context); > @@ -647,18 +802,24 @@ static void Init(rtems_task_argument arg) > write_through = test_data_flush_and_invalidate(); > test_misalignment( write_through ); > test_timing(); > + test_multiprocessor_extensions(write_through); > > 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 > > _______________________________________________ > rtems-devel mailing list > rtems-devel@rtems.org > http://www.rtems.org/mailman/listinfo/rtems-devel _______________________________________________ rtems-devel mailing list rtems-devel@rtems.org http://www.rtems.org/mailman/listinfo/rtems-devel