source: rtems/cpukit/include/rtems/score/smpimpl.h @ 21275b58

5
Last change on this file since 21275b58 was 7097962, checked in by Sebastian Huber <sebastian.huber@…>, on 08/29/18 at 07:43:44

score: Add thread pin/unpin support

Add support to temporarily pin a thread to its current processor. This
may be used to access per-processor data structures in critical sections
with enabled thread dispatching, e.g. a pinned thread is allowed to
block.

Update #3508.

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