Changeset 238629f in rtems
- Timestamp:
- 05/19/14 20:26:55 (9 years ago)
- Branches:
- 4.11, 5, master
- Children:
- 897a0935
- Parents:
- 647859e
- git-author:
- Joel Sherrill <joel.sherrill@…> (05/19/14 20:26:55)
- git-committer:
- Jennifer Averett <jennifer.averett@…> (06/11/14 14:27:06)
- Location:
- cpukit/score
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/score/Makefile.am
r647859e r238629f 115 115 include_rtems_score_HEADERS += include/rtems/score/atomic.h 116 116 include_rtems_score_HEADERS += include/rtems/score/cpustdatomic.h 117 include_rtems_score_HEADERS += include/rtems/score/schedulerprioritysmpimpl.h 117 118 include_rtems_score_HEADERS += include/rtems/score/schedulerpriorityaffinitysmp.h 118 119 include_rtems_score_HEADERS += include/rtems/score/schedulersimplesmp.h -
cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
r647859e r238629f 53 53 _Scheduler_default_Schedule, \ 54 54 _Scheduler_priority_SMP_Yield, \ 55 _Scheduler_priority_ SMP_Block, \56 _Scheduler_priority_ SMP_Unblock, \57 _Scheduler_priority_ SMP_Change_priority, \55 _Scheduler_priority_affinity_SMP_Block, \ 56 _Scheduler_priority_affinity_SMP_Unblock, \ 57 _Scheduler_priority_affinity_SMP_Change_priority, \ 58 58 _Scheduler_priority_affinity_SMP_Node_initialize, \ 59 59 _Scheduler_default_Node_destroy, \ … … 68 68 69 69 /** 70 * @brief Allocates @a the_thread->scheduler.70 * @brief Initializes per thread scheduler information 71 71 * 72 * This routine allocates @a th e_thread->scheduler.72 * This routine allocates @a thread->scheduler. 73 73 * 74 74 * @param[in] scheduler points to the scheduler specific information. 75 * @param[in] th e_thread is the thread the scheduler is allocating75 * @param[in] thread is the thread the scheduler is allocating 76 76 * management memory for. 77 77 */ 78 78 void _Scheduler_priority_affinity_SMP_Node_initialize( 79 79 const Scheduler_Control *scheduler, 80 Thread_Control *th e_thread80 Thread_Control *thread 81 81 ); 82 82 83 83 /** 84 * @brief Get affinity for the priority affinity smp scheduler. 84 * @brief SMP Priority Affinity Scheduler Block Operation 85 * 86 * This method is the block operation for this scheduler. 87 * 88 * @param[in] scheduler is the scheduler instance information 89 * @param[in] thread is the thread to block 90 */ 91 void _Scheduler_priority_affinity_SMP_Block( 92 const Scheduler_Control *scheduler, 93 Thread_Control *thread 94 ); 95 96 /** 97 * @brief SMP Priority Affinity Scheduler Unblock Operation 98 * 99 * This method is the unblock operation for this scheduler. 100 * 101 * @param[in] scheduler is the scheduler instance information 102 * @param[in] thread is the thread to unblock 103 */ 104 void _Scheduler_priority_affinity_SMP_Unblock( 105 const Scheduler_Control *scheduler, 106 Thread_Control *thread 107 ); 108 109 /** 110 * @brief Get affinity for the priority affinity SMP scheduler. 85 111 * 86 112 * @param[in] scheduler The scheduler of the thread. … … 99 125 ); 100 126 127 /** 128 * @brief Change priority for the priority affinity SMP scheduler. 129 * 130 * @param[in] scheduler The scheduler of the thread. 131 * @param[in] thread The associated thread. 132 * @param[in] new_priority The new priority for the thread. 133 * @param[in] prepend_it Append or prepend the thread to its priority FIFO. 134 */ 135 void _Scheduler_priority_affinity_SMP_Change_priority( 136 const Scheduler_Control *scheduler, 137 Thread_Control *the_thread, 138 Priority_Control new_priority, 139 bool prepend_it 140 ); 141 101 142 /** 102 * @brief Set affinity for the priority affinity smpscheduler.143 * @brief Set affinity for the priority affinity SMP scheduler. 103 144 * 104 145 * @param[in] scheduler The scheduler of the thread. … … 107 148 * @param[in] cpuset Affinity new affinity set. 108 149 * 109 * @retval 0 Successful 150 * @retval true if successful 151 * @retval false if unsuccessful 110 152 */ 111 153 bool _Scheduler_priority_affinity_SMP_Set_affinity( … … 113 155 Thread_Control *thread, 114 156 size_t cpusetsize, 115 c pu_set_t*cpuset157 const cpu_set_t *cpuset 116 158 ); 117 159 … … 119 161 * @brief Scheduler node specialization for Deterministic Priority Affinity SMP 120 162 * schedulers. 163 * 164 * This is a per thread structure. 121 165 */ 122 166 typedef struct { … … 138 182 #endif /* __cplusplus */ 139 183 140 #endif /* _RTEMS_SCORE_SCHEDULERPRIORITY SMP_H */184 #endif /* _RTEMS_SCORE_SCHEDULERPRIORITYAFFINITYSMP_H */ -
cpukit/score/include/rtems/score/schedulersmpimpl.h
r647859e r238629f 276 276 277 277 typedef Thread_Control *( *Scheduler_SMP_Get_highest_ready )( 278 Scheduler_Context *context 278 Scheduler_Context *context, 279 Thread_Control *blocking 280 ); 281 282 typedef Thread_Control *( *Scheduler_SMP_Get_lowest_scheduled )( 283 Scheduler_Context *context, 284 Thread_Control *thread, 285 Chain_Node_order order 279 286 ); 280 287 … … 303 310 Scheduler_Context *context, 304 311 Thread_Control *thread_to_enqueue 312 ); 313 314 typedef void ( *Scheduler_SMP_Allocate_processor )( 315 Scheduler_SMP_Context *self, 316 Thread_Control *scheduled, 317 Thread_Control *victim 305 318 ); 306 319 … … 383 396 } 384 397 385 static inlinevoid _Scheduler_SMP_Allocate_processor(398 static void _Scheduler_SMP_Allocate_processor( 386 399 Scheduler_SMP_Context *self, 387 400 Thread_Control *scheduled, … … 421 434 } 422 435 423 static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled( 424 Scheduler_SMP_Context *self 425 ) 426 { 436 static Thread_Control *_Scheduler_SMP_Get_lowest_scheduled( 437 Scheduler_Context *context, 438 Thread_Control *filter, 439 Chain_Node_order order 440 ) 441 { 442 Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context ); 427 443 Thread_Control *lowest_ready = NULL; 428 444 Chain_Control *scheduled = &self->Scheduled; … … 431 447 lowest_ready = (Thread_Control *) _Chain_Last( scheduled ); 432 448 } 449 450 /* 451 * _Scheduler_SMP_Enqueue_ordered() assumes that get_lowest_scheduled 452 * helpers may return NULL. But this method never should. 453 */ 454 _Assert( lowest_ready != NULL ); 433 455 434 456 return lowest_ready; … … 444 466 * @param[in] order The order function. 445 467 * @param[in] insert_ready Function to insert a node into the set of ready 446 * nodes.468 * nodes. 447 469 * @param[in] insert_scheduled Function to insert a node into the set of 448 * scheduled nodes.470 * scheduled nodes. 449 471 * @param[in] move_from_scheduled_to_ready Function to move a node from the set 450 * of scheduled nodes to the set of ready nodes. 472 * of scheduled nodes to the set of ready nodes. 473 * @param[in] get_lowest_scheduled Function to select the thread from the 474 * scheduled nodes to replace. It may not be possible to find one. 475 * @param[in] allocate_processor Function to allocate a processor to a thread 476 * based on the rules of the scheduler. 451 477 */ 452 478 static inline void _Scheduler_SMP_Enqueue_ordered( 453 Scheduler_Context *context, 454 Thread_Control *thread, 455 Chain_Node_order order, 456 Scheduler_SMP_Insert insert_ready, 457 Scheduler_SMP_Insert insert_scheduled, 458 Scheduler_SMP_Move move_from_scheduled_to_ready 479 Scheduler_Context *context, 480 Thread_Control *thread, 481 Chain_Node_order order, 482 Scheduler_SMP_Insert insert_ready, 483 Scheduler_SMP_Insert insert_scheduled, 484 Scheduler_SMP_Move move_from_scheduled_to_ready, 485 Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled, 486 Scheduler_SMP_Allocate_processor allocate_processor 459 487 ) 460 488 { 461 489 Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context ); 462 490 Thread_Control *lowest_scheduled = 463 _Scheduler_SMP_Get_lowest_scheduled( self ); 464 465 _Assert( lowest_scheduled != NULL ); 466 467 if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) { 491 ( *get_lowest_scheduled )( context, thread, order ); 492 493 /* 494 * get_lowest_scheduled can return a NULL if no scheduled threads 495 * should be removed from their processor based on the selection 496 * criteria. For example, this can occur when the affinity of the 497 * thread being enqueued schedules it against higher priority threads. 498 * A low priority thread with affinity can only consider the threads 499 * which are on the cores if has affinity for. 500 * 501 * The get_lowest_scheduled helper should assert on not returning NULL 502 * if that is not possible for that scheduler. 503 */ 504 505 if ( lowest_scheduled && 506 ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) { 468 507 Scheduler_SMP_Node *lowest_scheduled_node = 469 508 _Scheduler_SMP_Node_get( lowest_scheduled ); … … 473 512 SCHEDULER_SMP_NODE_READY 474 513 ); 475 _Scheduler_SMP_Allocate_processor( self, thread, lowest_scheduled );514 ( *allocate_processor )( self, thread, lowest_scheduled ); 476 515 ( *insert_scheduled )( &self->Base, thread ); 477 516 ( *move_from_scheduled_to_ready )( &self->Base, lowest_scheduled ); … … 490 529 * @param[in] get_highest_ready Function to get the highest ready node. 491 530 * @param[in] insert_ready Function to insert a node into the set of ready 492 * nodes.531 * nodes. 493 532 * @param[in] insert_scheduled Function to insert a node into the set of 494 * scheduled nodes.533 * scheduled nodes. 495 534 * @param[in] move_from_ready_to_scheduled Function to move a node from the set 496 * of ready nodes to the set of scheduled nodes. 535 * of ready nodes to the set of scheduled nodes. 536 * @param[in] allocate_processor Function to allocate a processor to a thread 537 * based on the rules of the scheduler. 497 538 */ 498 539 static inline void _Scheduler_SMP_Enqueue_scheduled_ordered( 499 540 Scheduler_Context *context, 500 Thread_Control *thread, 501 Chain_Node_order order, 502 Scheduler_SMP_Get_highest_ready get_highest_ready, 503 Scheduler_SMP_Insert insert_ready, 504 Scheduler_SMP_Insert insert_scheduled, 505 Scheduler_SMP_Move move_from_ready_to_scheduled 541 Thread_Control *thread, 542 Chain_Node_order order, 543 Scheduler_SMP_Get_highest_ready get_highest_ready, 544 Scheduler_SMP_Insert insert_ready, 545 Scheduler_SMP_Insert insert_scheduled, 546 Scheduler_SMP_Move move_from_ready_to_scheduled, 547 Scheduler_SMP_Allocate_processor allocate_processor 506 548 ) 507 549 { 508 550 Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context ); 509 551 Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread ); 510 Thread_Control *highest_ready = ( *get_highest_ready )( &self->Base ); 552 Thread_Control *highest_ready = 553 ( *get_highest_ready )( &self->Base, thread ); 511 554 512 555 _Assert( highest_ready != NULL ); … … 520 563 } else { 521 564 _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY ); 522 _Scheduler_SMP_Allocate_processor( self, highest_ready, thread );565 ( *allocate_processor) ( self, highest_ready, thread ); 523 566 ( *insert_ready )( &self->Base, thread ); 524 567 ( *move_from_ready_to_scheduled )( &self->Base, highest_ready ); … … 537 580 Thread_Control *victim, 538 581 Scheduler_SMP_Get_highest_ready get_highest_ready, 539 Scheduler_SMP_Move move_from_ready_to_scheduled 582 Scheduler_SMP_Move move_from_ready_to_scheduled, 583 Scheduler_SMP_Allocate_processor allocate_processor 540 584 ) 541 585 { 542 586 Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context ); 543 Thread_Control *highest_ready = ( *get_highest_ready )( &self->Base ); 544 545 _Scheduler_SMP_Allocate_processor( self, highest_ready, victim ); 587 Thread_Control *highest_ready = 588 ( *get_highest_ready )( &self->Base, victim ); 589 590 ( *allocate_processor )( self, highest_ready, victim ); 546 591 547 592 ( *move_from_ready_to_scheduled )( &self->Base, highest_ready ); … … 564 609 Scheduler_SMP_Extract extract_from_ready, 565 610 Scheduler_SMP_Get_highest_ready get_highest_ready, 566 Scheduler_SMP_Move move_from_ready_to_scheduled 611 Scheduler_SMP_Move move_from_ready_to_scheduled, 612 Scheduler_SMP_Allocate_processor allocate_processor 567 613 ) 568 614 { … … 579 625 thread, 580 626 get_highest_ready, 581 move_from_ready_to_scheduled 627 move_from_ready_to_scheduled, 628 allocate_processor 582 629 ); 583 630 } else { -
cpukit/score/preinstall.am
r647859e r238629f 407 407 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpustdatomic.h 408 408 409 $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmpimpl.h: include/rtems/score/schedulerprioritysmpimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) 410 $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmpimpl.h 411 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmpimpl.h 412 409 413 $(PROJECT_INCLUDE)/rtems/score/schedulerpriorityaffinitysmp.h: include/rtems/score/schedulerpriorityaffinitysmp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) 410 414 $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerpriorityaffinitysmp.h -
cpukit/score/src/schedulerpriorityaffinitysmp.c
r647859e r238629f 23 23 #include <rtems/score/schedulerpriorityimpl.h> 24 24 #include <rtems/score/schedulersmpimpl.h> 25 #include <rtems/score/schedulerprioritysmpimpl.h> 25 26 #include <rtems/score/wkspace.h> 26 27 #include <rtems/score/cpusetimpl.h> 27 28 29 #include <rtems/score/priority.h> 30 31 /* 32 * The following methods which initially were static in schedulerprioritysmp.c 33 * are shared with this scheduler. They are now public so they can be shared. 34 * 35 * + _Scheduler_priority_SMP_Get_self 36 * + _Scheduler_priority_SMP_Insert_ready_fifo 37 * + _Scheduler_priority_SMP_Insert_ready_lifo 38 * + _Scheduler_priority_SMP_Node_get 39 * + _Scheduler_priority_SMP_Move_from_scheduled_to_ready 40 * + _Scheduler_priority_SMP_Move_from_ready_to_scheduled 41 * + _Scheduler_priority_SMP_Extract_from_ready 42 * + _Scheduler_priority_SMP_Do_update 43 */ 44 45 /* 46 * This method returns the scheduler node for the specified thread 47 * as a scheduler specific type. 48 */ 28 49 static Scheduler_priority_affinity_SMP_Node * 29 _Scheduler_priority_affinity_Node_get( Thread_Control *thread ) 30 { 31 return ( Scheduler_priority_affinity_SMP_Node * ) 32 _Scheduler_Node_get( thread ); 33 } 34 50 _Scheduler_priority_affinity_SMP_Node_get( 51 Thread_Control *thread 52 ) 53 { 54 return (Scheduler_priority_affinity_SMP_Node *) _Scheduler_Node_get( thread ); 55 } 56 57 /* 58 * This method initializes the scheduler control information for 59 * this scheduler instance. 60 */ 35 61 void _Scheduler_priority_affinity_SMP_Node_initialize( 36 62 const Scheduler_Control *scheduler, 37 Thread_Control *the_thread 38 ) 39 { 63 Thread_Control *thread 64 ) 65 { 66 Scheduler_SMP_Node *smp_node = _Scheduler_SMP_Node_get( thread ); 67 40 68 Scheduler_priority_affinity_SMP_Node *node = 41 _Scheduler_priority_affinity_Node_get( the_thread ); 42 43 _Scheduler_SMP_Node_initialize( &node->Base.Base ); 44 45 node->Affinity = *_CPU_set_Default(); 69 _Scheduler_priority_affinity_SMP_Node_get( thread ); 70 71 (scheduler); 72 73 /* 74 * All we add is affinity information to the basic SMP node. 75 */ 76 _Scheduler_SMP_Node_initialize( smp_node ); 77 78 node->Affinity = *_CPU_set_Default(); 46 79 node->Affinity.set = &node->Affinity.preallocated; 47 80 } 48 81 82 /* 83 * This method is slightly different from _Scheduler_SMP_Allocate_processor() 84 * in that it does what it is asked to do. _Scheduler_SMP_Allocate_processor() 85 * attempts to prevent migrations but does not take into account affinity 86 */ 87 static inline void _Scheduler_SMP_Allocate_processor_exact( 88 Scheduler_SMP_Context *self, 89 Thread_Control *scheduled, 90 Thread_Control *victim 91 ) 92 { 93 Scheduler_SMP_Node *scheduled_node = _Scheduler_SMP_Node_get( scheduled ); 94 Per_CPU_Control *cpu_of_scheduled = _Thread_Get_CPU( scheduled ); 95 Per_CPU_Control *cpu_of_victim = _Thread_Get_CPU( victim ); 96 Per_CPU_Control *cpu_self = _Per_CPU_Get(); 97 98 _Scheduler_SMP_Node_change_state( 99 scheduled_node, 100 SCHEDULER_SMP_NODE_SCHEDULED 101 ); 102 103 _Thread_Set_CPU( scheduled, cpu_of_victim ); 104 _Scheduler_SMP_Update_heir( cpu_self, cpu_of_victim, scheduled ); 105 } 106 107 /* 108 * This method is unique to this scheduler because it takes into 109 * account affinity as it determines the highest ready thread. 110 * Since this is used to pick a new thread to replace the victim, 111 * the highest ready thread must have affinity such that it can 112 * be executed on the victim's processor. 113 */ 114 static Thread_Control *_Scheduler_priority_affinity_SMP_Get_highest_ready( 115 Scheduler_Context *context, 116 Thread_Control *victim 117 ) 118 { 119 Scheduler_priority_SMP_Context *self = 120 _Scheduler_priority_SMP_Get_self( context ); 121 Priority_Control index; 122 Thread_Control *highest = NULL; 123 int victim_cpu; 124 125 /* 126 * This is done when we need to check if reevaluations are needed. 127 */ 128 if ( victim == NULL ) { 129 return _Scheduler_priority_Ready_queue_first( 130 &self->Bit_map, 131 &self->Ready[ 0 ] 132 ); 133 } 134 135 victim_cpu = _Per_CPU_Get_index( _Thread_Get_CPU( victim ) ); 136 137 /** 138 * @todo The deterministic priority scheduler structure is optimized 139 * for insertion, extraction, and finding the highest priority 140 * thread. Scanning the list of ready threads is not a purpose 141 * for which it was optimized. There are optimizations to be 142 * made in this loop. 143 * 144 * + by checking the major bit, we could potentially skip entire 145 * groups of 16. 146 * 147 * When using this scheduler as implemented, the application's 148 * choice of numeric priorities and their distribution can have 149 * an impact on performance. 150 */ 151 for ( index = _Priority_bit_map_Get_highest( &self->Bit_map ) ; 152 index <= PRIORITY_MAXIMUM; 153 index++ ) 154 { 155 Chain_Control *chain = &self->Ready[index]; 156 Chain_Node *chain_node; 157 for ( chain_node = _Chain_First( chain ); 158 chain_node != _Chain_Immutable_tail( chain ) ; 159 chain_node = _Chain_Next( chain_node ) ) 160 { 161 Thread_Control *thread; 162 Scheduler_priority_affinity_SMP_Node *node; 163 164 thread = (Thread_Control *) chain_node; 165 node = _Scheduler_priority_affinity_SMP_Node_get( thread ); 166 167 /* 168 * Can this thread run on this CPU? 169 */ 170 if ( CPU_ISSET( victim_cpu, node->Affinity.set ) ) { 171 highest = thread; 172 break; 173 } 174 } 175 if ( highest ) 176 break; 177 } 178 179 _Assert( highest != NULL ); 180 181 return highest; 182 } 183 184 /* 185 * This method is very similar to _Scheduler_priority_affinity_SMP_Block 186 * but has the difference that is invokes this scheduler's 187 * get_highest_ready() support method. 188 */ 189 void _Scheduler_priority_affinity_SMP_Block( 190 const Scheduler_Control *scheduler, 191 Thread_Control *thread 192 ) 193 { 194 Scheduler_Context *context = _Scheduler_Get_context( scheduler ); 195 196 _Scheduler_SMP_Block( 197 context, 198 thread, 199 _Scheduler_priority_SMP_Extract_from_ready, 200 _Scheduler_priority_affinity_SMP_Get_highest_ready, 201 _Scheduler_priority_SMP_Move_from_ready_to_scheduled, 202 _Scheduler_SMP_Allocate_processor_exact 203 ); 204 205 /* 206 * Since this removed a single thread from the scheduled set 207 * and selected the most appropriate thread from the ready 208 * set to replace it, there should be no need for thread 209 * migrations. 210 */ 211 } 212 213 /* 214 * This method is unique to this scheduler because it must take into 215 * account affinity as it searches for the lowest priority scheduled 216 * thread. It ignores those which cannot be replaced by the filter 217 * thread because the potential victim thread does not have affinity 218 * for that processor. 219 */ 220 static Thread_Control *_Scheduler_priority_affinity_SMP_Get_lowest_scheduled( 221 Scheduler_Context *context, 222 Thread_Control *filter, 223 Chain_Node_order order 224 ) 225 { 226 Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context ); 227 Thread_Control *lowest_scheduled = NULL; 228 Thread_Control *thread = NULL; 229 Chain_Control *scheduled = &self->Scheduled; 230 Scheduler_priority_affinity_SMP_Node *node = 231 _Scheduler_priority_affinity_SMP_Node_get( filter ); 232 233 for ( thread = (Thread_Control *) _Chain_Last( scheduled ); 234 (Chain_Node *) thread != _Chain_Immutable_head( scheduled ) ; 235 thread = (Thread_Control *) _Chain_Previous( &thread->Object.Node ) ) { 236 int cpu_index; 237 238 /* 239 * If we didn't find a thread which is of equal or lower importance 240 * than filter thread is, then we can't schedule the filter thread 241 * to execute. 242 */ 243 if ( (*order)(&thread->Object.Node, &filter->Object.Node) ) 244 break; 245 246 /* cpu_index is the processor number thread is executing on */ 247 cpu_index = _Per_CPU_Get_index( _Thread_Get_CPU( thread ) ); 248 249 if ( CPU_ISSET( cpu_index, node->Affinity.set ) ) { 250 lowest_scheduled = thread; 251 break; 252 } 253 254 } 255 256 return lowest_scheduled; 257 } 258 259 /* 260 * This method is unique to this scheduler because it must pass 261 * _Scheduler_priority_affinity_SMP_Get_lowest_scheduled into 262 * _Scheduler_SMP_Enqueue_ordered. 263 */ 264 static void _Scheduler_priority_affinity_SMP_Enqueue_fifo( 265 Scheduler_Context *context, 266 Thread_Control *thread 267 ) 268 { 269 _Scheduler_SMP_Enqueue_ordered( 270 context, 271 thread, 272 _Scheduler_simple_Insert_priority_fifo_order, 273 _Scheduler_priority_SMP_Insert_ready_fifo, 274 _Scheduler_SMP_Insert_scheduled_fifo, 275 _Scheduler_priority_SMP_Move_from_scheduled_to_ready, 276 _Scheduler_priority_affinity_SMP_Get_lowest_scheduled, 277 _Scheduler_SMP_Allocate_processor_exact 278 ); 279 } 280 281 /* 282 * This method is invoked at the end of certain scheduling operations 283 * to ensure that the highest priority ready thread cannot be scheduled 284 * to execute. When we schedule with affinity, there is the possibility 285 * that we need to migrate a thread to another core to ensure that the 286 * highest priority ready threads are in fact scheduled. 287 */ 288 static void _Scheduler_priority_affinity_SMP_Check_for_migrations( 289 Scheduler_Context *context 290 ) 291 { 292 Thread_Control *lowest_scheduled; 293 Thread_Control *highest_ready; 294 Scheduler_SMP_Node *lowest_scheduled_node; 295 Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context ); 296 297 while (1) { 298 highest_ready = 299 _Scheduler_priority_affinity_SMP_Get_highest_ready( context, NULL ); 300 lowest_scheduled = _Scheduler_priority_affinity_SMP_Get_lowest_scheduled( 301 context, 302 highest_ready, 303 _Scheduler_simple_Insert_priority_lifo_order 304 ); 305 306 /* 307 * If we can't find a thread to displace from the scheduled set, 308 * then we have placed all the highest priority threads possible 309 * in the scheduled set. 310 * 311 * We found the absolute highest priority thread without 312 * considering affinity. But now we have to consider that thread's 313 * affinity as we look to place it. 314 */ 315 if ( lowest_scheduled == NULL ) 316 break; 317 318 /* 319 * But if we found a thread which is lower priority than one 320 * in the ready set, then we need to swap them out. 321 */ 322 lowest_scheduled_node = _Scheduler_SMP_Node_get( lowest_scheduled ); 323 324 _Scheduler_SMP_Node_change_state( 325 lowest_scheduled_node, 326 SCHEDULER_SMP_NODE_READY 327 ); 328 329 _Scheduler_SMP_Allocate_processor_exact( 330 self, 331 highest_ready, 332 lowest_scheduled 333 ); 334 335 _Scheduler_priority_SMP_Move_from_ready_to_scheduled( 336 context, 337 highest_ready 338 ); 339 340 _Scheduler_priority_SMP_Move_from_scheduled_to_ready( 341 &self->Base, 342 lowest_scheduled 343 ); 344 } 345 } 346 347 /* 348 * This is the public scheduler specific Unblock operation. 349 */ 350 void _Scheduler_priority_affinity_SMP_Unblock( 351 const Scheduler_Control *scheduler, 352 Thread_Control *thread 353 ) 354 { 355 Scheduler_Context *context = _Scheduler_Get_context( scheduler ); 356 357 _Scheduler_SMP_Unblock( 358 context, 359 thread, 360 _Scheduler_priority_affinity_SMP_Enqueue_fifo 361 ); 362 363 /* 364 * Perform any thread migrations that are needed due to these changes. 365 */ 366 _Scheduler_priority_affinity_SMP_Check_for_migrations( context ); 367 } 368 369 /* 370 * This is unique to this scheduler because it passes scheduler specific 371 * get_lowest_scheduled helper to _Scheduler_SMP_Enqueue_ordered. 372 */ 373 static void _Scheduler_priority_affinity_SMP_Enqueue_ordered( 374 Scheduler_Context *context, 375 Thread_Control *thread, 376 Chain_Node_order order, 377 Scheduler_SMP_Insert insert_ready, 378 Scheduler_SMP_Insert insert_scheduled 379 ) 380 { 381 _Scheduler_SMP_Enqueue_ordered( 382 context, 383 thread, 384 order, 385 insert_ready, 386 insert_scheduled, 387 _Scheduler_priority_SMP_Move_from_scheduled_to_ready, 388 _Scheduler_priority_affinity_SMP_Get_lowest_scheduled, 389 _Scheduler_SMP_Allocate_processor_exact 390 ); 391 } 392 393 /* 394 * This is unique to this scheduler because it is on the path 395 * to _Scheduler_priority_affinity_SMP_Enqueue_ordered() which 396 * invokes a scheduler unique get_lowest_scheduled helper. 397 */ 398 static void _Scheduler_priority_affinity_SMP_Enqueue_lifo( 399 Scheduler_Context *context, 400 Thread_Control *thread 401 ) 402 { 403 _Scheduler_priority_affinity_SMP_Enqueue_ordered( 404 context, 405 thread, 406 _Scheduler_simple_Insert_priority_lifo_order, 407 _Scheduler_priority_SMP_Insert_ready_lifo, 408 _Scheduler_SMP_Insert_scheduled_lifo 409 ); 410 } 411 412 /* 413 * This method is unique to this scheduler because it must 414 * invoke _Scheduler_SMP_Enqueue_scheduled_ordered() with 415 * this scheduler's get_highest_ready() helper. 416 */ 417 static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( 418 Scheduler_Context *context, 419 Thread_Control *thread, 420 Chain_Node_order order, 421 Scheduler_SMP_Insert insert_ready, 422 Scheduler_SMP_Insert insert_scheduled 423 ) 424 { 425 _Scheduler_SMP_Enqueue_scheduled_ordered( 426 context, 427 thread, 428 order, 429 _Scheduler_priority_affinity_SMP_Get_highest_ready, 430 insert_ready, 431 insert_scheduled, 432 _Scheduler_priority_SMP_Move_from_ready_to_scheduled, 433 _Scheduler_SMP_Allocate_processor_exact 434 ); 435 } 436 437 /* 438 * This is unique to this scheduler because it is on the path 439 * to _Scheduler_priority_affinity_SMP_Enqueue_scheduled__ordered() which 440 * invokes a scheduler unique get_lowest_scheduled helper. 441 */ 442 static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo( 443 Scheduler_Context *context, 444 Thread_Control *thread 445 ) 446 { 447 _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( 448 context, 449 thread, 450 _Scheduler_simple_Insert_priority_lifo_order, 451 _Scheduler_priority_SMP_Insert_ready_lifo, 452 _Scheduler_SMP_Insert_scheduled_lifo 453 ); 454 } 455 456 /* 457 * This is unique to this scheduler because it is on the path 458 * to _Scheduler_priority_affinity_SMP_Enqueue_scheduled__ordered() which 459 * invokes a scheduler unique get_lowest_scheduled helper. 460 */ 461 static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo( 462 Scheduler_Context *context, 463 Thread_Control *thread 464 ) 465 { 466 _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( 467 context, 468 thread, 469 _Scheduler_simple_Insert_priority_fifo_order, 470 _Scheduler_priority_SMP_Insert_ready_fifo, 471 _Scheduler_SMP_Insert_scheduled_fifo 472 ); 473 } 474 475 /* 476 * This is the public scheduler specific Change Priority operation. 477 */ 478 void _Scheduler_priority_affinity_SMP_Change_priority( 479 const Scheduler_Control *scheduler, 480 Thread_Control *thread, 481 Priority_Control new_priority, 482 bool prepend_it 483 ) 484 { 485 Scheduler_Context *context = _Scheduler_Get_context( scheduler ); 486 487 _Scheduler_SMP_Change_priority( 488 context, 489 thread, 490 new_priority, 491 prepend_it, 492 _Scheduler_priority_SMP_Extract_from_ready, 493 _Scheduler_priority_SMP_Do_update, 494 _Scheduler_priority_affinity_SMP_Enqueue_fifo, 495 _Scheduler_priority_affinity_SMP_Enqueue_lifo, 496 _Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo, 497 _Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo 498 ); 499 500 /* 501 * Perform any thread migrations that are needed due to these changes. 502 */ 503 _Scheduler_priority_affinity_SMP_Check_for_migrations( context ); 504 } 505 506 /* 507 * This is the public scheduler specific Change Priority operation. 508 */ 49 509 bool _Scheduler_priority_affinity_SMP_Get_affinity( 50 510 const Scheduler_Control *scheduler, … … 55 515 { 56 516 Scheduler_priority_affinity_SMP_Node *node = 57 _Scheduler_priority_affinity_ Node_get(thread);517 _Scheduler_priority_affinity_SMP_Node_get(thread); 58 518 59 519 (void) scheduler; … … 64 524 65 525 CPU_COPY( cpuset, node->Affinity.set ); 66 return true; 526 return true; 67 527 } 68 528 … … 71 531 Thread_Control *thread, 72 532 size_t cpusetsize, 73 c pu_set_t*cpuset533 const cpu_set_t *cpuset 74 534 ) 75 535 { 76 536 Scheduler_priority_affinity_SMP_Node *node = 77 _Scheduler_priority_affinity_ Node_get(thread);537 _Scheduler_priority_affinity_SMP_Node_get(thread); 78 538 79 539 (void) scheduler; 80 81 if ( ! _CPU_set_Is_valid( cpuset, cpusetsize ) ) { 540 541 /* 542 * Validate that the cpset meets basic requirements. 543 */ 544 if ( !_CPU_set_Is_valid( cpuset, cpusetsize ) ) { 82 545 return false; 83 546 } 84 547 85 CPU_COPY( node->Affinity.set, cpuset ); 86 548 /* 549 * The old and new set are the same, there is no point in 550 * doing anything. 551 */ 552 if ( CPU_EQUAL_S( cpusetsize, cpuset, node->Affinity.set ) ) 553 return true; 554 555 _Thread_Set_state( thread, STATES_MIGRATING ); 556 CPU_COPY( node->Affinity.set, cpuset ); 557 _Thread_Clear_state( thread, STATES_MIGRATING ); 558 87 559 return true; 88 560 } -
cpukit/score/src/schedulerprioritysmp.c
r647859e r238629f 27 27 #include <rtems/score/schedulerprioritysmp.h> 28 28 #include <rtems/score/schedulerpriorityimpl.h> 29 #include <rtems/score/schedulerprioritysmpimpl.h> 29 30 #include <rtems/score/schedulersmpimpl.h> 30 31 … … 35 36 } 36 37 37 static Scheduler_priority_SMP_Context * 38 _Scheduler_priority_SMP_Get_self( Scheduler_Context *context ) 38 Scheduler_priority_SMP_Context *_Scheduler_priority_SMP_Get_self( 39 Scheduler_Context *context 40 ) 39 41 { 40 42 return (Scheduler_priority_SMP_Context *) context; 41 43 } 42 44 43 staticScheduler_priority_SMP_Node *_Scheduler_priority_SMP_Node_get(45 Scheduler_priority_SMP_Node *_Scheduler_priority_SMP_Node_get( 44 46 Thread_Control *thread 45 47 ) … … 75 77 } 76 78 77 staticvoid _Scheduler_priority_SMP_Do_update(79 void _Scheduler_priority_SMP_Do_update( 78 80 Scheduler_Context *context, 79 81 Scheduler_Node *base_node, … … 107 109 108 110 static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready( 109 Scheduler_Context *context 110 ) 111 { 112 Scheduler_priority_SMP_Context *self = 113 _Scheduler_priority_SMP_Get_self( context ); 111 Scheduler_Context *context, 112 Thread_Control *thread 113 ) 114 { 115 Scheduler_priority_SMP_Context *self = 116 _Scheduler_priority_SMP_Get_self( context ); 117 118 (void) thread; 114 119 115 120 return _Scheduler_priority_Ready_queue_first( … … 119 124 } 120 125 121 staticvoid _Scheduler_priority_SMP_Move_from_scheduled_to_ready(126 void _Scheduler_priority_SMP_Move_from_scheduled_to_ready( 122 127 Scheduler_Context *context, 123 128 Thread_Control *scheduled_to_ready … … 137 142 } 138 143 139 staticvoid _Scheduler_priority_SMP_Move_from_ready_to_scheduled(144 void _Scheduler_priority_SMP_Move_from_ready_to_scheduled( 140 145 Scheduler_Context *context, 141 146 Thread_Control *ready_to_scheduled … … 158 163 } 159 164 160 staticvoid _Scheduler_priority_SMP_Insert_ready_lifo(165 void _Scheduler_priority_SMP_Insert_ready_lifo( 161 166 Scheduler_Context *context, 162 167 Thread_Control *thread … … 175 180 } 176 181 177 staticvoid _Scheduler_priority_SMP_Insert_ready_fifo(182 void _Scheduler_priority_SMP_Insert_ready_fifo( 178 183 Scheduler_Context *context, 179 184 Thread_Control *thread … … 192 197 } 193 198 194 staticvoid _Scheduler_priority_SMP_Extract_from_ready(199 void _Scheduler_priority_SMP_Extract_from_ready( 195 200 Scheduler_Context *context, 196 201 Thread_Control *thread … … 221 226 _Scheduler_priority_SMP_Extract_from_ready, 222 227 _Scheduler_priority_SMP_Get_highest_ready, 223 _Scheduler_priority_SMP_Move_from_ready_to_scheduled 228 _Scheduler_priority_SMP_Move_from_ready_to_scheduled, 229 _Scheduler_SMP_Allocate_processor 224 230 ); 225 231 } … … 239 245 insert_ready, 240 246 insert_scheduled, 241 _Scheduler_priority_SMP_Move_from_scheduled_to_ready 247 _Scheduler_priority_SMP_Move_from_scheduled_to_ready, 248 _Scheduler_SMP_Get_lowest_scheduled, 249 _Scheduler_SMP_Allocate_processor 242 250 ); 243 251 } … … 286 294 insert_ready, 287 295 insert_scheduled, 288 _Scheduler_priority_SMP_Move_from_ready_to_scheduled 296 _Scheduler_priority_SMP_Move_from_ready_to_scheduled, 297 _Scheduler_SMP_Allocate_processor 289 298 ); 290 299 } -
cpukit/score/src/schedulersimplesmp.c
r647859e r238629f 65 65 66 66 static Thread_Control *_Scheduler_simple_SMP_Get_highest_ready( 67 Scheduler_Context *context 68 ) 69 { 70 Scheduler_simple_SMP_Context *self = 71 _Scheduler_simple_SMP_Get_self( context ); 67 Scheduler_Context *context, 68 Thread_Control *thread 69 ) 70 { 71 Scheduler_simple_SMP_Context *self = 72 _Scheduler_simple_SMP_Get_self( context ); 73 74 (void) thread; 72 75 73 76 return (Thread_Control *) _Chain_First( &self->Ready ); … … 156 159 _Scheduler_simple_SMP_Extract_from_ready, 157 160 _Scheduler_simple_SMP_Get_highest_ready, 158 _Scheduler_simple_SMP_Move_from_ready_to_scheduled 161 _Scheduler_simple_SMP_Move_from_ready_to_scheduled, 162 _Scheduler_SMP_Allocate_processor 159 163 ); 160 164 } … … 174 178 insert_ready, 175 179 insert_scheduled, 176 _Scheduler_simple_SMP_Move_from_scheduled_to_ready 180 _Scheduler_simple_SMP_Move_from_scheduled_to_ready, 181 _Scheduler_SMP_Get_lowest_scheduled, 182 _Scheduler_SMP_Allocate_processor 177 183 ); 178 184 } … … 221 227 insert_ready, 222 228 insert_scheduled, 223 _Scheduler_simple_SMP_Move_from_ready_to_scheduled 229 _Scheduler_simple_SMP_Move_from_ready_to_scheduled, 230 _Scheduler_SMP_Allocate_processor 224 231 ); 225 232 }
Note: See TracChangeset
for help on using the changeset viewer.