summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-06-05 11:19:32 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-06-05 14:55:16 +0200
commit9a1bab2525679abc75eb321f61e4b130f8801490 (patch)
tree01cbc61810dde5bbec4a80c26e41833902fde7b2
parentscore: Avoid NULL pointer access (diff)
downloadrtems-9a1bab2525679abc75eb321f61e4b130f8801490.tar.bz2
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.
-rw-r--r--cpukit/score/Makefile.am1
-rw-r--r--cpukit/score/include/rtems/score/percpu.h39
-rw-r--r--cpukit/score/src/percpustatewait.c56
3 files changed, 72 insertions, 24 deletions
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
+ * <rtems@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.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/score/percpu.h>
+#include <rtems/counter.h>
+
+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;
+}