source: rtems/testsuites/smptests/smpcache01/init.c @ 54835ae

Last change on this file since 54835ae was 54835ae, checked in by Sebastian Huber <sebastian.huber@…>, on Feb 1, 2017 at 1:10:18 PM

Rename CONFIGURE_SMP_MAXIMUM_PROCESSORS

Rename CONFIGURE_SMP_MAXIMUM_PROCESSORS to CONFIGURE_MAXIMUM_PROCESSORS
since the SMP part is superfluous.

Update #2894.

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 * Copyright (c) 2014 Aeroflex Gaisler AB.  All rights reserved.
3 *
4 * The license and distribution terms for this file may be
5 * found in the file LICENSE in this distribution or at
6 * http://www.rtems.org/license/LICENSE.
7 */
8
9#ifdef HAVE_CONFIG_H
10  #include "config.h"
11#endif
12
13#include <rtems/score/atomic.h>
14#include <rtems/score/smpbarrier.h>
15#include <rtems/score/smpimpl.h>
16#include <rtems.h>
17#include <limits.h>
18#include <string.h>
19
20#include "tmacros.h"
21
22const char rtems_test_name[] = "SMPCACHE 1";
23
24CPU_STRUCTURE_ALIGNMENT static int data_to_flush[1024];
25
26#define CPU_COUNT 32
27
28#define WORKER_PRIORITY 100
29
30typedef struct {
31  SMP_barrier_Control barrier;
32  uint32_t count[CPU_COUNT];
33} test_context;
34
35static test_context ctx = {
36  .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
37};
38
39static void function_to_flush( void )
40{
41  /* Does nothing. Used to give a pointer to instruction address space. */
42}
43
44static void test_action( void *arg )
45{
46  rtems_test_assert(arg == &ctx);
47
48  ctx.count[rtems_get_current_processor()]++;
49}
50
51typedef void ( *test_case )(
52  size_t set_size,
53  const cpu_set_t *cpu_set,
54  SMP_barrier_State *bs
55);
56
57static void test_cache_flush_multiple_data_lines(
58  size_t set_size,
59  const cpu_set_t *cpu_set,
60  SMP_barrier_State *bs
61)
62{
63  rtems_cache_flush_multiple_data_lines_processor_set( &data_to_flush,
64      sizeof(data_to_flush), set_size, cpu_set );
65}
66
67static void test_cache_invalidate_multiple_data_lines(
68  size_t set_size,
69  const cpu_set_t *cpu_set,
70  SMP_barrier_State *bs
71)
72{
73  rtems_cache_invalidate_multiple_data_lines_processor_set( &data_to_flush,
74      sizeof(data_to_flush), set_size, cpu_set );
75}
76
77static void test_cache_flush_entire_data(
78  size_t set_size,
79  const cpu_set_t *cpu_set,
80  SMP_barrier_State *bs
81)
82{
83  rtems_cache_flush_entire_data_processor_set( set_size, cpu_set );
84}
85
86static void test_cache_invalidate_entire_instruction(
87  size_t set_size,
88  const cpu_set_t *cpu_set,
89  SMP_barrier_State *bs
90)
91{
92  rtems_cache_invalidate_entire_instruction();
93}
94
95static void test_cache_invalidate_multiple_instruction_lines(
96  size_t set_size,
97  const cpu_set_t *cpu_set,
98  SMP_barrier_State *bs
99)
100{
101  rtems_cache_invalidate_multiple_instruction_lines( &function_to_flush,
102      4 /* arbitrary size */ );
103}
104
105static void test_broadcast_action(
106  size_t set_size,
107  const cpu_set_t *cpu_set,
108  SMP_barrier_State *bs
109)
110{
111  ctx.count[rtems_get_current_processor()] = 0;
112  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
113
114  _SMP_Multicast_action( set_size, cpu_set, test_action, &ctx );
115
116  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
117
118  rtems_test_assert( ctx.count[rtems_get_current_processor()] ==
119      rtems_get_processor_count() );
120}
121
122static test_case test_cases[] = {
123  test_cache_flush_multiple_data_lines,
124  test_cache_invalidate_multiple_data_lines,
125  test_cache_flush_entire_data,
126  test_cache_invalidate_entire_instruction,
127  test_cache_invalidate_multiple_instruction_lines,
128  test_broadcast_action
129};
130
131static void call_test(
132  size_t set_size,
133  const cpu_set_t *cpu_set,
134  SMP_barrier_State *bs,
135  size_t i
136)
137{
138  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
139  ( *test_cases[ i ] )( set_size, cpu_set, bs );
140  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
141}
142
143static void call_tests( size_t set_size,
144    const cpu_set_t *cpu_set, SMP_barrier_State *bs  )
145{
146  size_t i;
147
148  for (i = 0; i < RTEMS_ARRAY_SIZE( test_cases ); ++i) {
149    call_test( set_size, cpu_set, bs, i );
150  }
151}
152
153static void call_tests_isr_disabled( size_t set_size,
154    const cpu_set_t *cpu_set, SMP_barrier_State *bs  )
155{
156  size_t i;
157
158  for (i = 0; i < RTEMS_ARRAY_SIZE( test_cases ); ++i) {
159    ISR_Level isr_level;
160
161    _ISR_Local_disable( isr_level );
162
163    call_test( set_size, cpu_set, bs, i );
164
165    _ISR_Local_enable( isr_level );
166  }
167}
168
169static void call_tests_with_thread_dispatch_disabled( size_t set_size,
170    const cpu_set_t *cpu_set, SMP_barrier_State *bs )
171{
172  size_t i;
173
174  for (i = 0; i < RTEMS_ARRAY_SIZE( test_cases ); ++i) {
175    Per_CPU_Control *cpu_self;
176
177    cpu_self = _Thread_Dispatch_disable();
178
179    call_test( set_size, cpu_set, bs, i );
180
181    _Thread_Dispatch_enable( cpu_self );
182  }
183}
184
185static void cmlog(  const char* str )
186{
187  if ( rtems_get_current_processor() == 0 )
188    printf( "%s", str );
189}
190
191static void all_tests( void )
192{
193  uint32_t cpu_count = rtems_get_processor_count();
194  size_t set_size = CPU_ALLOC_SIZE( rtems_get_processor_count() );
195  cpu_set_t *cpu_set = CPU_ALLOC( rtems_get_processor_count() );
196  SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER;
197
198  /* Send message to all available CPUs */
199  CPU_FILL_S( set_size, cpu_set );
200
201  /* Call test cases */
202  cmlog( "Calling test cases. " );
203  call_tests( set_size, cpu_set, &bs );
204  cmlog( "Done!\n");
205
206  /* Call test cases with ISR disabled */
207  cmlog( "Calling test cases with ISR disabled. " );
208  call_tests_isr_disabled( set_size, cpu_set, &bs );
209  cmlog( "Done!\n" );
210
211  /* Call test cases with thread dispatch disabled */
212  cmlog( "Calling test cases with thread_dispatch_disabled. ");
213  call_tests_with_thread_dispatch_disabled( set_size, cpu_set, &bs );
214  cmlog( "Done!\n");
215
216  /* Done. Free up memory. */
217  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count);
218  CPU_FREE( cpu_set );
219}
220
221static void worker_task(rtems_task_argument arg)
222{
223  rtems_status_code sc;
224
225  all_tests();
226
227  sc = rtems_task_suspend(RTEMS_SELF);
228  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
229}
230
231static void test_smp_cache_manager( void )
232{
233  rtems_status_code sc;
234  size_t worker_index;
235  uint32_t cpu_count = rtems_get_processor_count();
236
237  for (worker_index = 1; worker_index < cpu_count; ++worker_index) {
238    rtems_id worker_id;
239
240    sc = rtems_task_create(
241      rtems_build_name('W', 'R', 'K', '0'+worker_index),
242      WORKER_PRIORITY,
243      RTEMS_MINIMUM_STACK_SIZE,
244      RTEMS_DEFAULT_MODES,
245      RTEMS_DEFAULT_ATTRIBUTES,
246      &worker_id
247    );
248    rtems_test_assert( sc == RTEMS_SUCCESSFUL );
249
250    sc = rtems_task_start( worker_id, worker_task, 0 );
251    rtems_test_assert( sc == RTEMS_SUCCESSFUL );
252  }
253
254  all_tests();
255}
256
257
258static void Init(rtems_task_argument arg)
259{
260  TEST_BEGIN();
261
262  test_smp_cache_manager();
263
264  TEST_END();
265  rtems_test_exit(0);
266}
267
268#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
269#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
270
271#define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
272
273#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
274
275#define CONFIGURE_MAXIMUM_TIMERS 1
276
277#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
278
279#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
280
281#define CONFIGURE_INIT
282
283#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.