source: rtems/cpukit/score/src/schedulerprioritysmp.c @ c499856

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/**
2 * @file
3 *
4 * @brief Deterministic Priority SMP Scheduler Implementation
5 *
6 * @ingroup ScoreSchedulerSMP
7 */
8
9/*
10 * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#if HAVE_CONFIG_H
24  #include "config.h"
25#endif
26
27#include <rtems/score/schedulerprioritysmp.h>
28#include <rtems/score/schedulerpriorityimpl.h>
29#include <rtems/score/schedulersmpimpl.h>
30#include <rtems/score/wkspace.h>
31
32void _Scheduler_priority_SMP_Initialize( void )
33{
34  Scheduler_SMP_Control *self = _Workspace_Allocate_or_fatal_error(
35    sizeof( *self ) + PRIORITY_MAXIMUM * sizeof( Chain_Control )
36  );
37
38  _Chain_Initialize_empty( &self->scheduled );
39  _Scheduler_priority_Ready_queue_initialize( &self->ready[ 0 ] );
40
41  _Scheduler.information = self;
42}
43
44void _Scheduler_priority_SMP_Update( Thread_Control *thread )
45{
46  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
47
48  _Scheduler_priority_Update_body( thread, &self->ready[ 0 ] );
49}
50
51static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready(
52  Scheduler_SMP_Control *self
53)
54{
55  Thread_Control *highest_ready = NULL;
56
57  if ( !_Priority_bit_map_Is_empty() ) {
58    highest_ready = _Scheduler_priority_Ready_queue_first( &self->ready[ 0 ] );
59  }
60
61  return highest_ready;
62}
63
64static void _Scheduler_priority_SMP_Move_from_scheduled_to_ready(
65  Scheduler_SMP_Control *self,
66  Thread_Control *scheduled_to_ready
67)
68{
69  _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
70  _Scheduler_priority_Ready_queue_enqueue_first( scheduled_to_ready );
71}
72
73static void _Scheduler_priority_SMP_Move_from_ready_to_scheduled(
74  Scheduler_SMP_Control *self,
75  Thread_Control *ready_to_scheduled
76)
77{
78  _Scheduler_priority_Ready_queue_extract( ready_to_scheduled );
79  _Scheduler_simple_Insert_priority_fifo(
80    &self->scheduled,
81    ready_to_scheduled
82  );
83}
84
85static void _Scheduler_priority_SMP_Insert_ready_lifo(
86  Scheduler_SMP_Control *self,
87  Thread_Control *thread
88)
89{
90  _Scheduler_priority_Ready_queue_enqueue( thread );
91}
92
93static void _Scheduler_priority_SMP_Insert_ready_fifo(
94  Scheduler_SMP_Control *self,
95  Thread_Control *thread
96)
97{
98  _Scheduler_priority_Ready_queue_enqueue_first( thread );
99}
100
101static void _Scheduler_priority_SMP_Do_extract(
102  Scheduler_SMP_Control *self,
103  Thread_Control *thread
104)
105{
106  bool is_scheduled = thread->is_scheduled;
107
108  ( void ) self;
109
110  thread->is_in_the_air = is_scheduled;
111  thread->is_scheduled = false;
112
113  if ( is_scheduled ) {
114    _Chain_Extract_unprotected( &thread->Object.Node );
115  } else {
116    _Scheduler_priority_Ready_queue_extract( thread );
117  }
118}
119
120void _Scheduler_priority_SMP_Block( Thread_Control *thread )
121{
122  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
123
124  _Scheduler_SMP_Block(
125    self,
126    thread,
127    _Scheduler_priority_SMP_Do_extract,
128    _Scheduler_priority_SMP_Get_highest_ready,
129    _Scheduler_priority_SMP_Move_from_ready_to_scheduled
130  );
131}
132
133static void _Scheduler_priority_SMP_Enqueue_ordered(
134  Scheduler_SMP_Control *self,
135  Thread_Control *thread,
136  Chain_Node_order order,
137  Scheduler_SMP_Insert insert_ready,
138  Scheduler_SMP_Insert insert_scheduled
139)
140{
141  _Scheduler_SMP_Enqueue_ordered(
142    self,
143    thread,
144    order,
145    _Scheduler_priority_SMP_Get_highest_ready,
146    insert_ready,
147    insert_scheduled,
148    _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
149    _Scheduler_priority_SMP_Move_from_scheduled_to_ready
150  );
151}
152
153void _Scheduler_priority_SMP_Enqueue_lifo( Thread_Control *thread )
154{
155  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
156
157  _Scheduler_priority_SMP_Enqueue_ordered(
158    self,
159    thread,
160    _Scheduler_simple_Insert_priority_lifo_order,
161    _Scheduler_priority_SMP_Insert_ready_lifo,
162    _Scheduler_SMP_Insert_scheduled_lifo
163  );
164}
165
166void _Scheduler_priority_SMP_Enqueue_fifo( Thread_Control *thread )
167{
168  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
169
170  _Scheduler_priority_SMP_Enqueue_ordered(
171    self,
172    thread,
173    _Scheduler_simple_Insert_priority_fifo_order,
174    _Scheduler_priority_SMP_Insert_ready_fifo,
175    _Scheduler_SMP_Insert_scheduled_fifo
176  );
177}
178
179void _Scheduler_priority_SMP_Extract( Thread_Control *thread )
180{
181  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
182
183  _Scheduler_SMP_Extract(
184    self,
185    thread,
186    _Scheduler_priority_SMP_Do_extract
187  );
188}
189
190void _Scheduler_priority_SMP_Yield( Thread_Control *thread )
191{
192  ISR_Level level;
193
194  _ISR_Disable( level );
195
196  _Scheduler_priority_SMP_Extract( thread );
197  _Scheduler_priority_SMP_Enqueue_fifo( thread );
198
199  _ISR_Enable( level );
200}
201
202void _Scheduler_priority_SMP_Schedule( Thread_Control *thread )
203{
204  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
205
206  _Scheduler_SMP_Schedule(
207    self,
208    thread,
209    _Scheduler_priority_SMP_Get_highest_ready,
210    _Scheduler_priority_SMP_Move_from_ready_to_scheduled
211  );
212}
Note: See TracBrowser for help on using the repository browser.