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

Last change on this file since a660e9dc was a660e9dc, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/22 at 08:37:05

Do not use RTEMS_INLINE_ROUTINE

Directly use "static inline" which is available in C99 and later. This brings
the RTEMS implementation closer to standard C.

Close #3935.

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreSMP
7 *
8 * @brief This header file provides interfaces of the
9 *   @ref RTEMSScoreSMP which are only used by the implementation.
10 */
11
12/*
13 *  COPYRIGHT (c) 1989-2011.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 *    notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 *    notice, this list of conditions and the following disclaimer in the
23 *    documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef _RTEMS_SCORE_SMPIMPL_H
39#define _RTEMS_SCORE_SMPIMPL_H
40
41#include <rtems/score/smp.h>
42#include <rtems/score/percpu.h>
43#include <rtems/score/processormask.h>
44#include <rtems/fatal.h>
45
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50/**
51 * @addtogroup RTEMSScoreSMP
52 *
53 * This defines the interface of the SuperCore SMP support.
54 *
55 * @{
56 */
57
58/**
59 * @brief SMP message to request a processor shutdown.
60 *
61 * @see _SMP_Send_message().
62 */
63#define SMP_MESSAGE_SHUTDOWN 0x1UL
64
65/**
66 * @brief SMP message to perform per-processor jobs.
67 *
68 * @see _SMP_Send_message().
69 */
70#define SMP_MESSAGE_PERFORM_JOBS 0x2UL
71
72/**
73 * @brief SMP message to force the message processing in
74 *   _SMP_Try_to_process_message().
75 *
76 * This message bit is never sent to a processor.  It is only used to force the
77 * message processing in _SMP_Try_to_process_message().  Any non-zero value
78 * would do it.
79 */
80#define SMP_MESSAGE_FORCE_PROCESSING 0x4UL
81
82/**
83 * @brief SMP fatal codes.
84 */
85typedef enum {
86  SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER,
87  SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT,
88  SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR,
89  SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR,
90  SMP_FATAL_SHUTDOWN,
91  SMP_FATAL_SHUTDOWN_RESPONSE,
92  SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED,
93  SMP_FATAL_SCHEDULER_PIN_OR_UNPIN_NOT_SUPPORTED,
94  SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS,
95  SMP_FATAL_SCHEDULER_REQUIRES_EXACTLY_ONE_PROCESSOR,
96  SMP_FATAL_MULTITASKING_START_ON_NOT_ONLINE_PROCESSOR
97} SMP_Fatal_code;
98
99/**
100 * @brief Terminates with the given code.
101 *
102 * @param code The code for the termination.
103 */
104static inline void _SMP_Fatal( SMP_Fatal_code code )
105{
106  _Terminate( RTEMS_FATAL_SOURCE_SMP, code );
107}
108
109/**
110 * @brief Initializes SMP Handler
111 *
112 * This method initialize the SMP Handler.
113 */
114#if defined( RTEMS_SMP )
115  void _SMP_Handler_initialize( void );
116#else
117  #define _SMP_Handler_initialize() \
118    do { } while ( 0 )
119#endif
120
121#if defined( RTEMS_SMP )
122
123/**
124 * @brief Set of online processors.
125 *
126 * A processor is online if was started during system initialization.  In this
127 * case its corresponding bit in the mask is set.
128 *
129 * @see _SMP_Handler_initialize().
130 */
131extern Processor_mask _SMP_Online_processors;
132
133/**
134 * @brief Performs high-level initialization of a secondary processor and runs
135 * the application threads.
136 *
137 * The low-level initialization code must call this function to hand over the
138 * control of this processor to RTEMS.  Interrupts must be disabled.  It must
139 * be possible to send inter-processor interrupts to this processor.  Since
140 * interrupts are disabled the inter-processor interrupt delivery is postponed
141 * until interrupts are enabled the first time.  Interrupts are enabled during
142 * the execution begin of threads in case they have interrupt level zero (this
143 * is the default).
144 *
145 * The pre-requisites for the call to this function are
146 * - disabled interrupts,
147 * - delivery of inter-processor interrupts is possible,
148 * - a valid stack pointer and enough stack space,
149 * - a valid code memory, and
150 * - a valid BSS section.
151 *
152 * This function must not be called by the main processor.  The main processor
153 * uses _Thread_Start_multitasking() instead.
154 *
155 * This function does not return to the caller.
156 *
157 * @param cpu_self The current processor control.
158 */
159RTEMS_NO_RETURN void _SMP_Start_multitasking_on_secondary_processor(
160  Per_CPU_Control *cpu_self
161);
162
163/**
164 * @brief Processes the SMP message.
165 *
166 * @param[in, out] cpu_self is the processor control of the processor executing
167 *   this function.
168 *
169 * @return Returns the processed message.
170 */
171long unsigned _SMP_Process_message(
172  Per_CPU_Control *cpu_self,
173  long unsigned    message
174);
175
176/**
177 * @brief Tries to process the current SMP message.
178 *
179 * This function may be used in busy wait loops.
180 *
181 * @param cpu_self is the processor control of the processor executing this
182 *   function.
183 *
184 * @param message is used to check if the SMP message processing should be
185 *   carried out.  If it is not equal to zero, then _SMP_Process_message() is
186 *   called with a newly fetched message.  This parameter is not used to process
187 *   the message.  It is only used to check if the processing is necessary.
188 *   Use #SMP_MESSAGE_FORCE_PROCESSING to force the message processing.
189 */
190void _SMP_Try_to_process_message(
191  Per_CPU_Control *cpu_self,
192  unsigned long    message
193);
194
195/**
196 * @brief Processes an inter-processor interrupt.
197 *
198 * Use this function for the inter-processor interrupt handler.  Never call
199 * this function in a tight loop.
200 *
201 * @param[in, out] cpu_self is the processor control of the processor executing
202 *   this function.
203 *
204 * @return Returns the processed message.
205 */
206static inline long unsigned _SMP_Inter_processor_interrupt_handler(
207  Per_CPU_Control *cpu_self
208)
209{
210  unsigned long message;
211
212  /*
213   * In the common case the inter-processor interrupt is issued to carry out a
214   * thread dispatch.
215   */
216  cpu_self->dispatch_necessary = true;
217
218  message = _Atomic_Exchange_ulong(
219    &cpu_self->message,
220    0,
221    ATOMIC_ORDER_ACQUIRE
222  );
223
224  if ( RTEMS_PREDICT_FALSE( message != 0 ) ) {
225    return _SMP_Process_message( cpu_self, message );
226  }
227
228  return message;
229}
230
231/**
232 * @brief Checks if the processor with the specified index should be started.
233 *
234 * @param cpu_index The processor index.
235 *
236 * @retval true The processor should be started.
237 * @retval false The processor should not be started.
238 */
239bool _SMP_Should_start_processor( uint32_t cpu_index );
240
241/**
242 * @brief Sends the SMP message to the processor.
243 *
244 * The target processor may be the sending processor.
245 *
246 * @param[in, out] cpu is the processor control of the target processor.
247 *
248 * @param message is the message to send.
249 */
250void _SMP_Send_message( Per_CPU_Control *cpu, unsigned long message );
251
252typedef void ( *SMP_Action_handler )( void *arg );
253
254/**
255 * @brief Initiates an SMP multicast action to the set of target processors.
256 *
257 * The current processor may be part of the set.  The caller must ensure that
258 * no thread dispatch can happen during the call of this function, otherwise
259 * the behaviour is undefined.  In case a target processor is in a wrong state
260 * to process per-processor jobs, then this function results in an
261 * SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS fatal SMP error.
262 *
263 * @param targets The set of target processors for the action.
264 * @param handler The multicast action handler.
265 * @param arg The multicast action argument.
266 */
267void _SMP_Multicast_action(
268  const Processor_mask *targets,
269  SMP_Action_handler    handler,
270  void                 *arg
271);
272
273/**
274 * @brief Initiates an SMP multicast action to the set of all online
275 * processors.
276 *
277 * Simply calls _SMP_Multicast_action() with _SMP_Get_online_processors() as
278 * the target processor set.
279 *
280 * @param handler The multicast action handler.
281 * @param arg The multicast action argument.
282 */
283void _SMP_Broadcast_action(
284  SMP_Action_handler  handler,
285  void               *arg
286);
287
288/**
289 * @brief Initiates an SMP multicast action to the set of all online
290 * processors excluding the current processor.
291 *
292 * Simply calls _SMP_Multicast_action() with _SMP_Get_online_processors() as
293 * the target processor set excluding the current processor.
294 *
295 * @param handler The multicast action handler.
296 * @param arg The multicast action argument.
297 */
298void _SMP_Othercast_action(
299  SMP_Action_handler  handler,
300  void               *arg
301);
302
303/**
304 * @brief Initiates an SMP action on the specified target processor.
305 *
306 * This is an optimized variant of _SMP_Multicast_action().
307 *
308 * @param cpu_index The index of the target processor.
309 * @param handler The action handler.
310 * @param arg The action argument.
311 */
312void _SMP_Unicast_action(
313  uint32_t            cpu_index,
314  SMP_Action_handler  handler,
315  void               *arg
316);
317
318/**
319 * @brief Ensures that all store operations issued by the current processor
320 * before the call this function are visible to all other online processors.
321 *
322 * Simply calls _SMP_Othercast_action() with an empty multicast action.
323 */
324void _SMP_Synchronize( void );
325
326#endif /* defined( RTEMS_SMP ) */
327
328/**
329 * @brief Requests a multitasking start on all configured and available
330 * processors.
331 */
332#if defined( RTEMS_SMP )
333  void _SMP_Request_start_multitasking( void );
334#else
335  #define _SMP_Request_start_multitasking() \
336    do { } while ( 0 )
337#endif
338
339/**
340 * @brief Requests a shutdown of all processors.
341 *
342 * This function is a part of the system termination procedure.
343 *
344 * @see _Terminate().
345 */
346#if defined( RTEMS_SMP )
347  void _SMP_Request_shutdown( void );
348#else
349  #define _SMP_Request_shutdown() \
350    do { } while ( 0 )
351#endif
352
353/**
354 * @brief Gets all online processors
355 *
356 * @return The processor mask with all online processors.
357 */
358static inline const Processor_mask *_SMP_Get_online_processors( void )
359{
360#if defined(RTEMS_SMP)
361  return &_SMP_Online_processors;
362#else
363  return &_Processor_mask_The_one_and_only;
364#endif
365}
366
367/**
368 * @brief Indicate if inter-processor interrupts are needed.
369 *
370 * @return True if inter-processor interrupts are needed for the correct system
371 * operation, otherwise false.
372 */
373static inline bool _SMP_Need_inter_processor_interrupts( void )
374{
375  /*
376   * Use the configured processor maximum instead of the actual to allow
377   * testing on uni-processor systems.
378   */
379  return _SMP_Processor_configured_maximum > 1;
380}
381
382/** @} */
383
384#ifdef __cplusplus
385}
386#endif
387
388#endif
389/* end of include file */
Note: See TracBrowser for help on using the repository browser.