source: rtems/cpukit/rtems/src/schedulerremoveprocessor.c @ 66cb142

Last change on this file since 66cb142 was 3b14e7aa, checked in by Sebastian Huber <sebastian.huber@…>, on Jul 11, 2017 at 11:51:10 AM

rtems: Fix warning

Update #3059.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include <rtems/rtems/tasks.h>
20#include <rtems/score/schedulerimpl.h>
21#include <rtems/config.h>
22
23#if defined(RTEMS_SMP)
24typedef struct {
25  const Scheduler_Control *scheduler;
26  rtems_status_code        status;
27} Scheduler_Processor_removal_context;
28
29static bool _Scheduler_Check_processor_removal(
30  Thread_Control *the_thread,
31  void           *arg
32)
33{
34  Scheduler_Processor_removal_context *iter_context;
35  Thread_queue_Context                 queue_context;
36  ISR_lock_Context                     state_context;
37
38  if ( the_thread->is_idle ) {
39    return false;
40  }
41
42  iter_context = arg;
43
44  _Thread_queue_Context_initialize( &queue_context );
45  _Thread_Wait_acquire( the_thread, &queue_context );
46  _Thread_State_acquire_critical( the_thread, &state_context );
47
48  if (
49    _Thread_Scheduler_get_home( the_thread ) == iter_context->scheduler
50      && !_Processor_mask_Has_overlap(
51        &the_thread->Scheduler.Affinity,
52        _Scheduler_Get_processors( iter_context->scheduler )
53      )
54  ) {
55    iter_context->status = RTEMS_RESOURCE_IN_USE;
56  }
57
58  _Thread_State_release_critical( the_thread, &state_context );
59  _Thread_Wait_release( the_thread, &queue_context );
60  return iter_context->status != RTEMS_SUCCESSFUL;
61}
62#endif
63
64rtems_status_code rtems_scheduler_remove_processor(
65  rtems_id scheduler_id,
66  uint32_t cpu_index
67)
68{
69  const Scheduler_Control             *scheduler;
70#if defined(RTEMS_SMP)
71  Scheduler_Processor_removal_context  iter_context;
72  ISR_lock_Context                     lock_context;
73  Scheduler_Context                   *scheduler_context;
74  Per_CPU_Control                     *cpu;
75  Per_CPU_Control                     *cpu_self;
76#endif
77
78  scheduler = _Scheduler_Get_by_id( scheduler_id );
79  if ( scheduler == NULL ) {
80    return RTEMS_INVALID_ID;
81  }
82
83  if ( cpu_index >= rtems_configuration_get_maximum_processors() ) {
84    return RTEMS_INVALID_NUMBER;
85  }
86
87#if defined(RTEMS_SMP)
88  iter_context.scheduler = scheduler;
89  iter_context.status = RTEMS_SUCCESSFUL;
90  scheduler_context = _Scheduler_Get_context( scheduler );
91  cpu = _Per_CPU_Get_by_index( cpu_index );
92
93  _Objects_Allocator_lock();
94
95  if ( cpu->Scheduler.control != scheduler ) {
96    _Objects_Allocator_unlock();
97    return RTEMS_INVALID_NUMBER;
98  }
99
100  /*
101   * This prevents the selection of this scheduler instance by new threads in
102   * case the processor count changes to zero.
103   */
104  _ISR_lock_ISR_disable( &lock_context );
105  _Scheduler_Acquire_critical( scheduler, &lock_context );
106  _Processor_mask_Clear( &scheduler_context->Processors, cpu_index );
107  _Scheduler_Release_critical( scheduler, &lock_context );
108  _ISR_lock_ISR_enable( &lock_context );
109
110  _Thread_Iterate( _Scheduler_Check_processor_removal, &iter_context );
111
112  _ISR_lock_ISR_disable( &lock_context );
113  _Scheduler_Acquire_critical( scheduler, &lock_context );
114
115  if ( iter_context.status == RTEMS_SUCCESSFUL ) {
116    Thread_Control *idle;
117    Scheduler_Node *scheduler_node;
118
119    cpu->Scheduler.control = NULL;
120    cpu->Scheduler.context = NULL;
121    idle = ( *scheduler->Operations.remove_processor )( scheduler, cpu );
122    cpu->Scheduler.idle_if_online_and_unused = idle;
123
124    scheduler_node = _Thread_Scheduler_get_home_node( idle );
125    _Priority_Plain_extract(
126      &scheduler_node->Wait.Priority,
127      &idle->Real_priority
128    );
129    _Assert( _Priority_Is_empty( &scheduler_node->Wait.Priority ) );
130    _Chain_Extract_unprotected( &scheduler_node->Thread.Wait_node );
131    _Assert( _Chain_Is_empty( &idle->Scheduler.Wait_nodes ) );
132    _Chain_Extract_unprotected( &scheduler_node->Thread.Scheduler_node.Chain );
133    _Assert( _Chain_Is_empty( &idle->Scheduler.Scheduler_nodes ) );
134  } else {
135    _Processor_mask_Set( &scheduler_context->Processors, cpu_index );
136  }
137
138  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
139  _Scheduler_Release_critical( scheduler, &lock_context );
140  _ISR_lock_ISR_enable( &lock_context );
141  _Thread_Dispatch_direct( cpu_self );
142  _Objects_Allocator_unlock();
143  return iter_context.status;
144#else
145  return RTEMS_RESOURCE_IN_USE;
146#endif
147}
Note: See TracBrowser for help on using the repository browser.