diff options
Diffstat (limited to 'cpukit/score/src/percpu.c')
-rw-r--r-- | cpukit/score/src/percpu.c | 178 |
1 files changed, 25 insertions, 153 deletions
diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c index e254f306eb..ec6098afa9 100644 --- a/cpukit/score/src/percpu.c +++ b/cpukit/score/src/percpu.c @@ -1,19 +1,38 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /** * @file * * @ingroup RTEMSScorePerCPU * - * @brief This source file contains a definition of ::_Per_CPU_Information and - * the implementation of _Per_CPU_State_change(). + * @brief This source file contains the uniprocessor definition of + * ::_Per_CPU_Information and some static assertions. */ /* * COPYRIGHT (c) 1989-2011. * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H @@ -21,10 +40,6 @@ #endif #include <rtems/score/percpu.h> -#include <rtems/score/assert.h> -#include <rtems/score/isrlock.h> -#include <rtems/score/smpimpl.h> -#include <rtems/config.h> RTEMS_STATIC_ASSERT( sizeof( CPU_Uint32ptr ) >= sizeof( uintptr_t ), @@ -36,150 +51,7 @@ RTEMS_STATIC_ASSERT( CPU_Uint32ptr_greater_equal_uint32_t ); -#if defined(RTEMS_SMP) - -ISR_LOCK_DEFINE( static, _Per_CPU_State_lock, "Per-CPU State" ) - -static void _Per_CPU_State_acquire( ISR_lock_Context *lock_context ) -{ - _ISR_lock_ISR_disable_and_acquire( &_Per_CPU_State_lock, lock_context ); -} - -static void _Per_CPU_State_release( ISR_lock_Context *lock_context ) -{ - _ISR_lock_Release_and_ISR_enable( &_Per_CPU_State_lock, lock_context ); -} - -static void _Per_CPU_State_busy_wait( - Per_CPU_Control *cpu, - Per_CPU_State new_state -) -{ - Per_CPU_State state = cpu->state; - - switch ( new_state ) { - case PER_CPU_STATE_REQUEST_START_MULTITASKING: - while ( - state != PER_CPU_STATE_READY_TO_START_MULTITASKING - && state != PER_CPU_STATE_SHUTDOWN - ) { - _Per_CPU_Perform_jobs( cpu ); - _CPU_SMP_Processor_event_receive(); - state = cpu->state; - } - break; - case PER_CPU_STATE_UP: - while ( - state != PER_CPU_STATE_REQUEST_START_MULTITASKING - && state != PER_CPU_STATE_SHUTDOWN - ) { - _Per_CPU_Perform_jobs( cpu ); - _CPU_SMP_Processor_event_receive(); - state = cpu->state; - } - break; - default: - /* No need to wait */ - break; - } -} - -static Per_CPU_State _Per_CPU_State_get_next( - Per_CPU_State current_state, - Per_CPU_State new_state -) -{ - switch ( current_state ) { - case PER_CPU_STATE_INITIAL: - switch ( new_state ) { - case PER_CPU_STATE_READY_TO_START_MULTITASKING: - case PER_CPU_STATE_SHUTDOWN: - /* Change is acceptable */ - break; - default: - new_state = PER_CPU_STATE_SHUTDOWN; - break; - } - break; - case PER_CPU_STATE_READY_TO_START_MULTITASKING: - switch ( new_state ) { - case PER_CPU_STATE_REQUEST_START_MULTITASKING: - case PER_CPU_STATE_SHUTDOWN: - /* Change is acceptable */ - break; - default: - new_state = PER_CPU_STATE_SHUTDOWN; - break; - } - break; - case PER_CPU_STATE_REQUEST_START_MULTITASKING: - switch ( new_state ) { - case PER_CPU_STATE_UP: - case PER_CPU_STATE_SHUTDOWN: - /* Change is acceptable */ - break; - default: - new_state = PER_CPU_STATE_SHUTDOWN; - break; - } - break; - default: - new_state = PER_CPU_STATE_SHUTDOWN; - break; - } - - return new_state; -} - -void _Per_CPU_State_change( - Per_CPU_Control *cpu, - Per_CPU_State new_state -) -{ - ISR_lock_Context lock_context; - Per_CPU_State next_state; - - _Per_CPU_State_busy_wait( cpu, new_state ); - - _Per_CPU_State_acquire( &lock_context ); - - next_state = _Per_CPU_State_get_next( cpu->state, new_state ); - cpu->state = next_state; - - if ( next_state == PER_CPU_STATE_SHUTDOWN ) { - uint32_t cpu_max = rtems_configuration_get_maximum_processors(); - uint32_t cpu_index; - - for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) { - Per_CPU_Control *cpu_other = _Per_CPU_Get_by_index( cpu_index ); - - if ( cpu_other != cpu ) { - switch ( cpu_other->state ) { - case PER_CPU_STATE_UP: - _SMP_Send_message( cpu_index, SMP_MESSAGE_SHUTDOWN ); - break; - default: - /* Nothing to do */ - break; - } - - cpu_other->state = PER_CPU_STATE_SHUTDOWN; - } - } - } - - _CPU_SMP_Processor_event_broadcast(); - - _Per_CPU_State_release( &lock_context ); - - if ( - next_state == PER_CPU_STATE_SHUTDOWN - && new_state != PER_CPU_STATE_SHUTDOWN - ) { - _SMP_Fatal( SMP_FATAL_SHUTDOWN ); - } -} -#else +#if !defined(RTEMS_SMP) /* * On single core systems, we can efficiently directly access a single * statically allocated per cpu structure. And the fields are initialized |