source: rtems/cpukit/include/rtems/score/smpimpl.h @ e90486a

5
Last change on this file since e90486a was e90486a, checked in by Sebastian Huber <sebastian.huber@…>, on 04/11/19 at 13:16:40

score: Rework SMP multicast action

Use a FIFO list of jobs per processor to carry out the SMP multicast
action. Use a done indicator per job to reduce the bus traffic a bit.

  • Property mode set to 100644
File size: 8.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSScoreSMPImpl
5 *
6 * @brief SuperCore SMP Implementation
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2011.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#ifndef _RTEMS_SCORE_SMPIMPL_H
19#define _RTEMS_SCORE_SMPIMPL_H
20
21#include <rtems/score/smp.h>
22#include <rtems/score/percpu.h>
23#include <rtems/score/processormask.h>
24#include <rtems/fatal.h>
25#include <rtems/rtems/cache.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/**
32 * @addtogroup RTEMSScoreSMP
33 *
34 * This defines the interface of the SuperCore SMP support.
35 *
36 * @{
37 */
38
39/**
40 * @brief SMP message to request a processor shutdown.
41 *
42 * @see _SMP_Send_message().
43 */
44#define SMP_MESSAGE_SHUTDOWN 0x1UL
45
46/**
47 * @brief SMP message to request a test handler invocation.
48 *
49 * @see _SMP_Send_message().
50 */
51#define SMP_MESSAGE_TEST 0x2UL
52
53/**
54 * @brief SMP message to perform per-processor jobs.
55 *
56 * @see _SMP_Send_message().
57 */
58#define SMP_MESSAGE_PERFORM_JOBS 0x4UL
59
60/**
61 * @brief SMP message to request a clock tick.
62 *
63 * This message is provided for systems without a proper interrupt affinity
64 * support and may be used by the clock driver.
65 *
66 * @see _SMP_Send_message().
67 */
68#define SMP_MESSAGE_CLOCK_TICK 0x8UL
69
70/**
71 * @brief SMP fatal codes.
72 */
73typedef enum {
74  SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER,
75  SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT,
76  SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR,
77  SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR,
78  SMP_FATAL_SHUTDOWN,
79  SMP_FATAL_SHUTDOWN_RESPONSE,
80  SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED,
81  SMP_FATAL_SCHEDULER_PIN_OR_UNPIN_NOT_SUPPORTED
82} SMP_Fatal_code;
83
84static inline void _SMP_Fatal( SMP_Fatal_code code )
85{
86  _Terminate( RTEMS_FATAL_SOURCE_SMP, code );
87}
88
89/**
90 *  @brief Initialize SMP Handler
91 *
92 *  This method initialize the SMP Handler.
93 */
94#if defined( RTEMS_SMP )
95  void _SMP_Handler_initialize( void );
96#else
97  #define _SMP_Handler_initialize() \
98    do { } while ( 0 )
99#endif
100
101#if defined( RTEMS_SMP )
102
103/**
104 * @brief Set of online processors.
105 *
106 * A processor is online if was started during system initialization.  In this
107 * case its corresponding bit in the mask is set.
108 *
109 * @see _SMP_Handler_initialize().
110 */
111extern Processor_mask _SMP_Online_processors;
112
113/**
114 * @brief Performs high-level initialization of a secondary processor and runs
115 * the application threads.
116 *
117 * The low-level initialization code must call this function to hand over the
118 * control of this processor to RTEMS.  Interrupts must be disabled.  It must
119 * be possible to send inter-processor interrupts to this processor.  Since
120 * interrupts are disabled the inter-processor interrupt delivery is postponed
121 * until interrupts are enabled the first time.  Interrupts are enabled during
122 * the execution begin of threads in case they have interrupt level zero (this
123 * is the default).
124 *
125 * The pre-requisites for the call to this function are
126 * - disabled interrupts,
127 * - delivery of inter-processor interrupts is possible,
128 * - a valid stack pointer and enough stack space,
129 * - a valid code memory, and
130 * - a valid BSS section.
131 *
132 * This function must not be called by the main processor.  The main processor
133 * uses _Thread_Start_multitasking() instead.
134 *
135 * This function does not return to the caller.
136 *
137 * @param[in] cpu_self The current processor control.
138 */
139void _SMP_Start_multitasking_on_secondary_processor(
140  Per_CPU_Control *cpu_self
141) RTEMS_NO_RETURN;
142
143typedef void ( *SMP_Test_message_handler )( Per_CPU_Control *cpu_self );
144
145extern SMP_Test_message_handler _SMP_Test_message_handler;
146
147/**
148 * @brief Sets the handler for test messages.
149 *
150 * This handler can be used to test the inter-processor interrupt
151 * implementation.
152 */
153static inline void _SMP_Set_test_message_handler(
154  SMP_Test_message_handler handler
155)
156{
157  _SMP_Test_message_handler = handler;
158}
159
160/**
161 * @brief Interrupt handler for inter-processor interrupts.
162 *
163 * @return The received message.
164 */
165static inline long unsigned _SMP_Inter_processor_interrupt_handler(
166  Per_CPU_Control *cpu_self
167)
168{
169  unsigned long message;
170
171  /*
172   * In the common case the inter-processor interrupt is issued to carry out a
173   * thread dispatch.
174   */
175  cpu_self->dispatch_necessary = true;
176
177  message = _Atomic_Exchange_ulong(
178    &cpu_self->message,
179    0,
180    ATOMIC_ORDER_ACQUIRE
181  );
182
183  if ( RTEMS_PREDICT_FALSE( message != 0 ) ) {
184    if ( ( message & SMP_MESSAGE_SHUTDOWN ) != 0 ) {
185      _SMP_Fatal( SMP_FATAL_SHUTDOWN_RESPONSE );
186      /* does not continue past here */
187    }
188
189    if ( ( message & SMP_MESSAGE_TEST ) != 0 ) {
190      ( *_SMP_Test_message_handler )( cpu_self );
191    }
192
193    if ( ( message & SMP_MESSAGE_PERFORM_JOBS ) != 0 ) {
194      _Per_CPU_Perform_jobs( cpu_self );
195    }
196  }
197
198  return message;
199}
200
201/**
202 *  @brief Returns true, if the processor with the specified index should be
203 *  started.
204 *
205 *  @param[in] cpu_index The processor index.
206 *
207 *  @retval true The processor should be started.
208 *  @retval false Otherwise.
209 */
210bool _SMP_Should_start_processor( uint32_t cpu_index );
211
212/**
213 *  @brief Sends an SMP message to a processor.
214 *
215 *  The target processor may be the sending processor.
216 *
217 *  @param[in] cpu_index The target processor of the message.
218 *  @param[in] message The message.
219 */
220void _SMP_Send_message( uint32_t cpu_index, unsigned long message );
221
222/**
223 *  @brief Sends an SMP message to all other online processors.
224 *
225 *  @param[in] message The message.
226 */
227void _SMP_Send_message_broadcast(
228  unsigned long message
229);
230
231/**
232 *  @brief Sends an SMP message to a set of processors.
233 *
234 *  The sending processor may be part of the set.
235 *
236 *  @param[in] targets The set of processors to send the message.
237 *  @param[in] message The message.
238 */
239void _SMP_Send_message_multicast(
240  const Processor_mask *targets,
241  unsigned long         message
242);
243
244typedef void ( *SMP_Action_handler )( void *arg );
245
246/**
247 * @brief Initiates an SMP multicast action to a set of target processors.
248 *
249 * The current processor may be part of the set.
250 *
251 * @param targets The set of target processors for the action.  If @c NULL,
252 *   then the action will be performed on all online processors.
253 * @param handler The multicast action handler.
254 * @param arg The multicast action argument.
255 */
256void _SMP_Multicast_action(
257  const Processor_mask *targets,
258  SMP_Action_handler    handler,
259  void                 *arg
260);
261
262/**
263 * @brief Executes a handler with argument on the specified processor on behalf
264 * of the boot processor.
265 *
266 * The calling processor must be the boot processor.  In case the specified
267 * processor is not online or not in the
268 * PER_CPU_STATE_READY_TO_START_MULTITASKING state, then no action is
269 * performed.
270 *
271 * @param cpu The processor to execute the action.
272 * @param handler The handler of the action.
273 * @param arg The argument of the action.
274 *
275 * @retval true The handler executed on the specified processor.
276 * @retval false Otherwise.
277 *
278 * @see _SMP_Before_multitasking_action_broadcast().
279 */
280bool _SMP_Before_multitasking_action(
281  Per_CPU_Control    *cpu,
282  SMP_Action_handler  handler,
283  void               *arg
284);
285
286/**
287 * @brief Executes a handler with argument on all online processors except the
288 * boot processor on behalf of the boot processor.
289 *
290 * The calling processor must be the boot processor.
291 *
292 * @param handler The handler of the action.
293 * @param arg The argument of the action.
294 *
295 * @retval true The handler executed on all online processors except the boot
296 * processor.
297 * @retval false Otherwise.
298 *
299 * @see _SMP_Before_multitasking_action().
300 */
301bool _SMP_Before_multitasking_action_broadcast(
302  SMP_Action_handler  handler,
303  void               *arg
304);
305
306#endif /* defined( RTEMS_SMP ) */
307
308/**
309 * @brief Requests a multitasking start on all configured and available
310 * processors.
311 */
312#if defined( RTEMS_SMP )
313  void _SMP_Request_start_multitasking( void );
314#else
315  #define _SMP_Request_start_multitasking() \
316    do { } while ( 0 )
317#endif
318
319/**
320 * @brief Requests a shutdown of all processors.
321 *
322 * This function is a part of the system termination procedure.
323 *
324 * @see _Terminate().
325 */
326#if defined( RTEMS_SMP )
327  void _SMP_Request_shutdown( void );
328#else
329  #define _SMP_Request_shutdown() \
330    do { } while ( 0 )
331#endif
332
333RTEMS_INLINE_ROUTINE const Processor_mask *_SMP_Get_online_processors( void )
334{
335#if defined(RTEMS_SMP)
336  return &_SMP_Online_processors;
337#else
338  return &_Processor_mask_The_one_and_only;
339#endif
340}
341
342/** @} */
343
344#ifdef __cplusplus
345}
346#endif
347
348#endif
349/* end of include file */
Note: See TracBrowser for help on using the repository browser.