From 9a1bab2525679abc75eb321f61e4b130f8801490 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 5 Jun 2014 11:19:32 +0200 Subject: score: _Per_CPU_State_wait_for_non_initial_state() Replace _Per_CPU_State_wait_for_ready_to_start_multitasking() with _Per_CPU_State_wait_for_non_initial_state(). Implement this function. --- cpukit/score/Makefile.am | 1 + cpukit/score/include/rtems/score/percpu.h | 39 +++++++++------------ cpukit/score/src/percpustatewait.c | 56 +++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 24 deletions(-) create mode 100644 cpukit/score/src/percpustatewait.c diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index feb757dfb1..7b17569cb5 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -130,6 +130,7 @@ libscore_a_SOURCES += src/mpci.c src/objectmp.c src/threadmp.c endif if HAS_SMP +libscore_a_SOURCES += src/percpustatewait.c libscore_a_SOURCES += src/profilingsmplock.c libscore_a_SOURCES += src/schedulersmpvalidstatechanges.c libscore_a_SOURCES += src/schedulerpriorityaffinitysmp.c diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h index e232674c30..30d61d519f 100644 --- a/cpukit/score/include/rtems/score/percpu.h +++ b/cpukit/score/include/rtems/score/percpu.h @@ -547,42 +547,33 @@ void _Per_CPU_State_change( ); /** - * @brief Waits for all other processors to enter the ready to start - * multitasking state with a timeout in microseconds. + * @brief Waits for a processor to change into a non-initial state. * - * In case one processor enters the shutdown state, this function does not - * return and terminates the system with the SMP_FATAL_SHUTDOWN_EARLY fatal SMP - * error. - * - * This function should be called only in _CPU_SMP_Initialize() if required by - * the CPU port or BSP. + * This function should be called only in _CPU_SMP_Start_processor() if + * required by the CPU port or BSP. * * @code - * uint32_t _CPU_SMP_Initialize(uint32_t configured_cpu_count) + * bool _CPU_SMP_Start_processor(uint32_t cpu_index) * { - * uint32_t cnt = MIN(get_hardware_cpu_count(), configured_cpu_count); * uint32_t timeout = 123456; * - * do_some_stuff(); + * start_the_processor(cpu_index); * - * return _Per_CPU_State_wait_for_ready_to_start_multitasking(cnt, timeout); + * return _Per_CPU_State_wait_for_non_initial_state(cpu_index, timeout); * } * @endcode * - * In case the timeout expires the count of processors is reduced to reflect - * the set of processors which is actually available at this point in time. - * - * @param[in] processor_count The processor count is the minimum value of the - * configured count of processors and the processor count offered by the actual - * hardware. - * @param[in] timeout_in_us The timeout in microseconds. + * @param[in] cpu_index The processor index. + * @param[in] timeout_in_ns The timeout in nanoseconds. Use a value of zero to + * wait forever if necessary. * - * @return The count of processors available for the application in the system. - * This value is less than or equal to the processor count. + * @retval true The processor is in a non-initial state. + * @retval false The timeout expired before the processor reached a non-initial + * state. */ -uint32_t _Per_CPU_State_wait_for_ready_to_start_multitasking( - uint32_t processor_count, - uint32_t timeout_in_us +bool _Per_CPU_State_wait_for_non_initial_state( + uint32_t cpu_index, + uint32_t timeout_in_ns ); #endif /* defined( RTEMS_SMP ) */ diff --git a/cpukit/score/src/percpustatewait.c b/cpukit/score/src/percpustatewait.c new file mode 100644 index 0000000000..bde367b698 --- /dev/null +++ b/cpukit/score/src/percpustatewait.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +bool _Per_CPU_State_wait_for_non_initial_state( + uint32_t cpu_index, + uint32_t timeout_in_ns +) +{ + const Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index ); + Per_CPU_State state = cpu->state; + + if ( timeout_in_ns > 0 ) { + rtems_counter_ticks ticks = + rtems_counter_nanoseconds_to_ticks( timeout_in_ns ); + rtems_counter_ticks a = rtems_counter_read(); + rtems_counter_ticks delta = 0; + + while ( ticks > delta && state == PER_CPU_STATE_INITIAL ) { + rtems_counter_ticks b; + + _CPU_SMP_Processor_event_receive(); + state = cpu->state; + + ticks -= delta; + + b = rtems_counter_read(); + delta = rtems_counter_difference( b, a ); + a = b; + } + } else { + while ( state == PER_CPU_STATE_INITIAL ) { + _CPU_SMP_Processor_event_receive(); + state = cpu->state; + } + } + + return state != PER_CPU_STATE_INITIAL; +} -- cgit v1.2.3