source: rtems/cpukit/score/src/smp.c @ 3380ee8

4.115
Last change on this file since 3380ee8 was 3380ee8, checked in by Sebastian Huber <sebastian.huber@…>, on 04/22/14 at 05:46:53

score: Use common names for per-CPU variables

Use "cpu" for an arbitrary Per_CPU_Control variable.

Use "cpu_self" for the Per_CPU_Control of the current processor.

Use "cpu_index" for an arbitrary processor index.

Use "cpu_index_self" for the processor index of the current processor.

Use "cpu_count" for the processor count obtained via
_SMP_Get_processor_count().

Use "cpu_max" for the processor maximum obtained by
rtems_configuration_get_maximum_processors().

  • Property mode set to 100644
File size: 4.8 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief SMP Support
5 *  @ingroup Score
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2011.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/smpimpl.h>
22#include <rtems/score/assert.h>
23#include <rtems/score/schedulerimpl.h>
24#include <rtems/score/threaddispatch.h>
25#include <rtems/score/threadimpl.h>
26#include <rtems/config.h>
27
28static void _SMP_Check_scheduler_configuration( void )
29{
30  size_t n = _Scheduler_Count;
31  size_t i;
32
33  for ( i = 0 ; i < n ; ++i ) {
34    const Scheduler_Control *scheduler = &_Scheduler_Table[ i ];
35
36    if ( scheduler->context->processor_count == 0 ) {
37      _SMP_Fatal( SMP_FATAL_SCHEDULER_WITHOUT_PROCESSORS );
38    }
39  }
40}
41
42static void _SMP_Start_processors( uint32_t cpu_count )
43{
44  uint32_t cpu_index_self = _SMP_Get_current_processor();
45  uint32_t cpu_index;
46
47
48  for ( cpu_index = 0 ; cpu_index < cpu_count; ++cpu_index ) {
49    const Scheduler_Assignment *assignment =
50      _Scheduler_Get_assignment( cpu_index );
51    Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
52    bool started;
53
54    if ( cpu_index != cpu_index_self ) {
55      if ( _Scheduler_Should_start_processor( assignment ) ) {
56        started = _CPU_SMP_Start_processor( cpu_index );
57
58        if ( !started && _Scheduler_Is_mandatory_processor( assignment ) ) {
59          _SMP_Fatal( SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED );
60        }
61      } else {
62        started = false;
63      }
64    } else {
65      started = true;
66
67      if ( !_Scheduler_Should_start_processor( assignment ) ) {
68        _SMP_Fatal( SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER );
69      }
70    }
71
72    cpu->started = started;
73
74    if ( started ) {
75      ++assignment->scheduler->context->processor_count;
76    }
77  }
78
79  _SMP_Check_scheduler_configuration();
80}
81
82void _SMP_Handler_initialize( void )
83{
84  uint32_t cpu_max = rtems_configuration_get_maximum_processors();
85  uint32_t cpu_count;
86  uint32_t cpu_index;
87
88  for ( cpu_index = 0 ; cpu_index < cpu_max; ++cpu_index ) {
89    Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
90
91    _SMP_ticket_lock_Initialize( &cpu->Lock, "per-CPU" );
92  }
93
94  /*
95   * Discover and initialize the secondary cores in an SMP system.
96   */
97
98  cpu_count = _CPU_SMP_Initialize();
99  cpu_count = cpu_count < cpu_max ? cpu_count : cpu_max;
100  _SMP_Processor_count = cpu_count;
101
102  for ( cpu_index = cpu_count ; cpu_index < cpu_max; ++cpu_index ) {
103    const Scheduler_Assignment *assignment =
104      _Scheduler_Get_assignment( cpu_index );
105
106    if ( _Scheduler_Is_mandatory_processor( assignment ) ) {
107      _SMP_Fatal( SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT );
108    }
109  }
110
111  _SMP_Start_processors( cpu_count );
112
113  _CPU_SMP_Finalize_initialization( cpu_count );
114}
115
116void _SMP_Request_start_multitasking( void )
117{
118  Per_CPU_Control *self_cpu = _Per_CPU_Get();
119  uint32_t cpu_count = _SMP_Get_processor_count();
120  uint32_t cpu_index;
121
122  _Per_CPU_State_change( self_cpu, PER_CPU_STATE_READY_TO_START_MULTITASKING );
123
124  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
125    Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
126
127    _Per_CPU_State_change( cpu, PER_CPU_STATE_REQUEST_START_MULTITASKING );
128  }
129}
130
131void _SMP_Start_multitasking_on_secondary_processor( void )
132{
133  Per_CPU_Control *self_cpu = _Per_CPU_Get();
134
135  if ( !_Per_CPU_Is_processor_started( self_cpu ) ) {
136    _SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR );
137  }
138
139  _Per_CPU_State_change( self_cpu, PER_CPU_STATE_READY_TO_START_MULTITASKING );
140
141  _Thread_Start_multitasking();
142}
143
144void _SMP_Request_shutdown( void )
145{
146  Per_CPU_Control *self_cpu = _Per_CPU_Get();
147
148  _Per_CPU_State_change( self_cpu, PER_CPU_STATE_SHUTDOWN );
149
150  /*
151   * We have to drop the Giant lock here in order to give other processors the
152   * opportunity to receive the inter-processor interrupts issued previously.
153   * In case the executing thread still holds SMP locks, then other processors
154   * already waiting for this SMP lock will spin forever.
155   */
156  _Giant_Drop( self_cpu );
157}
158
159void _SMP_Send_message( uint32_t cpu_index, uint32_t message )
160{
161  Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
162  ISR_Level level;
163
164  _Per_CPU_ISR_disable_and_acquire( cpu, level );
165  cpu->message |= message;
166  _Per_CPU_Release_and_ISR_enable( cpu, level );
167
168  _CPU_SMP_Send_interrupt( cpu_index );
169}
170
171void _SMP_Broadcast_message( uint32_t message )
172{
173  uint32_t cpu_count = _SMP_Get_processor_count();
174  uint32_t cpu_index_self = _SMP_Get_current_processor();
175  uint32_t cpu_index;
176
177  _Assert( _Debug_Is_thread_dispatching_allowed() );
178
179  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
180    if ( cpu_index != cpu_index_self ) {
181      _SMP_Send_message( cpu_index, message );
182    }
183  }
184}
Note: See TracBrowser for help on using the repository browser.