[PATCH 2/4] score: SMP initialization and shutdown changes

Gedare Bloom gedare at rtems.org
Wed Feb 19 15:11:02 UTC 2014


Hi,
There is dissimilarity between the SMP handler function names
* _SMP_Request_processors_to_shutdown
* _SMP_Request_start_multitasking_on_secondary_processors()

Note the order switch between the verb and object. If you like the
similar with _Thread_Start_multitasking, I recommend using
_SMP_Request_shutdown_on_secondary_processors().

I also do not think it is necessary to include
"on_secondary_processors()" however. You could just use
* _SMP_Request_shutdown()
* _SMP_Request_start_multitasking()

-Gedare

On Wed, Feb 19, 2014 at 8:42 AM, Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
> Rename _SMP_Request_other_cores_to_perform_first_context_switch() into
> _SMP_Request_start_multitasking_on_secondary_processors() to match the
> corresponding _SMP_Start_multitasking_on_secondary_processor() action of
> secondary processors.  Highlights also similarity to
> _Thread_Start_multitasking().  Move in source file to right place.
>
> Rename PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING into
> PER_CPU_STATE_READY_TO_START_MULTITASKING.
>
> Rename PER_CPU_STATE_BEGIN_MULTITASKING into
> PER_CPU_STATE_START_MULTITASKING.
>
> Rename _SMP_Request_other_cores_to_shutdown() into
> _SMP_Request_processors_to_shutdown().
>
> Add new state PER_CPU_STATE_DO_SHUTDOWN to initiate a shutdown of other
> processors during system initialization.  Add documentation for
> Per_CPU_State.
>
> Delete debug output.
>
> New test smptests/smpfatal01.
> ---
>  cpukit/sapi/src/exinit.c                      |    2 +-
>  cpukit/score/include/rtems/score/percpu.h     |   66 ++++++++++--
>  cpukit/score/include/rtems/score/smpimpl.h    |   11 +-
>  cpukit/score/src/interr.c                     |    2 +-
>  cpukit/score/src/percpu.c                     |   13 ++-
>  cpukit/score/src/smp.c                        |  117 +++++++++++---------
>  testsuites/smptests/Makefile.am               |    1 +
>  testsuites/smptests/configure.ac              |    1 +
>  testsuites/smptests/smpfatal01/Makefile.am    |   19 ++++
>  testsuites/smptests/smpfatal01/init.c         |  140 +++++++++++++++++++++++++
>  testsuites/smptests/smpfatal01/smpfatal01.doc |   12 ++
>  testsuites/smptests/smpfatal01/smpfatal01.scn |    2 +
>  12 files changed, 312 insertions(+), 74 deletions(-)
>  create mode 100644 testsuites/smptests/smpfatal01/Makefile.am
>  create mode 100644 testsuites/smptests/smpfatal01/init.c
>  create mode 100644 testsuites/smptests/smpfatal01/smpfatal01.doc
>  create mode 100644 testsuites/smptests/smpfatal01/smpfatal01.scn
>
> diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c
> index d265455..3784401 100644
> --- a/cpukit/sapi/src/exinit.c
> +++ b/cpukit/sapi/src/exinit.c
> @@ -210,7 +210,7 @@ void rtems_initialize_start_multitasking(void)
>  {
>    _System_state_Set( SYSTEM_STATE_UP );
>
> -  _SMP_Request_other_cores_to_perform_first_context_switch();
> +  _SMP_Request_start_multitasking_on_secondary_processors();
>
>    _Thread_Start_multitasking();
>
> diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h
> index 4c46b50..27b97f6 100644
> --- a/cpukit/score/include/rtems/score/percpu.h
> +++ b/cpukit/score/include/rtems/score/percpu.h
> @@ -70,6 +70,32 @@ typedef struct Thread_Control_struct Thread_Control;
>    #error "deferred FP switch not implemented for SMP"
>  #endif
>
> +/**
> + * @brief State of a processor.
> + *
> + * @dot
> + * digraph states {
> + *   bi [label="PER_CPU_STATE_BEFORE_INITIALIZATION"];
> + *   rsm [label="PER_CPU_STATE_READY_TO_START_MULTITASKING"];
> + *   sm [label="PER_CPU_STATE_START_MULTITASKING"];
> + *   ds [label="PER_CPU_STATE_DO_SHUTDOWN"];
> + *   u [label="PER_CPU_STATE_UP"];
> + *   s [label="PER_CPU_STATE_SHUTDOWN"];
> + *   bi -> rsm [label="secondary processor\ncompleted initialization"];
> + *   bi -> u [label="main processor\nstarts multitasking"];
> + *   rsm -> sm [label="main processor\ncompleted initialization"];
> + *   rsm -> ds [label="a fatal error occurred"];
> + *   ds -> s [label="do shutdown\nstate observed"];
> + *   sm -> u [label="secondary processor\nstarts multitasking"];
> + *   u -> s [label="shutdown initiated"];
> + * }
> + * @enddot
> + *
> + * The values are chosen to stop the wait for change in case an alternative
> + * state change occurs during _Per_CPU_Wait_for_state().
> + *
> + * @see _Per_CPU_Change_state(), _Per_CPU_Wait_for_state() and _Per_CPU_Get_state().
> + */
>  typedef enum {
>    /**
>     * @brief The per CPU controls are initialized to zero.
> @@ -77,15 +103,15 @@ typedef enum {
>     * In this state the only valid field of the per CPU controls for secondary
>     * processors is the per CPU state.  The secondary processors should perform
>     * their basic initialization now and change into the
> -   * PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING state once this is complete.
> +   * PER_CPU_STATE_READY_TO_START_MULTITASKING state once this is complete.
>     *
>     * The owner of the per CPU state field is the secondary processor in this
>     * state.
>     */
> -  PER_CPU_STATE_BEFORE_INITIALIZATION,
> +  PER_CPU_STATE_BEFORE_INITIALIZATION = 0x0,
>
>    /**
> -   * @brief Secondary processor is ready to begin multitasking.
> +   * @brief Secondary processor is ready to start multitasking.
>     *
>     * The secondary processor performed its basic initialization and is ready to
>     * receive inter-processor interrupts.  Interrupt delivery must be disabled
> @@ -94,16 +120,16 @@ typedef enum {
>     * the first time.  The main processor will wait for all secondary processors
>     * to change into this state.  In case a secondary processor does not reach
>     * this state the system will not start.  The secondary processors wait now
> -   * for a change into the PER_CPU_STATE_BEGIN_MULTITASKING state set by the
> +   * for a change into the PER_CPU_STATE_START_MULTITASKING state set by the
>     * main processor once all secondary processors reached the
> -   * PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING state.
> +   * PER_CPU_STATE_READY_TO_START_MULTITASKING state.
>     *
>     * The owner of the per CPU state field is the main processor in this state.
>     */
> -  PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING,
> +  PER_CPU_STATE_READY_TO_START_MULTITASKING = 0x1,
>
>    /**
> -   * @brief Multitasking begin of secondary processor is requested.
> +   * @brief Multitasking start of secondary processor is requested.
>     *
>     * The main processor completed system initialization and is about to perform
>     * a context switch to its heir thread.  Secondary processors should now
> @@ -113,7 +139,18 @@ typedef enum {
>     * The owner of the per CPU state field is the secondary processor in this
>     * state.
>     */
> -  PER_CPU_STATE_BEGIN_MULTITASKING,
> +  PER_CPU_STATE_START_MULTITASKING = 0x2 | 0x4,
> +
> +  /**
> +   * @brief Shutdown of secondary processor is requested.
> +   *
> +   * A fatal error occurred during system initialization.  A secondary
> +   * processor will shutdown once observes this state.
> +   *
> +   * The owner of the per CPU state field is the secondary processor in this
> +   * state.
> +   */
> +  PER_CPU_STATE_DO_SHUTDOWN = 0x2 | 0x8,
>
>    /**
>     * @brief Normal multitasking state.
> @@ -121,7 +158,7 @@ typedef enum {
>     * The owner of the per CPU state field is the secondary processor in this
>     * state.
>     */
> -  PER_CPU_STATE_UP,
> +  PER_CPU_STATE_UP = 0x10,
>
>    /**
>     * @brief This is the terminal state.
> @@ -129,7 +166,7 @@ typedef enum {
>     * The owner of the per CPU state field is the secondary processor in this
>     * state.
>     */
> -  PER_CPU_STATE_SHUTDOWN
> +  PER_CPU_STATE_SHUTDOWN = 0x20
>  } Per_CPU_State;
>
>  #endif /* defined( RTEMS_SMP ) */
> @@ -318,11 +355,18 @@ void _Per_CPU_Change_state(
>    Per_CPU_State new_state
>  );
>
> -void _Per_CPU_Wait_for_state(
> +Per_CPU_State _Per_CPU_Wait_for_state(
>    const Per_CPU_Control *per_cpu,
>    Per_CPU_State desired_state
>  );
>
> +static inline Per_CPU_State _Per_CPU_Get_state(
> +  const Per_CPU_Control *per_cpu
> +)
> +{
> +  return per_cpu->state;
> +}
> +
>  #endif /* defined( RTEMS_SMP ) */
>
>  /*
> diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h
> index d68af43..1c44c29 100644
> --- a/cpukit/score/include/rtems/score/smpimpl.h
> +++ b/cpukit/score/include/rtems/score/smpimpl.h
> @@ -47,6 +47,7 @@ extern "C" {
>   * @brief SMP fatal codes.
>   */
>  typedef enum {
> +  SMP_FATAL_EARLY_SHUTDOWN,
>    SMP_FATAL_SHUTDOWN
>  } SMP_Fatal_code;
>
> @@ -108,8 +109,6 @@ static inline void _SMP_Inter_processor_interrupt_handler( void )
>      _Per_CPU_Release_and_ISR_enable( self_cpu, level );
>
>      if ( ( message & SMP_MESSAGE_SHUTDOWN ) != 0 ) {
> -      _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_SHUTDOWN );
> -
>        rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_SHUTDOWN );
>        /* does not continue past here */
>      }
> @@ -149,9 +148,9 @@ void _SMP_Broadcast_message(
>   *  their first context switch operation.
>   */
>  #if defined( RTEMS_SMP )
> -  void _SMP_Request_other_cores_to_perform_first_context_switch( void );
> +  void _SMP_Request_start_multitasking_on_secondary_processors( void );
>  #else
> -  #define _SMP_Request_other_cores_to_perform_first_context_switch() \
> +  #define _SMP_Request_start_multitasking_on_secondary_processors() \
>      do { } while ( 0 )
>  #endif
>
> @@ -161,9 +160,9 @@ void _SMP_Broadcast_message(
>   *  Send message to other cores requesting them to shutdown.
>   */
>  #if defined( RTEMS_SMP )
> -  void _SMP_Request_other_cores_to_shutdown( void );
> +  void _SMP_Request_processors_to_shutdown( void );
>  #else
> -  #define _SMP_Request_other_cores_to_shutdown() \
> +  #define _SMP_Request_processors_to_shutdown() \
>      do { } while ( 0 )
>  #endif
>
> diff --git a/cpukit/score/src/interr.c b/cpukit/score/src/interr.c
> index c2a9fbe..d57f116 100644
> --- a/cpukit/score/src/interr.c
> +++ b/cpukit/score/src/interr.c
> @@ -39,7 +39,7 @@ void _Terminate(
>    _ISR_Disable_without_giant( level );
>    (void) level;
>
> -  _SMP_Request_other_cores_to_shutdown();
> +  _SMP_Request_processors_to_shutdown();
>
>    _User_extensions_Fatal( the_source, is_internal, the_error );
>
> diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c
> index c68f378..9ce8b17 100644
> --- a/cpukit/score/src/percpu.c
> +++ b/cpukit/score/src/percpu.c
> @@ -19,6 +19,7 @@
>  #endif
>
>  #include <rtems/score/percpu.h>
> +#include <rtems/score/assert.h>
>
>  #if defined(RTEMS_SMP)
>    void _Per_CPU_Change_state(
> @@ -30,14 +31,22 @@
>      _CPU_SMP_Processor_event_broadcast();
>    }
>
> -  void _Per_CPU_Wait_for_state(
> +  Per_CPU_State _Per_CPU_Wait_for_state(
>      const Per_CPU_Control *per_cpu,
>      Per_CPU_State desired_state
>    )
>    {
> -    while ( per_cpu->state != desired_state ) {
> +    Per_CPU_State state = per_cpu->state;
> +
> +    _Assert( desired_state != 0 );
> +
> +    while ( (state & desired_state) == 0 ) {
>        _CPU_SMP_Processor_event_receive();
> +
> +       state = per_cpu->state;
>      }
> +
> +    return state;
>    }
>  #else
>    /*
> diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c
> index 59036eb..445a56a 100644
> --- a/cpukit/score/src/smp.c
> +++ b/cpukit/score/src/smp.c
> @@ -24,10 +24,6 @@
>  #include <rtems/score/threadimpl.h>
>  #include <rtems/config.h>
>
> -#if defined(RTEMS_DEBUG)
> -  #include <rtems/bspIo.h>
> -#endif
> -
>  void _SMP_Handler_initialize( void )
>  {
>    uint32_t max_cpus = rtems_configuration_get_maximum_processors();
> @@ -47,69 +43,44 @@ void _SMP_Handler_initialize( void )
>    _SMP_Processor_count = max_cpus;
>  }
>
> -void _SMP_Start_multitasking_on_secondary_processor( void )
> -{
> -  Per_CPU_Control *self_cpu = _Per_CPU_Get();
> -
> -  #if defined(RTEMS_DEBUG)
> -    printk( "Made it to %d -- ", _Per_CPU_Get_index( self_cpu ) );
> -  #endif
> -
> -  _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING );
> -
> -  _Per_CPU_Wait_for_state( self_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
> -
> -  _Thread_Start_multitasking();
> -}
> -
> -void _SMP_Send_message( uint32_t cpu, uint32_t message )
> -{
> -  Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
> -  ISR_Level level;
> -
> -  _Per_CPU_ISR_disable_and_acquire( per_cpu, level );
> -  per_cpu->message |= message;
> -  _Per_CPU_Release_and_ISR_enable( per_cpu, level );
> -
> -  _CPU_SMP_Send_interrupt( cpu );
> -}
> -
> -void _SMP_Broadcast_message( uint32_t message )
> +void _SMP_Request_start_multitasking_on_secondary_processors( void )
>  {
>    uint32_t self = _SMP_Get_current_processor();
>    uint32_t ncpus = _SMP_Get_processor_count();
>    uint32_t cpu;
>
> -  _Assert_Thread_dispatching_repressed();
> -
>    for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
> +    Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
> +
>      if ( cpu != self ) {
> -      _SMP_Send_message( cpu, message );
> +      _Per_CPU_Wait_for_state(
> +        per_cpu,
> +        PER_CPU_STATE_READY_TO_START_MULTITASKING
> +      );
> +
> +      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_START_MULTITASKING );
>      }
>    }
>  }
>
> -void _SMP_Request_other_cores_to_perform_first_context_switch( void )
> +void _SMP_Start_multitasking_on_secondary_processor( void )
>  {
> -  uint32_t self = _SMP_Get_current_processor();
> -  uint32_t ncpus = _SMP_Get_processor_count();
> -  uint32_t cpu;
> +  Per_CPU_Control *self_cpu = _Per_CPU_Get();
> +  Per_CPU_State state;
>
> -  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
> -    Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
> +  _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_READY_TO_START_MULTITASKING );
>
> -    if ( cpu != self ) {
> -      _Per_CPU_Wait_for_state(
> -        per_cpu,
> -        PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING
> -      );
> +  state =
> +    _Per_CPU_Wait_for_state( self_cpu, PER_CPU_STATE_START_MULTITASKING );
>
> -      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
> -    }
> +  if ( state == PER_CPU_STATE_START_MULTITASKING ) {
> +    _Thread_Start_multitasking();
> +  } else {
> +    rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_EARLY_SHUTDOWN );
>    }
>  }
>
> -void _SMP_Request_other_cores_to_shutdown( void )
> +void _SMP_Request_processors_to_shutdown( void )
>  {
>    uint32_t self = _SMP_Get_current_processor();
>
> @@ -123,12 +94,52 @@ void _SMP_Request_other_cores_to_shutdown( void )
>    uint32_t cpu;
>
>    for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
> -    if ( cpu != self ) {
> -      const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
> +    Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
>
> -      if ( per_cpu->state != PER_CPU_STATE_BEFORE_INITIALIZATION ) {
> -        _SMP_Send_message( cpu, SMP_MESSAGE_SHUTDOWN );
> +    if ( cpu != self ) {
> +      switch ( _Per_CPU_Get_state( per_cpu ) ) {
> +        case PER_CPU_STATE_READY_TO_START_MULTITASKING:
> +          _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_DO_SHUTDOWN );
> +          break;
> +        case PER_CPU_STATE_START_MULTITASKING:
> +        case PER_CPU_STATE_UP:
> +          _SMP_Send_message( cpu, SMP_MESSAGE_SHUTDOWN );
> +          break;
> +        case PER_CPU_STATE_DO_SHUTDOWN:
> +        case PER_CPU_STATE_SHUTDOWN:
> +        case PER_CPU_STATE_BEFORE_INITIALIZATION:
> +          /* Nothing to do */
> +          break;
>        }
> +    } else {
> +      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_SHUTDOWN );
> +    }
> +  }
> +}
> +
> +void _SMP_Send_message( uint32_t cpu, uint32_t message )
> +{
> +  Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
> +  ISR_Level level;
> +
> +  _Per_CPU_ISR_disable_and_acquire( per_cpu, level );
> +  per_cpu->message |= message;
> +  _Per_CPU_Release_and_ISR_enable( per_cpu, level );
> +
> +  _CPU_SMP_Send_interrupt( cpu );
> +}
> +
> +void _SMP_Broadcast_message( uint32_t message )
> +{
> +  uint32_t self = _SMP_Get_current_processor();
> +  uint32_t ncpus = _SMP_Get_processor_count();
> +  uint32_t cpu;
> +
> +  _Assert_Thread_dispatching_repressed();
> +
> +  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
> +    if ( cpu != self ) {
> +      _SMP_Send_message( cpu, message );
>      }
>    }
>  }
> diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am
> index 023b7e9..7b610b5 100644
> --- a/testsuites/smptests/Makefile.am
> +++ b/testsuites/smptests/Makefile.am
> @@ -11,6 +11,7 @@ SUBDIRS += smp07
>  SUBDIRS += smp08
>  SUBDIRS += smp09
>  SUBDIRS += smpatomic01
> +SUBDIRS += smpfatal01
>  SUBDIRS += smplock01
>  SUBDIRS += smpmigration01
>  SUBDIRS += smpschedule01
> diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac
> index 5c68772..475ee9c 100644
> --- a/testsuites/smptests/configure.ac
> +++ b/testsuites/smptests/configure.ac
> @@ -65,6 +65,7 @@ smp07/Makefile
>  smp08/Makefile
>  smp09/Makefile
>  smpatomic01/Makefile
> +smpfatal01/Makefile
>  smplock01/Makefile
>  smpmigration01/Makefile
>  smppsxsignal01/Makefile
> diff --git a/testsuites/smptests/smpfatal01/Makefile.am b/testsuites/smptests/smpfatal01/Makefile.am
> new file mode 100644
> index 0000000..2aaee2b
> --- /dev/null
> +++ b/testsuites/smptests/smpfatal01/Makefile.am
> @@ -0,0 +1,19 @@
> +rtems_tests_PROGRAMS = smpfatal01
> +smpfatal01_SOURCES = init.c
> +
> +dist_rtems_tests_DATA = smpfatal01.scn smpfatal01.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 = $(smpfatal01_OBJECTS)
> +LINK_LIBS = $(smpfatal01_LDLIBS)
> +
> +smpfatal01$(EXEEXT): $(smpfatal01_OBJECTS) $(smpfatal01_DEPENDENCIES)
> +       @rm -f smpfatal01$(EXEEXT)
> +       $(make-exe)
> +
> +include $(top_srcdir)/../automake/local.am
> diff --git a/testsuites/smptests/smpfatal01/init.c b/testsuites/smptests/smpfatal01/init.c
> new file mode 100644
> index 0000000..e6b2eee
> --- /dev/null
> +++ b/testsuites/smptests/smpfatal01/init.c
> @@ -0,0 +1,140 @@
> +/*
> + * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
> + *
> + *  embedded brains GmbH
> + *  Dornierstr. 4
> + *  82178 Puchheim
> + *  Germany
> + *  <rtems at embedded-brains.de>
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.com/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +  #include "config.h"
> +#endif
> +
> +#include <rtems.h>
> +#include <rtems/score/percpu.h>
> +#include <rtems/score/smpimpl.h>
> +
> +#include "tmacros.h"
> +
> +#define MAX_CPUS 32
> +
> +static uint32_t main_cpu;
> +
> +static void Init(rtems_task_argument arg)
> +{
> +  rtems_test_assert(0);
> +}
> +
> +static void fatal_extension(
> +  rtems_fatal_source source,
> +  bool is_internal,
> +  rtems_fatal_code code
> +)
> +{
> +  if (source != RTEMS_FATAL_SOURCE_ASSERT) {
> +    uint32_t self_cpu = rtems_smp_get_current_processor();
> +
> +    rtems_test_assert(!is_internal);
> +
> +    if (self_cpu == main_cpu) {
> +      uint32_t cpu_count = rtems_smp_get_processor_count();
> +      uint32_t cpu;
> +
> +      rtems_test_assert(source == RTEMS_FATAL_SOURCE_APPLICATION);
> +      rtems_test_assert(code == 0xdeadbeef);
> +
> +      for (cpu = 0; cpu < MAX_CPUS; ++cpu) {
> +        const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
> +        Per_CPU_State state = _Per_CPU_Get_state( per_cpu );
> +
> +        if (cpu == self_cpu) {
> +          rtems_test_assert(state == PER_CPU_STATE_SHUTDOWN);
> +        } else if (cpu < cpu_count) {
> +          rtems_test_assert(
> +             state == PER_CPU_STATE_READY_TO_START_MULTITASKING
> +              || state == PER_CPU_STATE_DO_SHUTDOWN
> +              || state == PER_CPU_STATE_SHUTDOWN
> +          );
> +          state = _Per_CPU_Wait_for_state(
> +            per_cpu,
> +            PER_CPU_STATE_SHUTDOWN
> +          );
> +          rtems_test_assert(state == PER_CPU_STATE_SHUTDOWN);
> +        } else {
> +          rtems_test_assert(state == PER_CPU_STATE_BEFORE_INITIALIZATION);
> +        }
> +      }
> +
> +      printk( "*** END OF TEST SMPFATAL 1 ***\n" );
> +    } else {
> +      rtems_test_assert(source == RTEMS_FATAL_SOURCE_SMP);
> +      rtems_test_assert(code == SMP_FATAL_EARLY_SHUTDOWN);
> +    }
> +  }
> +}
> +
> +static rtems_status_code test_driver_init(
> +  rtems_device_major_number major,
> +  rtems_device_minor_number minor,
> +  void *arg
> +)
> +{
> +  uint32_t self_cpu = rtems_smp_get_current_processor();
> +  uint32_t cpu_count = rtems_smp_get_processor_count();
> +  uint32_t cpu;
> +
> +  printk("\n\n*** TEST SMPFATAL 1 ***\n");
> +
> +  rtems_test_assert(rtems_configuration_get_maximum_processors() == MAX_CPUS);
> +
> +  main_cpu = self_cpu;
> +
> +  for (cpu = 0; cpu < MAX_CPUS; ++cpu) {
> +    const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
> +    Per_CPU_State state = _Per_CPU_Get_state( per_cpu );
> +
> +    if (cpu == self_cpu) {
> +      rtems_test_assert(state == PER_CPU_STATE_BEFORE_INITIALIZATION);
> +    } else if (cpu < cpu_count) {
> +      rtems_test_assert(
> +        state == PER_CPU_STATE_BEFORE_INITIALIZATION
> +          || state == PER_CPU_STATE_READY_TO_START_MULTITASKING
> +      );
> +      state = _Per_CPU_Wait_for_state(
> +        per_cpu,
> +        PER_CPU_STATE_READY_TO_START_MULTITASKING
> +      );
> +      rtems_test_assert(state == PER_CPU_STATE_READY_TO_START_MULTITASKING);
> +    } else {
> +      rtems_test_assert(state == PER_CPU_STATE_BEFORE_INITIALIZATION);
> +    }
> +  }
> +
> +  rtems_fatal(RTEMS_FATAL_SOURCE_APPLICATION, 0xdeadbeef);
> +}
> +
> +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
> +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
> +
> +#define CONFIGURE_APPLICATION_EXTRA_DRIVERS \
> +  { .initialization_entry = test_driver_init }
> +
> +#define CONFIGURE_INITIAL_EXTENSIONS { .fatal = fatal_extension }
> +
> +#define CONFIGURE_SMP_APPLICATION
> +
> +#define CONFIGURE_SMP_MAXIMUM_PROCESSORS MAX_CPUS
> +
> +#define CONFIGURE_MAXIMUM_TASKS 1
> +
> +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
> +
> +#define CONFIGURE_INIT
> +
> +#include <rtems/confdefs.h>
> diff --git a/testsuites/smptests/smpfatal01/smpfatal01.doc b/testsuites/smptests/smpfatal01/smpfatal01.doc
> new file mode 100644
> index 0000000..831fabc
> --- /dev/null
> +++ b/testsuites/smptests/smpfatal01/smpfatal01.doc
> @@ -0,0 +1,12 @@
> +This file describes the directives and concepts tested by this test set.
> +
> +test set name: smpfatal01
> +
> +directives:
> +
> +  - _SMP_Request_processors_to_shutdown()
> +
> +concepts:
> +
> +  - Ensure that the system termination in case of fatal errors during driver
> +    initialization works.
> diff --git a/testsuites/smptests/smpfatal01/smpfatal01.scn b/testsuites/smptests/smpfatal01/smpfatal01.scn
> new file mode 100644
> index 0000000..0b67121
> --- /dev/null
> +++ b/testsuites/smptests/smpfatal01/smpfatal01.scn
> @@ -0,0 +1,2 @@
> +*** TEST SMPFATAL 1 ***
> +*** END OF TEST SMPFATAL 1 ***
> --
> 1.7.7
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel



More information about the devel mailing list