Let it work during system initialization. --- cpukit/include/rtems/score/smpimpl.h | 3 +- cpukit/score/src/percpu.c | 1 + cpukit/score/src/smpmulticastaction.c | 20 +++++++---- testsuites/smptests/smpmulticast01/init.c | 59 ++++++++++--------------------- 4 files changed, 34 insertions(+), 49 deletions(-)
diff --git a/cpukit/include/rtems/score/smpimpl.h b/cpukit/include/rtems/score/smpimpl.h index a501339176..c0a3ccb610 100644 --- a/cpukit/include/rtems/score/smpimpl.h +++ b/cpukit/include/rtems/score/smpimpl.h @@ -78,7 +78,8 @@ typedef enum { SMP_FATAL_SHUTDOWN, SMP_FATAL_SHUTDOWN_RESPONSE, SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED, - SMP_FATAL_SCHEDULER_PIN_OR_UNPIN_NOT_SUPPORTED + SMP_FATAL_SCHEDULER_PIN_OR_UNPIN_NOT_SUPPORTED, + SMP_FATAL_INVALID_CPU_STATE_TO_PERFORM_JOBS } SMP_Fatal_code; static inline void _SMP_Fatal( SMP_Fatal_code code ) diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c index 0e4c0678e7..e4c3b881e5 100644 --- a/cpukit/score/src/percpu.c +++ b/cpukit/score/src/percpu.c @@ -99,6 +99,7 @@ static void _Per_CPU_State_busy_wait( && state != PER_CPU_STATE_SHUTDOWN ) { _Per_CPU_State_before_multitasking_action( cpu ); + _Per_CPU_Perform_jobs( cpu ); _CPU_SMP_Processor_event_receive(); state = cpu->state; } diff --git a/cpukit/score/src/smpmulticastaction.c b/cpukit/score/src/smpmulticastaction.c index 2288dbe939..69bc87d7e0 100644 --- a/cpukit/score/src/smpmulticastaction.c +++ b/cpukit/score/src/smpmulticastaction.c @@ -31,7 +31,6 @@ #include <rtems/score/smpimpl.h> #include <rtems/score/threaddispatch.h> -#include <rtems/score/sysstate.h> typedef struct Per_CPU_Job { struct Per_CPU_Job *next; @@ -138,11 +137,23 @@ static void _SMP_Wait_for_action_jobs( for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) { if ( _Processor_mask_Is_set( targets, cpu_index ) ) { const Per_CPU_Job *job; + Per_CPU_Control *cpu; job = &jobs[ cpu_index ]; + cpu = _Per_CPU_Get_by_index( cpu_index ); while ( _Atomic_Load_uint( &job->done, ATOMIC_ORDER_ACQUIRE ) == 0 ) { - _Per_CPU_Try_perform_jobs( cpu_self ); + switch ( cpu->state ) { + case PER_CPU_STATE_INITIAL: + case PER_CPU_STATE_READY_TO_START_MULTITASKING: + case PER_CPU_STATE_REQUEST_START_MULTITASKING: + case PER_CPU_STATE_UP: + _Per_CPU_Try_perform_jobs( cpu_self ); + break; + default: + _SMP_Fatal( SMP_FATAL_INVALID_CPU_STATE_TO_PERFORM_JOBS ); + break; + } } } } @@ -161,11 +172,6 @@ void _SMP_Multicast_action( cpu_max = _SMP_Get_processor_maximum(); _Assert( cpu_max <= CPU_MAXIMUM_PROCESSORS ); - if ( ! _System_state_Is_up( _System_state_Get() ) ) { - ( *handler )( arg ); - return; - } - if ( targets == NULL ) { targets = _SMP_Get_online_processors(); } diff --git a/testsuites/smptests/smpmulticast01/init.c b/testsuites/smptests/smpmulticast01/init.c index e599a78bde..c421767b1c 100644 --- a/testsuites/smptests/smpmulticast01/init.c +++ b/testsuites/smptests/smpmulticast01/init.c @@ -104,18 +104,15 @@ static void action(void *arg) static void test_unicast( test_context *ctx, - void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *), - bool before_multitasking + void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *) ) { uint32_t step; uint32_t i; uint32_t n; - uint32_t self; T_plan(1); step = 0; - self = rtems_scheduler_get_processor(); n = rtems_scheduler_get_processor_maximum(); for (i = 0; i < n; ++i) { @@ -134,18 +131,10 @@ static void test_unicast( ++step; id = _Atomic_Load_uint(&ctx->id[j], ATOMIC_ORDER_RELAXED); - if (before_multitasking) { - if (j == self) { - T_quiet_eq_uint(j + 1, id); - } else { - T_quiet_eq_uint(0, id); - } + if (j == i) { + T_quiet_eq_uint(j + 1, id); } else { - if (j == i) { - T_quiet_eq_uint(j + 1, id); - } else { - T_quiet_eq_uint(0, id); - } + T_quiet_eq_uint(0, id); } } } @@ -155,18 +144,15 @@ static void test_unicast( static void test_broadcast( test_context *ctx, - void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *), - bool before_multitasking + void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *) ) { uint32_t step; uint32_t i; uint32_t n; - uint32_t self; T_plan(1); step = 0; - self = rtems_scheduler_get_processor(); n = rtems_scheduler_get_processor_maximum(); for (i = 0; i < n; ++i) { @@ -181,16 +167,7 @@ static void test_broadcast( ++step; id = _Atomic_Load_uint(&ctx->id[j], ATOMIC_ORDER_RELAXED); - - if (before_multitasking) { - if (j == self) { - T_quiet_eq_uint(j + 1, id); - } else { - T_quiet_eq_uint(0, id); - } - } else { - T_quiet_eq_uint(j + 1, id); - } + T_quiet_eq_uint(j + 1, id); } } @@ -204,27 +181,27 @@ static void test_before_multitasking(void) ctx = &test_instance; T_case_begin("UnicastBeforeMultitasking", NULL); - test_unicast(ctx, _SMP_Multicast_action, true); + test_unicast(ctx, _SMP_Multicast_action); T_case_end(); T_case_begin("UnicastBeforeMultitaskingIRQDisabled", NULL); - test_unicast(ctx, multicast_action_irq_disabled, true); + test_unicast(ctx, multicast_action_irq_disabled); T_case_end(); T_case_begin("UnicastBeforeMultitaskingDispatchDisabled", NULL); - test_unicast(ctx, multicast_action_dispatch_disabled, true); + test_unicast(ctx, multicast_action_dispatch_disabled); T_case_end(); T_case_begin("BroadcastBeforeMultitasking", NULL); - test_broadcast(ctx, _SMP_Multicast_action, true); + test_broadcast(ctx, _SMP_Multicast_action); T_case_end(); T_case_begin("BroadcastBeforeMultitaskingIRQDisabled", NULL); - test_broadcast(ctx, multicast_action_irq_disabled, true); + test_broadcast(ctx, multicast_action_irq_disabled); T_case_end(); T_case_begin("BroadcastBeforeMultitaskingDispatchDisabled", NULL); - test_broadcast(ctx, multicast_action_dispatch_disabled, true); + test_broadcast(ctx, multicast_action_dispatch_disabled); T_case_end(); } @@ -249,27 +226,27 @@ static void Init(rtems_task_argument arg) ctx = &test_instance; T_case_begin("UnicastDuringMultitasking", NULL); - test_unicast(ctx, _SMP_Multicast_action, false); + test_unicast(ctx, _SMP_Multicast_action); T_case_end(); T_case_begin("UnicastDuringMultitaskingIRQDisabled", NULL); - test_unicast(ctx, multicast_action_irq_disabled, false); + test_unicast(ctx, multicast_action_irq_disabled); T_case_end(); T_case_begin("UnicastDuringMultitaskingDispatchDisabled", NULL); - test_unicast(ctx, multicast_action_dispatch_disabled, false); + test_unicast(ctx, multicast_action_dispatch_disabled); T_case_end(); T_case_begin("BroadcastDuringMultitasking", NULL); - test_broadcast(ctx, _SMP_Multicast_action, false); + test_broadcast(ctx, _SMP_Multicast_action); T_case_end(); T_case_begin("BroadcastDuringMultitaskingIRQDisabled", NULL); - test_broadcast(ctx, multicast_action_irq_disabled, false); + test_broadcast(ctx, multicast_action_irq_disabled); T_case_end(); T_case_begin("BroadcastDuringMultitaskingDispatchDisabled", NULL); - test_broadcast(ctx, multicast_action_dispatch_disabled, false); + test_broadcast(ctx, multicast_action_dispatch_disabled); T_case_end(); ok = T_run_finalize(); -- 2.16.4 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel