[99b3505] | 1 | /** |
---|
| 2 | * @file |
---|
| 3 | * |
---|
[beab7329] | 4 | * @ingroup ScoreSchedulerPrioritySMP |
---|
[99b3505] | 5 | * |
---|
[beab7329] | 6 | * @brief Deterministic Priority SMP Scheduler Implementation |
---|
[99b3505] | 7 | */ |
---|
| 8 | |
---|
| 9 | /* |
---|
[494c2e3] | 10 | * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. |
---|
[99b3505] | 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 |
---|
[c499856] | 20 | * http://www.rtems.org/license/LICENSE. |
---|
[99b3505] | 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> |
---|
[238629f] | 29 | #include <rtems/score/schedulerprioritysmpimpl.h> |
---|
[99b3505] | 30 | #include <rtems/score/schedulersmpimpl.h> |
---|
| 31 | |
---|
[e1598a6] | 32 | static Scheduler_priority_SMP_Context * |
---|
| 33 | _Scheduler_priority_SMP_Get_context( const Scheduler_Control *scheduler ) |
---|
[494c2e3] | 34 | { |
---|
[2369b10] | 35 | return (Scheduler_priority_SMP_Context *) _Scheduler_Get_context( scheduler ); |
---|
[494c2e3] | 36 | } |
---|
| 37 | |
---|
[238629f] | 38 | Scheduler_priority_SMP_Context *_Scheduler_priority_SMP_Get_self( |
---|
| 39 | Scheduler_Context *context |
---|
| 40 | ) |
---|
[494c2e3] | 41 | { |
---|
[3730a07f] | 42 | return (Scheduler_priority_SMP_Context *) context; |
---|
[494c2e3] | 43 | } |
---|
| 44 | |
---|
[238629f] | 45 | Scheduler_priority_SMP_Node *_Scheduler_priority_SMP_Node_get( |
---|
[beab7329] | 46 | Thread_Control *thread |
---|
| 47 | ) |
---|
| 48 | { |
---|
| 49 | return (Scheduler_priority_SMP_Node *) _Scheduler_Node_get( thread ); |
---|
| 50 | } |
---|
| 51 | |
---|
[f39f667a] | 52 | static Scheduler_priority_SMP_Node *_Scheduler_priority_SMP_Node_downcast( |
---|
| 53 | Scheduler_Node *node |
---|
| 54 | ) |
---|
| 55 | { |
---|
| 56 | return (Scheduler_priority_SMP_Node *) node; |
---|
| 57 | } |
---|
| 58 | |
---|
[e1598a6] | 59 | void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler ) |
---|
[99b3505] | 60 | { |
---|
[e1598a6] | 61 | Scheduler_priority_SMP_Context *self = |
---|
| 62 | _Scheduler_priority_SMP_Get_context( scheduler ); |
---|
[99b3505] | 63 | |
---|
[494c2e3] | 64 | _Scheduler_SMP_Initialize( &self->Base ); |
---|
| 65 | _Priority_bit_map_Initialize( &self->Bit_map ); |
---|
| 66 | _Scheduler_priority_Ready_queue_initialize( &self->Ready[ 0 ] ); |
---|
[99b3505] | 67 | } |
---|
| 68 | |
---|
[8e467384] | 69 | void _Scheduler_priority_SMP_Node_initialize( |
---|
[beab7329] | 70 | const Scheduler_Control *scheduler, |
---|
| 71 | Thread_Control *thread |
---|
| 72 | ) |
---|
| 73 | { |
---|
| 74 | Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread ); |
---|
| 75 | |
---|
| 76 | _Scheduler_SMP_Node_initialize( node ); |
---|
| 77 | } |
---|
| 78 | |
---|
[238629f] | 79 | void _Scheduler_priority_SMP_Do_update( |
---|
[f39f667a] | 80 | Scheduler_Context *context, |
---|
| 81 | Scheduler_Node *base_node, |
---|
| 82 | Priority_Control new_priority |
---|
[24934e36] | 83 | ) |
---|
[99b3505] | 84 | { |
---|
[e1598a6] | 85 | Scheduler_priority_SMP_Context *self = |
---|
[f39f667a] | 86 | _Scheduler_priority_SMP_Get_self( context ); |
---|
[beab7329] | 87 | Scheduler_priority_SMP_Node *node = |
---|
[f39f667a] | 88 | _Scheduler_priority_SMP_Node_downcast( base_node ); |
---|
[99b3505] | 89 | |
---|
[beab7329] | 90 | _Scheduler_priority_Ready_queue_update( |
---|
| 91 | &node->Ready_queue, |
---|
[f39f667a] | 92 | new_priority, |
---|
[494c2e3] | 93 | &self->Bit_map, |
---|
| 94 | &self->Ready[ 0 ] |
---|
| 95 | ); |
---|
[99b3505] | 96 | } |
---|
| 97 | |
---|
[4d1f500] | 98 | void _Scheduler_priority_SMP_Update_priority( |
---|
[f39f667a] | 99 | const Scheduler_Control *scheduler, |
---|
[4d1f500] | 100 | Thread_Control *thread, |
---|
| 101 | Priority_Control new_priority |
---|
[f39f667a] | 102 | ) |
---|
| 103 | { |
---|
| 104 | Scheduler_Context *context = _Scheduler_Get_context( scheduler ); |
---|
| 105 | Scheduler_Node *node = _Scheduler_Node_get( thread ); |
---|
| 106 | |
---|
[4d1f500] | 107 | _Scheduler_priority_SMP_Do_update( context, node, new_priority ); |
---|
[f39f667a] | 108 | } |
---|
| 109 | |
---|
[99b3505] | 110 | static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready( |
---|
[238629f] | 111 | Scheduler_Context *context, |
---|
| 112 | Thread_Control *thread |
---|
[99b3505] | 113 | ) |
---|
| 114 | { |
---|
[e1598a6] | 115 | Scheduler_priority_SMP_Context *self = |
---|
[3730a07f] | 116 | _Scheduler_priority_SMP_Get_self( context ); |
---|
[99b3505] | 117 | |
---|
[238629f] | 118 | (void) thread; |
---|
| 119 | |
---|
[f39f667a] | 120 | return _Scheduler_priority_Ready_queue_first( |
---|
| 121 | &self->Bit_map, |
---|
| 122 | &self->Ready[ 0 ] |
---|
| 123 | ); |
---|
[99b3505] | 124 | } |
---|
| 125 | |
---|
[238629f] | 126 | void _Scheduler_priority_SMP_Move_from_scheduled_to_ready( |
---|
[3730a07f] | 127 | Scheduler_Context *context, |
---|
[99b3505] | 128 | Thread_Control *scheduled_to_ready |
---|
| 129 | ) |
---|
| 130 | { |
---|
[e1598a6] | 131 | Scheduler_priority_SMP_Context *self = |
---|
[3730a07f] | 132 | _Scheduler_priority_SMP_Get_self( context ); |
---|
[beab7329] | 133 | Scheduler_priority_SMP_Node *node = |
---|
| 134 | _Scheduler_priority_SMP_Node_get( scheduled_to_ready ); |
---|
[494c2e3] | 135 | |
---|
[99b3505] | 136 | _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node ); |
---|
[494c2e3] | 137 | _Scheduler_priority_Ready_queue_enqueue_first( |
---|
| 138 | scheduled_to_ready, |
---|
[beab7329] | 139 | &node->Ready_queue, |
---|
[494c2e3] | 140 | &self->Bit_map |
---|
| 141 | ); |
---|
[99b3505] | 142 | } |
---|
| 143 | |
---|
[238629f] | 144 | void _Scheduler_priority_SMP_Move_from_ready_to_scheduled( |
---|
[3730a07f] | 145 | Scheduler_Context *context, |
---|
[99b3505] | 146 | Thread_Control *ready_to_scheduled |
---|
| 147 | ) |
---|
| 148 | { |
---|
[e1598a6] | 149 | Scheduler_priority_SMP_Context *self = |
---|
[3730a07f] | 150 | _Scheduler_priority_SMP_Get_self( context ); |
---|
[beab7329] | 151 | Scheduler_priority_SMP_Node *node = |
---|
| 152 | _Scheduler_priority_SMP_Node_get( ready_to_scheduled ); |
---|
[494c2e3] | 153 | |
---|
| 154 | _Scheduler_priority_Ready_queue_extract( |
---|
| 155 | ready_to_scheduled, |
---|
[beab7329] | 156 | &node->Ready_queue, |
---|
[494c2e3] | 157 | &self->Bit_map |
---|
| 158 | ); |
---|
[99b3505] | 159 | _Scheduler_simple_Insert_priority_fifo( |
---|
[494c2e3] | 160 | &self->Base.Scheduled, |
---|
[99b3505] | 161 | ready_to_scheduled |
---|
| 162 | ); |
---|
| 163 | } |
---|
| 164 | |
---|
[238629f] | 165 | void _Scheduler_priority_SMP_Insert_ready_lifo( |
---|
[3730a07f] | 166 | Scheduler_Context *context, |
---|
[99b3505] | 167 | Thread_Control *thread |
---|
| 168 | ) |
---|
| 169 | { |
---|
[e1598a6] | 170 | Scheduler_priority_SMP_Context *self = |
---|
[3730a07f] | 171 | _Scheduler_priority_SMP_Get_self( context ); |
---|
[beab7329] | 172 | Scheduler_priority_SMP_Node *node = |
---|
| 173 | _Scheduler_priority_SMP_Node_get( thread ); |
---|
[494c2e3] | 174 | |
---|
[beab7329] | 175 | _Scheduler_priority_Ready_queue_enqueue( |
---|
| 176 | thread, |
---|
| 177 | &node->Ready_queue, |
---|
| 178 | &self->Bit_map |
---|
| 179 | ); |
---|
[99b3505] | 180 | } |
---|
| 181 | |
---|
[238629f] | 182 | void _Scheduler_priority_SMP_Insert_ready_fifo( |
---|
[3730a07f] | 183 | Scheduler_Context *context, |
---|
[99b3505] | 184 | Thread_Control *thread |
---|
| 185 | ) |
---|
| 186 | { |
---|
[e1598a6] | 187 | Scheduler_priority_SMP_Context *self = |
---|
[3730a07f] | 188 | _Scheduler_priority_SMP_Get_self( context ); |
---|
[beab7329] | 189 | Scheduler_priority_SMP_Node *node = |
---|
| 190 | _Scheduler_priority_SMP_Node_get( thread ); |
---|
[494c2e3] | 191 | |
---|
[beab7329] | 192 | _Scheduler_priority_Ready_queue_enqueue_first( |
---|
| 193 | thread, |
---|
| 194 | &node->Ready_queue, |
---|
| 195 | &self->Bit_map |
---|
| 196 | ); |
---|
[99b3505] | 197 | } |
---|
| 198 | |
---|
[238629f] | 199 | void _Scheduler_priority_SMP_Extract_from_ready( |
---|
[3730a07f] | 200 | Scheduler_Context *context, |
---|
[99b3505] | 201 | Thread_Control *thread |
---|
| 202 | ) |
---|
| 203 | { |
---|
[e1598a6] | 204 | Scheduler_priority_SMP_Context *self = |
---|
[3730a07f] | 205 | _Scheduler_priority_SMP_Get_self( context ); |
---|
[beab7329] | 206 | Scheduler_priority_SMP_Node *node = |
---|
| 207 | _Scheduler_priority_SMP_Node_get( thread ); |
---|
[99b3505] | 208 | |
---|
[f39f667a] | 209 | _Scheduler_priority_Ready_queue_extract( |
---|
| 210 | thread, |
---|
| 211 | &node->Ready_queue, |
---|
| 212 | &self->Bit_map |
---|
| 213 | ); |
---|
[99b3505] | 214 | } |
---|
| 215 | |
---|
[24934e36] | 216 | void _Scheduler_priority_SMP_Block( |
---|
[e1598a6] | 217 | const Scheduler_Control *scheduler, |
---|
[24934e36] | 218 | Thread_Control *thread |
---|
| 219 | ) |
---|
[99b3505] | 220 | { |
---|
[f39f667a] | 221 | Scheduler_Context *context = _Scheduler_Get_context( scheduler ); |
---|
[99b3505] | 222 | |
---|
| 223 | _Scheduler_SMP_Block( |
---|
[f39f667a] | 224 | context, |
---|
[99b3505] | 225 | thread, |
---|
[f39f667a] | 226 | _Scheduler_priority_SMP_Extract_from_ready, |
---|
[99b3505] | 227 | _Scheduler_priority_SMP_Get_highest_ready, |
---|
[238629f] | 228 | _Scheduler_priority_SMP_Move_from_ready_to_scheduled, |
---|
| 229 | _Scheduler_SMP_Allocate_processor |
---|
[99b3505] | 230 | ); |
---|
| 231 | } |
---|
| 232 | |
---|
| 233 | static void _Scheduler_priority_SMP_Enqueue_ordered( |
---|
[3730a07f] | 234 | Scheduler_Context *context, |
---|
[99b3505] | 235 | Thread_Control *thread, |
---|
| 236 | Chain_Node_order order, |
---|
| 237 | Scheduler_SMP_Insert insert_ready, |
---|
| 238 | Scheduler_SMP_Insert insert_scheduled |
---|
| 239 | ) |
---|
| 240 | { |
---|
| 241 | _Scheduler_SMP_Enqueue_ordered( |
---|
[3730a07f] | 242 | context, |
---|
[99b3505] | 243 | thread, |
---|
| 244 | order, |
---|
| 245 | insert_ready, |
---|
| 246 | insert_scheduled, |
---|
[238629f] | 247 | _Scheduler_priority_SMP_Move_from_scheduled_to_ready, |
---|
| 248 | _Scheduler_SMP_Get_lowest_scheduled, |
---|
| 249 | _Scheduler_SMP_Allocate_processor |
---|
[99b3505] | 250 | ); |
---|
| 251 | } |
---|
| 252 | |
---|
[f39f667a] | 253 | static void _Scheduler_priority_SMP_Enqueue_lifo( |
---|
| 254 | Scheduler_Context *context, |
---|
[c0bff5e] | 255 | Thread_Control *thread |
---|
[24934e36] | 256 | ) |
---|
[99b3505] | 257 | { |
---|
| 258 | _Scheduler_priority_SMP_Enqueue_ordered( |
---|
[f39f667a] | 259 | context, |
---|
[99b3505] | 260 | thread, |
---|
| 261 | _Scheduler_simple_Insert_priority_lifo_order, |
---|
| 262 | _Scheduler_priority_SMP_Insert_ready_lifo, |
---|
| 263 | _Scheduler_SMP_Insert_scheduled_lifo |
---|
| 264 | ); |
---|
| 265 | } |
---|
| 266 | |
---|
[f39f667a] | 267 | static void _Scheduler_priority_SMP_Enqueue_fifo( |
---|
| 268 | Scheduler_Context *context, |
---|
[c0bff5e] | 269 | Thread_Control *thread |
---|
[24934e36] | 270 | ) |
---|
[99b3505] | 271 | { |
---|
| 272 | _Scheduler_priority_SMP_Enqueue_ordered( |
---|
[f39f667a] | 273 | context, |
---|
[99b3505] | 274 | thread, |
---|
[c0bff5e] | 275 | _Scheduler_simple_Insert_priority_fifo_order, |
---|
| 276 | _Scheduler_priority_SMP_Insert_ready_fifo, |
---|
| 277 | _Scheduler_SMP_Insert_scheduled_fifo |
---|
| 278 | ); |
---|
| 279 | } |
---|
| 280 | |
---|
| 281 | static void _Scheduler_priority_SMP_Enqueue_scheduled_ordered( |
---|
| 282 | Scheduler_Context *context, |
---|
| 283 | Thread_Control *thread, |
---|
| 284 | Chain_Node_order order, |
---|
| 285 | Scheduler_SMP_Insert insert_ready, |
---|
| 286 | Scheduler_SMP_Insert insert_scheduled |
---|
| 287 | ) |
---|
| 288 | { |
---|
| 289 | _Scheduler_SMP_Enqueue_scheduled_ordered( |
---|
| 290 | context, |
---|
| 291 | thread, |
---|
| 292 | order, |
---|
| 293 | _Scheduler_priority_SMP_Get_highest_ready, |
---|
| 294 | insert_ready, |
---|
| 295 | insert_scheduled, |
---|
[238629f] | 296 | _Scheduler_priority_SMP_Move_from_ready_to_scheduled, |
---|
| 297 | _Scheduler_SMP_Allocate_processor |
---|
[c0bff5e] | 298 | ); |
---|
| 299 | } |
---|
| 300 | |
---|
| 301 | static void _Scheduler_priority_SMP_Enqueue_scheduled_lifo( |
---|
| 302 | Scheduler_Context *context, |
---|
| 303 | Thread_Control *thread |
---|
| 304 | ) |
---|
| 305 | { |
---|
| 306 | _Scheduler_priority_SMP_Enqueue_scheduled_ordered( |
---|
| 307 | context, |
---|
| 308 | thread, |
---|
| 309 | _Scheduler_simple_Insert_priority_lifo_order, |
---|
| 310 | _Scheduler_priority_SMP_Insert_ready_lifo, |
---|
| 311 | _Scheduler_SMP_Insert_scheduled_lifo |
---|
| 312 | ); |
---|
| 313 | } |
---|
| 314 | |
---|
| 315 | static void _Scheduler_priority_SMP_Enqueue_scheduled_fifo( |
---|
| 316 | Scheduler_Context *context, |
---|
| 317 | Thread_Control *thread |
---|
| 318 | ) |
---|
| 319 | { |
---|
| 320 | _Scheduler_priority_SMP_Enqueue_scheduled_ordered( |
---|
| 321 | context, |
---|
| 322 | thread, |
---|
[99b3505] | 323 | _Scheduler_simple_Insert_priority_fifo_order, |
---|
| 324 | _Scheduler_priority_SMP_Insert_ready_fifo, |
---|
| 325 | _Scheduler_SMP_Insert_scheduled_fifo |
---|
| 326 | ); |
---|
| 327 | } |
---|
| 328 | |
---|
[f39f667a] | 329 | void _Scheduler_priority_SMP_Unblock( |
---|
[e1598a6] | 330 | const Scheduler_Control *scheduler, |
---|
[24934e36] | 331 | Thread_Control *thread |
---|
| 332 | ) |
---|
[99b3505] | 333 | { |
---|
[f39f667a] | 334 | Scheduler_Context *context = _Scheduler_Get_context( scheduler ); |
---|
[99b3505] | 335 | |
---|
[c0bff5e] | 336 | _Scheduler_SMP_Unblock( |
---|
| 337 | context, |
---|
| 338 | thread, |
---|
| 339 | _Scheduler_priority_SMP_Enqueue_fifo |
---|
| 340 | ); |
---|
[f39f667a] | 341 | } |
---|
| 342 | |
---|
| 343 | void _Scheduler_priority_SMP_Change_priority( |
---|
| 344 | const Scheduler_Control *scheduler, |
---|
| 345 | Thread_Control *thread, |
---|
| 346 | Priority_Control new_priority, |
---|
| 347 | bool prepend_it |
---|
| 348 | ) |
---|
| 349 | { |
---|
| 350 | Scheduler_Context *context = _Scheduler_Get_context( scheduler ); |
---|
| 351 | |
---|
| 352 | _Scheduler_SMP_Change_priority( |
---|
| 353 | context, |
---|
[99b3505] | 354 | thread, |
---|
[f39f667a] | 355 | new_priority, |
---|
| 356 | prepend_it, |
---|
| 357 | _Scheduler_priority_SMP_Extract_from_ready, |
---|
| 358 | _Scheduler_priority_SMP_Do_update, |
---|
| 359 | _Scheduler_priority_SMP_Enqueue_fifo, |
---|
[c0bff5e] | 360 | _Scheduler_priority_SMP_Enqueue_lifo, |
---|
| 361 | _Scheduler_priority_SMP_Enqueue_scheduled_fifo, |
---|
| 362 | _Scheduler_priority_SMP_Enqueue_scheduled_lifo |
---|
[99b3505] | 363 | ); |
---|
| 364 | } |
---|
| 365 | |
---|
[24934e36] | 366 | void _Scheduler_priority_SMP_Yield( |
---|
[e1598a6] | 367 | const Scheduler_Control *scheduler, |
---|
[24934e36] | 368 | Thread_Control *thread |
---|
| 369 | ) |
---|
[99b3505] | 370 | { |
---|
[f39f667a] | 371 | Scheduler_Context *context = _Scheduler_Get_context( scheduler ); |
---|
[99b3505] | 372 | ISR_Level level; |
---|
| 373 | |
---|
| 374 | _ISR_Disable( level ); |
---|
| 375 | |
---|
[f39f667a] | 376 | _Scheduler_SMP_Extract_from_scheduled( thread ); |
---|
[c0bff5e] | 377 | _Scheduler_priority_SMP_Enqueue_scheduled_fifo( context, thread ); |
---|
[99b3505] | 378 | |
---|
| 379 | _ISR_Enable( level ); |
---|
| 380 | } |
---|