37#ifndef _RTEMS_SCORE_SCHEDULERSMPIMPL_H
38#define _RTEMS_SCORE_SCHEDULERSMPIMPL_H
292typedef bool ( *Scheduler_SMP_Has_ready )(
310typedef void ( *Scheduler_SMP_Extract )(
315typedef void ( *Scheduler_SMP_Insert )(
321typedef void ( *Scheduler_SMP_Move )(
326typedef bool ( *Scheduler_SMP_Ask_for_help )(
332typedef void ( *Scheduler_SMP_Update )(
338typedef void ( *Scheduler_SMP_Set_affinity )(
344typedef bool ( *Scheduler_SMP_Enqueue )(
350typedef void ( *Scheduler_SMP_Enqueue_scheduled )(
356typedef void ( *Scheduler_SMP_Allocate_processor )(
362typedef void ( *Scheduler_SMP_Register_idle )(
375static inline void _Scheduler_SMP_Do_nothing_register_idle(
398static inline bool _Scheduler_SMP_Priority_less_equal(
411 return *priority_to_insert <= node_next->
priority;
433static inline void _Scheduler_SMP_Initialize(
437 _Chain_Initialize_empty( &self->
Scheduled );
518static inline void _Scheduler_SMP_Node_initialize(
525 _Scheduler_Node_do_initialize( scheduler, &node->Base, thread, priority );
527 node->priority = priority;
536static inline void _Scheduler_SMP_Node_update_priority(
541 node->priority = new_priority;
550static inline void _Scheduler_SMP_Node_change_state(
557 the_node = _Scheduler_SMP_Node_downcast( node );
558 the_node->state = new_state;
570static inline bool _Scheduler_SMP_Is_processor_owned_by_us(
575 return cpu->Scheduler.context == context;
600static inline void _Scheduler_SMP_Cancel_ask_for_help(
Thread_Control *thread )
605 cpu = thread->
Scheduler.ask_for_help_cpu;
626static inline void _Scheduler_SMP_Request_ask_for_help(
Thread_Control *thread )
631 cpu_self = _Per_CPU_Get();
634 thread->
Scheduler.ask_for_help_cpu = cpu_self;
637 _Per_CPU_Acquire( cpu_self, &lock_context );
638 _Chain_Append_unprotected(
639 &cpu_self->Threads_in_need_for_help,
642 _Per_CPU_Release( cpu_self, &lock_context );
650 SCHEDULER_SMP_DO_SCHEDULE,
651 SCHEDULER_SMP_DO_NOT_SCHEDULE
682 Scheduler_Get_idle_node get_idle_node,
688 Thread_Scheduler_state owner_state;
689 int owner_sticky_level;
691 owner = _Scheduler_Node_get_owner( node );
692 _Assert( _Scheduler_Node_get_idle( node ) == NULL );
694 _Thread_Scheduler_acquire_critical( owner, &lock_context );
696 owner_sticky_level = node->sticky_level;
699 _Scheduler_SMP_Cancel_ask_for_help( owner );
700 _Scheduler_Thread_change_state( owner, THREAD_SCHEDULER_SCHEDULED );
701 _Thread_Scheduler_release_critical( owner, &lock_context );
702 return SCHEDULER_SMP_DO_SCHEDULE;
705 _Thread_Scheduler_release_critical( owner, &lock_context );
708 ( owner_state == THREAD_SCHEDULER_SCHEDULED && owner_sticky_level <= 1 ) ||
709 owner_sticky_level == 0
713 return SCHEDULER_SMP_DO_NOT_SCHEDULE;
716 (void) _Scheduler_Use_idle_thread( node, get_idle_node, arg );
718 return SCHEDULER_SMP_DO_SCHEDULE;
732static inline void _Scheduler_SMP_Allocate_processor_lazy(
738 Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
744 if ( cpu == scheduled_cpu ) {
745 _Thread_Set_CPU( scheduled_thread, cpu );
746 _Thread_Dispatch_update_heir( cpu_self, cpu, scheduled_thread );
752 _Thread_Is_executing_on_a_processor( scheduled_thread ) &&
753 _Scheduler_SMP_Is_processor_owned_by_us( context, scheduled_cpu )
756 _Thread_Dispatch_update_heir( cpu_self, scheduled_cpu, scheduled_thread );
757 _Thread_Set_CPU( heir, cpu );
758 _Thread_Dispatch_update_heir( cpu_self, cpu, heir );
763 _Thread_Set_CPU( scheduled_thread, cpu );
764 _Thread_Dispatch_update_heir( cpu_self, cpu, scheduled_thread );
781static inline void _Scheduler_SMP_Allocate_processor_exact(
787 Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
792 _Thread_Set_CPU( scheduled_thread, cpu );
793 _Thread_Dispatch_update_heir( cpu_self, cpu, scheduled_thread );
808static inline void _Scheduler_SMP_Allocate_processor(
812 Scheduler_SMP_Allocate_processor allocate_processor
816 ( *allocate_processor )( context, scheduled, cpu );
834static inline void _Scheduler_SMP_Preempt(
839 Scheduler_SMP_Allocate_processor allocate_processor
848 victim_owner = _Scheduler_Node_get_owner( victim );
849 _Thread_Scheduler_acquire_critical( victim_owner, &lock_context );
852 if ( victim_owner->
Scheduler.state == THREAD_SCHEDULER_SCHEDULED ) {
853 _Scheduler_Thread_change_state( victim_owner, THREAD_SCHEDULER_READY );
855 if ( victim_owner->
Scheduler.helping_nodes > 0 ) {
856 _Scheduler_SMP_Request_ask_for_help( victim_owner );
860 cpu = _Thread_Get_CPU( victim_owner );
862 cpu = _Thread_Get_CPU( victim_idle );
865 _Thread_Scheduler_release_critical( victim_owner, &lock_context );
867 _Scheduler_SMP_Allocate_processor(
893 self = _Scheduler_SMP_Get_self( context );
899 _Chain_Next( &lowest_scheduled->Node.Chain ) ==
903 return lowest_scheduled;
922static inline void _Scheduler_SMP_Enqueue_to_scheduled(
927 Scheduler_SMP_Insert insert_scheduled,
928 Scheduler_SMP_Move move_from_scheduled_to_ready,
929 Scheduler_SMP_Move move_from_ready_to_scheduled,
930 Scheduler_SMP_Allocate_processor allocate_processor,
931 Scheduler_Get_idle_node get_idle_node,
932 Scheduler_Release_idle_node release_idle_node
938 lowest_scheduled_idle = _Scheduler_Release_idle_thread_if_necessary(
944 ( *move_from_scheduled_to_ready )( context, lowest_scheduled );
946 action = _Scheduler_SMP_Try_to_schedule( node, get_idle_node, context );
949 _Scheduler_SMP_Preempt(
953 lowest_scheduled_idle,
957 ( *insert_scheduled )( context, node, priority );
959 _Assert( action == SCHEDULER_SMP_DO_NOT_SCHEDULE );
961 if ( lowest_scheduled_idle != NULL ) {
962 (void) _Scheduler_Use_idle_thread( lowest_scheduled, get_idle_node, context );
965 ( *move_from_ready_to_scheduled )( context, lowest_scheduled );
991static inline bool _Scheduler_SMP_Enqueue(
996 Scheduler_SMP_Insert insert_ready,
997 Scheduler_SMP_Insert insert_scheduled,
998 Scheduler_SMP_Move move_from_scheduled_to_ready,
999 Scheduler_SMP_Move move_from_ready_to_scheduled,
1000 Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled,
1001 Scheduler_SMP_Allocate_processor allocate_processor,
1002 Scheduler_Get_idle_node get_idle_node,
1003 Scheduler_Release_idle_node release_idle_node
1009 lowest_scheduled = ( *get_lowest_scheduled )( context, node );
1015 &lowest_scheduled->Node.Chain
1018 _Scheduler_SMP_Enqueue_to_scheduled(
1024 move_from_scheduled_to_ready,
1025 move_from_ready_to_scheduled,
1033 ( *insert_ready )( context, node, insert_priority );
1059static inline void _Scheduler_SMP_Enqueue_scheduled(
1064 Scheduler_SMP_Extract extract_from_ready,
1065 Scheduler_SMP_Get_highest_ready get_highest_ready,
1066 Scheduler_SMP_Insert insert_ready,
1067 Scheduler_SMP_Insert insert_scheduled,
1068 Scheduler_SMP_Move move_from_ready_to_scheduled,
1069 Scheduler_SMP_Allocate_processor allocate_processor,
1070 Scheduler_Get_idle_node get_idle_node,
1071 Scheduler_Release_idle_node release_idle_node
1076 node_idle = _Scheduler_Release_idle_thread_if_necessary(
1086 highest_ready = ( *get_highest_ready )( context, node );
1093 node->sticky_level > 0 && ( *order )(
1096 &highest_ready->Node.Chain
1099 if ( node_idle != NULL ) {
1103 owner = _Scheduler_Node_get_owner( node );
1104 _Thread_Scheduler_acquire_critical( owner, &lock_context );
1106 if ( owner->
Scheduler.state == THREAD_SCHEDULER_READY ) {
1109 _Scheduler_SMP_Cancel_ask_for_help( owner );
1110 _Scheduler_Thread_change_state( owner, THREAD_SCHEDULER_SCHEDULED );
1111 cpu = _Thread_Get_CPU( node_idle );
1112 _Thread_Set_CPU( owner, cpu );
1113 _Thread_Scheduler_release_critical( owner, &lock_context );
1114 _Thread_Dispatch_update_heir( _Per_CPU_Get(), cpu, owner );
1118 _Thread_Scheduler_release_critical( owner, &lock_context );
1119 new_idle = _Scheduler_Use_idle_thread( node, get_idle_node, context );
1124 ( *insert_scheduled )( context, node, insert_priority );
1129 action = _Scheduler_SMP_Try_to_schedule(
1136 _Scheduler_SMP_Preempt(
1144 ( *move_from_ready_to_scheduled )( context, highest_ready );
1145 ( *insert_ready )( context, node, insert_priority );
1149 _Assert( action == SCHEDULER_SMP_DO_NOT_SCHEDULE );
1150 ( *extract_from_ready )( context, highest_ready );
1160static inline void _Scheduler_SMP_Extract_from_scheduled(
1166 _Chain_Extract_unprotected( &node->Node.Chain );
1185static inline void _Scheduler_SMP_Schedule_highest_ready(
1189 Scheduler_SMP_Extract extract_from_scheduled,
1190 Scheduler_SMP_Extract extract_from_ready,
1191 Scheduler_SMP_Get_highest_ready get_highest_ready,
1192 Scheduler_SMP_Move move_from_ready_to_scheduled,
1193 Scheduler_SMP_Allocate_processor allocate_processor,
1194 Scheduler_Get_idle_node get_idle_node
1200 ( *extract_from_scheduled )( context, victim );
1203 Scheduler_Node *highest_ready = ( *get_highest_ready )( context, victim );
1205 action = _Scheduler_SMP_Try_to_schedule(
1212 _Scheduler_SMP_Allocate_processor(
1219 ( *move_from_ready_to_scheduled )( context, highest_ready );
1223 _Assert( action == SCHEDULER_SMP_DO_NOT_SCHEDULE );
1224 ( *extract_from_ready )( context, highest_ready );
1241static inline void _Scheduler_SMP_Preempt_and_schedule_highest_ready(
1244 Scheduler_SMP_Extract extract_from_ready,
1245 Scheduler_SMP_Get_highest_ready get_highest_ready,
1246 Scheduler_SMP_Move move_from_ready_to_scheduled,
1247 Scheduler_SMP_Allocate_processor allocate_processor,
1248 Scheduler_Get_idle_node get_idle_node,
1249 Scheduler_Release_idle_node release_idle_node
1256 victim_idle = _Scheduler_Release_idle_thread_if_necessary(
1263 Scheduler_Node *highest_ready = ( *get_highest_ready )( context, victim );
1265 action = _Scheduler_SMP_Try_to_schedule(
1272 _Scheduler_SMP_Preempt(
1280 ( *move_from_ready_to_scheduled )( context, highest_ready );
1284 _Assert( action == SCHEDULER_SMP_DO_NOT_SCHEDULE );
1285 ( *extract_from_ready )( context, highest_ready );
1305static inline void _Scheduler_SMP_Block(
1309 Scheduler_SMP_Extract extract_from_scheduled,
1310 Scheduler_SMP_Extract extract_from_ready,
1311 Scheduler_SMP_Get_highest_ready get_highest_ready,
1312 Scheduler_SMP_Move move_from_ready_to_scheduled,
1313 Scheduler_SMP_Allocate_processor allocate_processor,
1314 Scheduler_Get_idle_node get_idle_node
1322 sticky_level = node->sticky_level;
1324 node->sticky_level = sticky_level;
1327 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1328 _Scheduler_SMP_Cancel_ask_for_help( thread );
1329 cpu = _Thread_Get_CPU( thread );
1330 _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_BLOCKED );
1331 _Thread_Scheduler_release_critical( thread, &lock_context );
1333 node_state = _Scheduler_SMP_Node_state( node );
1338 _Scheduler_Node_get_idle( node ) == NULL
1342 idle = _Scheduler_Use_idle_thread( node, get_idle_node, context );
1343 _Thread_Set_CPU( idle, cpu );
1344 _Thread_Dispatch_update_heir( _Per_CPU_Get(), cpu, idle );
1350 _Assert( _Scheduler_Node_get_user( node ) == thread );
1351 _Assert( _Scheduler_Node_get_idle( node ) == NULL );
1354 _Scheduler_SMP_Schedule_highest_ready(
1358 extract_from_scheduled,
1361 move_from_ready_to_scheduled,
1367 ( *extract_from_ready )( context, node );
1381static inline void _Scheduler_SMP_Unblock(
1385 Scheduler_SMP_Update update,
1386 Scheduler_SMP_Enqueue enqueue,
1387 Scheduler_Release_idle_node release_idle_node
1395 ++node->sticky_level;
1396 _Assert( node->sticky_level > 0 );
1398 node_state = _Scheduler_SMP_Node_state( node );
1401 _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_SCHEDULED );
1402 _Scheduler_Discard_idle_thread(
1412 _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_READY );
1414 priority = _Scheduler_Node_get_priority( node );
1417 if ( priority != _Scheduler_SMP_Node_priority( node ) ) {
1418 ( *update )( context, node, priority );
1426 needs_help = ( *enqueue )( context, node, insert_priority );
1428 if ( needs_help && thread->
Scheduler.helping_nodes > 0 ) {
1429 _Scheduler_SMP_Request_ask_for_help( thread );
1433 _Assert( node->sticky_level > 0 );
1434 _Assert( node->idle == NULL );
1435 _Scheduler_SMP_Request_ask_for_help( thread );
1460static inline void _Scheduler_SMP_Update_priority(
1464 Scheduler_SMP_Extract extract_from_scheduled,
1465 Scheduler_SMP_Extract extract_from_ready,
1466 Scheduler_SMP_Update update,
1467 Scheduler_SMP_Enqueue enqueue,
1468 Scheduler_SMP_Enqueue_scheduled enqueue_scheduled,
1469 Scheduler_SMP_Ask_for_help ask_for_help
1476 insert_priority = _Scheduler_Node_get_priority( node );
1479 if ( priority == _Scheduler_SMP_Node_priority( node ) ) {
1480 if ( _Thread_Is_ready( thread ) ) {
1481 ( *ask_for_help )( context, thread, node );
1487 node_state = _Scheduler_SMP_Node_state( node );
1490 ( *extract_from_scheduled )( context, node );
1491 ( *update )( context, node, priority );
1492 ( *enqueue_scheduled )( context, node, insert_priority );
1494 ( *extract_from_ready )( context, node );
1495 ( *update )( context, node, priority );
1496 ( *enqueue )( context, node, insert_priority );
1498 ( *update )( context, node, priority );
1500 if ( _Thread_Is_ready( thread ) ) {
1501 ( *ask_for_help )( context, thread, node );
1519static inline void _Scheduler_SMP_Yield(
1523 Scheduler_SMP_Extract extract_from_scheduled,
1524 Scheduler_SMP_Extract extract_from_ready,
1525 Scheduler_SMP_Enqueue enqueue,
1526 Scheduler_SMP_Enqueue_scheduled enqueue_scheduled
1534 node_state = _Scheduler_SMP_Node_state( node );
1535 insert_priority = _Scheduler_SMP_Node_priority( node );
1539 ( *extract_from_scheduled )( context, node );
1540 ( *enqueue_scheduled )( context, node, insert_priority );
1542 ( *extract_from_ready )( context, node );
1543 (void) ( *enqueue )( context, node, insert_priority );
1554static inline void _Scheduler_SMP_Insert_scheduled(
1562 self = _Scheduler_SMP_Get_self( context );
1564 _Chain_Insert_ordered_unprotected(
1566 &node_to_insert->Node.Chain,
1567 &priority_to_insert,
1568 _Scheduler_SMP_Priority_less_equal
1594static inline bool _Scheduler_SMP_Ask_for_help(
1599 Scheduler_SMP_Insert insert_ready,
1600 Scheduler_SMP_Insert insert_scheduled,
1601 Scheduler_SMP_Move move_from_scheduled_to_ready,
1602 Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled,
1603 Scheduler_SMP_Allocate_processor allocate_processor,
1604 Scheduler_Release_idle_node release_idle_node
1611 if ( thread->
Scheduler.pinned_scheduler != NULL ) {
1619 lowest_scheduled = ( *get_lowest_scheduled )( context, node );
1621 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1623 if ( thread->
Scheduler.state == THREAD_SCHEDULER_READY ) {
1626 node_state = _Scheduler_SMP_Node_state( node );
1631 insert_priority = _Scheduler_SMP_Node_priority( node );
1637 &lowest_scheduled->Node.Chain
1642 _Scheduler_SMP_Cancel_ask_for_help( thread );
1643 _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_SCHEDULED );
1644 _Thread_Scheduler_release_critical( thread, &lock_context );
1646 lowest_scheduled_idle = _Scheduler_Release_idle_thread_if_necessary(
1652 _Scheduler_SMP_Preempt(
1656 lowest_scheduled_idle,
1660 ( *move_from_scheduled_to_ready )( context, lowest_scheduled );
1661 ( *insert_scheduled )( context, node, insert_priority );
1665 _Thread_Scheduler_release_critical( thread, &lock_context );
1668 ( *insert_ready )( context, node, insert_priority );
1672 _Scheduler_SMP_Cancel_ask_for_help( thread );
1673 _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_SCHEDULED );
1674 _Thread_Scheduler_release_critical( thread, &lock_context );
1675 _Scheduler_Discard_idle_thread(
1683 _Thread_Scheduler_release_critical( thread, &lock_context );
1687 _Thread_Scheduler_release_critical( thread, &lock_context );
1703static inline void _Scheduler_SMP_Reconsider_help_request(
1707 Scheduler_SMP_Extract extract_from_ready
1712 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1715 thread->
Scheduler.state == THREAD_SCHEDULER_SCHEDULED
1717 && node->sticky_level == 1
1720 ( *extract_from_ready )( context, node );
1723 _Thread_Scheduler_release_critical( thread, &lock_context );
1743static inline void _Scheduler_SMP_Withdraw_node(
1747 Thread_Scheduler_state next_state,
1748 Scheduler_SMP_Extract extract_from_scheduled,
1749 Scheduler_SMP_Extract extract_from_ready,
1750 Scheduler_SMP_Get_highest_ready get_highest_ready,
1751 Scheduler_SMP_Move move_from_ready_to_scheduled,
1752 Scheduler_SMP_Allocate_processor allocate_processor,
1753 Scheduler_Get_idle_node get_idle_node
1759 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1761 node_state = _Scheduler_SMP_Node_state( node );
1766 _Assert( thread == _Scheduler_Node_get_user( node ) );
1767 cpu = _Thread_Get_CPU( thread );
1768 _Scheduler_Thread_change_state( thread, next_state );
1769 _Thread_Scheduler_release_critical( thread, &lock_context );
1771 _Assert( _Scheduler_Node_get_user( node ) == thread );
1772 _Assert( _Scheduler_Node_get_idle( node ) == NULL );
1774 _Scheduler_SMP_Schedule_highest_ready(
1778 extract_from_scheduled,
1781 move_from_ready_to_scheduled,
1786 _Thread_Scheduler_release_critical( thread, &lock_context );
1788 ( *extract_from_ready )( context, node );
1791 _Thread_Scheduler_release_critical( thread, &lock_context );
1804static inline void _Scheduler_SMP_Make_sticky(
1808 Scheduler_SMP_Update update,
1809 Scheduler_SMP_Enqueue enqueue
1816 node_state = _Scheduler_SMP_Node_state( node );
1823 context = _Scheduler_Get_context( scheduler );
1824 priority = _Scheduler_Node_get_priority( node );
1827 if ( priority != _Scheduler_SMP_Node_priority( node ) ) {
1828 ( *update )( context, node, priority );
1832 (void) ( *enqueue )( context, node, insert_priority );
1845static inline void _Scheduler_SMP_Clean_sticky(
1849 Scheduler_SMP_Extract extract_from_scheduled,
1850 Scheduler_SMP_Extract extract_from_ready,
1851 Scheduler_SMP_Get_highest_ready get_highest_ready,
1852 Scheduler_SMP_Move move_from_ready_to_scheduled,
1853 Scheduler_SMP_Allocate_processor allocate_processor,
1854 Scheduler_Get_idle_node get_idle_node,
1855 Scheduler_Release_idle_node release_idle_node
1862 node_state = _Scheduler_SMP_Node_state( node );
1867 idle = _Scheduler_Node_get_idle( node );
1869 if ( idle != NULL ) {
1872 context = _Scheduler_Get_context( scheduler );
1874 _Scheduler_Release_idle_thread( node, idle, release_idle_node, context );
1875 _Scheduler_SMP_Schedule_highest_ready(
1878 _Thread_Get_CPU( idle ),
1879 extract_from_scheduled,
1882 move_from_ready_to_scheduled,
1898static inline void _Scheduler_SMP_Do_start_idle(
1902 Scheduler_SMP_Register_idle register_idle
1908 self = _Scheduler_SMP_Get_self( context );
1909 node = _Scheduler_SMP_Thread_get_node( idle );
1911 _Scheduler_Thread_change_state( idle, THREAD_SCHEDULER_SCHEDULED );
1914 _Thread_Set_CPU( idle, cpu );
1915 ( *register_idle )( context, &node->Base, cpu );
1916 _Chain_Append_unprotected( &self->
Scheduled, &node->Base.Node.Chain );
1928static inline void _Scheduler_SMP_Add_processor(
1931 Scheduler_SMP_Has_ready has_ready,
1932 Scheduler_SMP_Enqueue_scheduled enqueue_scheduled,
1933 Scheduler_SMP_Register_idle register_idle
1939 self = _Scheduler_SMP_Get_self( context );
1940 idle->
Scheduler.state = THREAD_SCHEDULER_SCHEDULED;
1941 node = _Thread_Scheduler_get_home_node( idle );
1943 ( *register_idle )( context, node, _Thread_Get_CPU( idle ) );
1945 if ( ( *has_ready )( &self->
Base ) ) {
1948 insert_priority = _Scheduler_SMP_Node_priority( node );
1950 ( *enqueue_scheduled )( &self->
Base, node, insert_priority );
1952 _Chain_Append_unprotected( &self->
Scheduled, &node->Node.Chain );
1972 Scheduler_SMP_Extract extract_from_scheduled,
1973 Scheduler_SMP_Extract extract_from_ready,
1974 Scheduler_SMP_Enqueue enqueue,
1975 Scheduler_Get_idle_node get_idle_node,
1976 Scheduler_Release_idle_node release_idle_node
1979 (void) extract_from_ready;
1988 self = _Scheduler_SMP_Get_self( context );
1989 chain_node = _Chain_First( &self->
Scheduled );
1994 victim_user = _Scheduler_Node_get_user( victim_node );
1995 chain_node = _Chain_Next( chain_node );
1996 }
while ( _Thread_Get_CPU( victim_user ) != cpu );
1998 ( *extract_from_scheduled )( &self->
Base, victim_node );
1999 victim_owner = _Scheduler_Node_get_owner( victim_node );
2001 if ( !victim_owner->is_idle ) {
2006 victim_idle = _Scheduler_Release_idle_thread_if_necessary(
2011 idle_node = ( *get_idle_node )( &self->
Base );
2012 idle = _Scheduler_Node_get_owner( idle_node );
2013 _Scheduler_SMP_Preempt(
2018 _Scheduler_SMP_Allocate_processor_exact
2022 insert_priority = _Scheduler_SMP_Node_priority( victim_node );
2024 ( *enqueue )( &self->
Base, victim_node, insert_priority );
2026 _Assert( victim_owner == victim_user );
2027 _Assert( _Scheduler_Node_get_idle( victim_node ) == NULL );
2028 idle = victim_owner;
2055static inline void _Scheduler_SMP_Set_affinity(
2060 Scheduler_SMP_Set_affinity set_affinity,
2061 Scheduler_SMP_Extract extract_from_scheduled,
2062 Scheduler_SMP_Extract extract_from_ready,
2063 Scheduler_SMP_Get_highest_ready get_highest_ready,
2064 Scheduler_SMP_Move move_from_ready_to_scheduled,
2065 Scheduler_SMP_Enqueue enqueue,
2066 Scheduler_SMP_Allocate_processor allocate_processor,
2067 Scheduler_Get_idle_node get_idle_node,
2068 Scheduler_Release_idle_node release_idle_node
2076 node_state = _Scheduler_SMP_Node_state( node );
2077 insert_priority = _Scheduler_SMP_Node_priority( node );
2081 ( *extract_from_scheduled )( context, node );
2082 _Scheduler_SMP_Preempt_and_schedule_highest_ready(
2087 move_from_ready_to_scheduled,
2092 ( *set_affinity )( context, node, arg );
2093 ( *enqueue )( context, node, insert_priority );
2095 ( *extract_from_ready )( context, node );
2096 ( *set_affinity )( context, node, arg );
2097 ( *enqueue )( context, node, insert_priority );
2100 ( *set_affinity )( context, node, arg );
This header file provides the interfaces of the Assert Handler.
This header file provides the kernel character input/output support API.
This header file provides interfaces of the Chain Handler which are only used by the implementation.
#define RTEMS_PREDICT_FALSE(_exp)
Evaluates the integral expression and tells the compiler that the predicted value is false (0).
Definition: basedefs.h:757
#define RTEMS_PREDICT_TRUE(_exp)
Evaluates the integral expression and tells the compiler that the predicted value is true (1).
Definition: basedefs.h:776
#define _Assert_Unused_variable_equals(_var, _val)
Assert if unused return value is equal.
Definition: assert.h:108
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG and static analysis runs.
Definition: assert.h:96
bool(* Chain_Node_order)(const void *key, const Chain_Node *left, const Chain_Node *right)
Chain node order.
Definition: chainimpl.h:853
#define _ISR_Get_level()
Return current interrupt level.
Definition: isrlevel.h:147
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:91
void _Scheduler_SMP_Remove_ask_for_help_from_processor(Thread_Control *thread, Per_CPU_Control *cpu)
Removes the thread's ask for help request from the processor.
Definition: schedulersmp.c:43
Scheduler_SMP_Action
This enumeration defines what a scheduler should do with a node which could be scheduled.
Definition: schedulersmpimpl.h:649
Scheduler_SMP_Node_state
SMP scheduler node states.
Definition: schedulersmp.h:76
@ SCHEDULER_SMP_NODE_READY
This scheduler node is ready.
Definition: schedulersmp.h:100
@ SCHEDULER_SMP_NODE_BLOCKED
This scheduler node is blocked.
Definition: schedulersmp.h:82
@ SCHEDULER_SMP_NODE_SCHEDULED
The scheduler node is scheduled.
Definition: schedulersmp.h:92
#define SCHEDULER_PRIORITY_APPEND(priority)
Returns the priority control with the append indicator bit set.
Definition: schedulernodeimpl.h:81
#define SCHEDULER_PRIORITY_PURIFY(priority)
Clears the priority append indicator bit.
Definition: schedulernodeimpl.h:75
This header file provides interfaces of the Simple Priority Scheduler which are only used by the impl...
This header file provides interfaces of the SMP Scheduler which are used by the implementation and th...
This structure represents a chain node.
Definition: chain.h:78
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:94
Per CPU Core Structure.
Definition: percpu.h:384
struct _Thread_Control * heir
This is the heir thread for this processor.
Definition: percpu.h:473
volatile bool dispatch_necessary
This is set to true when this processor needs to run the thread dispatcher.
Definition: percpu.h:437
Scheduler context.
Definition: scheduler.h:318
Scheduler node for per-thread data.
Definition: schedulernode.h:94
Scheduler context specialization for SMP schedulers.
Definition: schedulersmp.h:61
Chain_Control Scheduled
The chain of scheduled nodes.
Definition: schedulersmp.h:70
Scheduler_Context Base
Basic scheduler context.
Definition: schedulersmp.h:65
Scheduler node specialization for SMP schedulers.
Definition: schedulersmp.h:106
Priority_Control priority
The current priority of thread owning this node.
Definition: schedulersmp.h:120
Scheduler control.
Definition: scheduler.h:337
Thread_Scheduler_control Scheduler
Scheduler related control.
Definition: thread.h:874