source: rtems/cpukit/score/src/schedulersimplesmp.c @ f068384e

4.115
Last change on this file since f068384e was f068384e, checked in by Sebastian Huber <sebastian.huber@…>, on 07/24/13 at 10:03:31

score: Create schedulerpriority impl header

Move implementation specific parts of schedulerpriority.h and
schedulerpriority.inl into new header file schedulerpriorityimpl.h. The
schedulerpriority.h contains now only the application visible API.

Add missing includes. Remove superfluous includes.

Move declaration of _Priority_Bit_map to prioritybitmap.inl since this
variable is used only here.

Remove second declaration of _Priority_Major_bit_map.

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Simple SMP Scheduler Implementation
5 *
6 * @ingroup ScoreSchedulerSMP
7 */
8
9/*
10 * Copyright (c) 2013 embedded brains GmbH.
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.com/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18  #include "config.h"
19#endif
20
21#include <rtems/score/schedulersimplesmp.h>
22#include <rtems/score/schedulersimpleimpl.h>
23#include <rtems/score/wkspace.h>
24
25static Scheduler_simple_smp_Control *_Scheduler_simple_smp_Instance( void )
26{
27  return _Scheduler.information;
28}
29
30void _Scheduler_simple_smp_Initialize( void )
31{
32  Scheduler_simple_smp_Control *self =
33    _Workspace_Allocate_or_fatal_error( sizeof( *self ) );
34
35  _Chain_Initialize_empty( &self->ready );
36  _Chain_Initialize_empty( &self->scheduled );
37
38  _Scheduler.information = self;
39}
40
41static void _Scheduler_simple_smp_Allocate_processor(
42  Thread_Control *scheduled,
43  Thread_Control *victim
44)
45{
46  Per_CPU_Control *cpu_of_scheduled = scheduled->cpu;
47  Per_CPU_Control *cpu_of_victim = victim->cpu;
48  Thread_Control *heir;
49
50  scheduled->is_scheduled = true;
51  victim->is_scheduled = false;
52
53  if ( scheduled->is_executing ) {
54    heir = cpu_of_scheduled->heir;
55    cpu_of_scheduled->heir = scheduled;
56  } else {
57    heir = scheduled;
58  }
59
60  if ( heir != victim ) {
61    heir->cpu = cpu_of_victim;
62    cpu_of_victim->heir = heir;
63    cpu_of_victim->dispatch_necessary = true;
64  }
65}
66
67static void _Scheduler_simple_smp_Move_from_scheduled_to_ready(
68  Chain_Control *ready_chain,
69  Thread_Control *scheduled_to_ready
70)
71{
72  _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
73  _Scheduler_simple_Insert_priority_lifo( ready_chain, scheduled_to_ready );
74}
75
76static void _Scheduler_simple_smp_Move_from_ready_to_scheduled(
77  Chain_Control *scheduled_chain,
78  Thread_Control *ready_to_scheduled
79)
80{
81  _Chain_Extract_unprotected( &ready_to_scheduled->Object.Node );
82  _Scheduler_simple_Insert_priority_fifo( scheduled_chain, ready_to_scheduled );
83}
84
85static void _Scheduler_simple_smp_Insert(
86  Chain_Control *chain,
87  Thread_Control *thread,
88  Chain_Node_order order
89)
90{
91  _Chain_Insert_ordered_unprotected( chain, &thread->Object.Node, order );
92}
93
94static void _Scheduler_simple_smp_Enqueue_ordered(
95  Thread_Control *thread,
96  Chain_Node_order order
97)
98{
99  Scheduler_simple_smp_Control *self = _Scheduler_simple_smp_Instance();
100
101  /*
102   * The scheduled chain has exactly processor count nodes after
103   * initialization, thus the lowest priority scheduled thread exists.
104   */
105  Thread_Control *lowest_scheduled =
106    (Thread_Control *) _Chain_Last( &self->scheduled );
107
108  if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
109    _Scheduler_simple_smp_Allocate_processor( thread, lowest_scheduled );
110
111    _Scheduler_simple_smp_Insert( &self->scheduled, thread, order );
112
113    _Scheduler_simple_smp_Move_from_scheduled_to_ready(
114      &self->ready,
115      lowest_scheduled
116    );
117  } else {
118    _Scheduler_simple_smp_Insert( &self->ready, thread, order );
119  }
120}
121
122void _Scheduler_simple_smp_Enqueue_priority_lifo( Thread_Control *thread )
123{
124  _Scheduler_simple_smp_Enqueue_ordered(
125    thread,
126    _Scheduler_simple_Insert_priority_lifo_order
127  );
128}
129
130void _Scheduler_simple_smp_Enqueue_priority_fifo( Thread_Control *thread )
131{
132  _Scheduler_simple_smp_Enqueue_ordered(
133    thread,
134    _Scheduler_simple_Insert_priority_fifo_order
135  );
136}
137
138void _Scheduler_simple_smp_Extract( Thread_Control *thread )
139{
140  Scheduler_simple_smp_Control *self = _Scheduler_simple_smp_Instance();
141
142  _Chain_Extract_unprotected( &thread->Object.Node );
143
144  if ( thread->is_scheduled ) {
145    Thread_Control *highest_ready =
146      (Thread_Control *) _Chain_First( &self->ready );
147
148    _Scheduler_simple_smp_Allocate_processor( highest_ready, thread );
149
150    _Scheduler_simple_smp_Move_from_ready_to_scheduled(
151      &self->scheduled,
152      highest_ready
153    );
154  }
155}
156
157void _Scheduler_simple_smp_Yield( Thread_Control *thread )
158{
159  ISR_Level level;
160
161  _ISR_Disable( level );
162
163  _Scheduler_simple_smp_Extract( thread );
164  _Scheduler_simple_smp_Enqueue_priority_fifo( thread );
165
166  _ISR_Enable( level );
167}
168
169void _Scheduler_simple_smp_Schedule( void )
170{
171  /* Nothing to do */
172}
173
174void _Scheduler_simple_smp_Start_idle(
175  Thread_Control *thread,
176  Per_CPU_Control *cpu
177)
178{
179  Scheduler_simple_smp_Control *self = _Scheduler_simple_smp_Instance();
180
181  thread->is_scheduled = true;
182  thread->cpu = cpu;
183  _Chain_Append_unprotected( &self->scheduled, &thread->Object.Node );
184}
Note: See TracBrowser for help on using the repository browser.