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 );
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(
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
1532 node_state = _Scheduler_SMP_Node_state( node );
1533 insert_priority = _Scheduler_SMP_Node_priority( node );
1537 ( *extract_from_scheduled )(
context, node );
1538 ( *enqueue_scheduled )(
context, node, insert_priority );
1540 ( *extract_from_ready )(
context, node );
1541 (void) ( *enqueue )(
context, node, insert_priority );
1552static inline void _Scheduler_SMP_Insert_scheduled(
1560 self = _Scheduler_SMP_Get_self(
context );
1562 _Chain_Insert_ordered_unprotected(
1564 &node_to_insert->Node.Chain,
1565 &priority_to_insert,
1566 _Scheduler_SMP_Priority_less_equal
1592static inline bool _Scheduler_SMP_Ask_for_help(
1597 Scheduler_SMP_Insert insert_ready,
1598 Scheduler_SMP_Insert insert_scheduled,
1599 Scheduler_SMP_Move move_from_scheduled_to_ready,
1600 Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled,
1601 Scheduler_SMP_Allocate_processor allocate_processor,
1602 Scheduler_Release_idle_node release_idle_node
1609 if ( thread->
Scheduler.pinned_scheduler != NULL ) {
1617 lowest_scheduled = ( *get_lowest_scheduled )(
context, node );
1619 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1621 if ( thread->
Scheduler.state == THREAD_SCHEDULER_READY ) {
1624 node_state = _Scheduler_SMP_Node_state( node );
1629 insert_priority = _Scheduler_SMP_Node_priority( node );
1635 &lowest_scheduled->Node.Chain
1640 _Scheduler_SMP_Cancel_ask_for_help( thread );
1641 _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_SCHEDULED );
1642 _Thread_Scheduler_release_critical( thread, &lock_context );
1644 lowest_scheduled_idle = _Scheduler_Release_idle_thread_if_necessary(
1650 _Scheduler_SMP_Preempt(
1654 lowest_scheduled_idle,
1658 ( *move_from_scheduled_to_ready )(
context, lowest_scheduled );
1659 ( *insert_scheduled )(
context, node, insert_priority );
1663 _Thread_Scheduler_release_critical( thread, &lock_context );
1666 ( *insert_ready )(
context, node, insert_priority );
1670 _Scheduler_SMP_Cancel_ask_for_help( thread );
1671 _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_SCHEDULED );
1672 _Thread_Scheduler_release_critical( thread, &lock_context );
1673 _Scheduler_Discard_idle_thread(
1681 _Thread_Scheduler_release_critical( thread, &lock_context );
1685 _Thread_Scheduler_release_critical( thread, &lock_context );
1701static inline void _Scheduler_SMP_Reconsider_help_request(
1705 Scheduler_SMP_Extract extract_from_ready
1710 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1713 thread->
Scheduler.state == THREAD_SCHEDULER_SCHEDULED
1715 && node->sticky_level == 1
1718 ( *extract_from_ready )(
context, node );
1721 _Thread_Scheduler_release_critical( thread, &lock_context );
1741static inline void _Scheduler_SMP_Withdraw_node(
1745 Thread_Scheduler_state next_state,
1746 Scheduler_SMP_Extract extract_from_scheduled,
1747 Scheduler_SMP_Extract extract_from_ready,
1748 Scheduler_SMP_Get_highest_ready get_highest_ready,
1749 Scheduler_SMP_Move move_from_ready_to_scheduled,
1750 Scheduler_SMP_Allocate_processor allocate_processor,
1751 Scheduler_Get_idle_node get_idle_node
1757 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1759 node_state = _Scheduler_SMP_Node_state( node );
1764 _Assert( thread == _Scheduler_Node_get_user( node ) );
1765 cpu = _Thread_Get_CPU( thread );
1766 _Scheduler_Thread_change_state( thread, next_state );
1767 _Thread_Scheduler_release_critical( thread, &lock_context );
1769 _Assert( _Scheduler_Node_get_user( node ) == thread );
1770 _Assert( _Scheduler_Node_get_idle( node ) == NULL );
1772 _Scheduler_SMP_Schedule_highest_ready(
1776 extract_from_scheduled,
1779 move_from_ready_to_scheduled,
1784 _Thread_Scheduler_release_critical( thread, &lock_context );
1786 ( *extract_from_ready )(
context, node );
1789 _Thread_Scheduler_release_critical( thread, &lock_context );
1802static inline void _Scheduler_SMP_Make_sticky(
1806 Scheduler_SMP_Update update,
1807 Scheduler_SMP_Enqueue enqueue
1812 node_state = _Scheduler_SMP_Node_state( node );
1819 context = _Scheduler_Get_context( scheduler );
1820 priority = _Scheduler_Node_get_priority( node );
1823 if ( priority != _Scheduler_SMP_Node_priority( node ) ) {
1824 ( *update )(
context, node, priority );
1828 (void) ( *enqueue )(
context, node, insert_priority );
1841static inline void _Scheduler_SMP_Clean_sticky(
1845 Scheduler_SMP_Extract extract_from_scheduled,
1846 Scheduler_SMP_Extract extract_from_ready,
1847 Scheduler_SMP_Get_highest_ready get_highest_ready,
1848 Scheduler_SMP_Move move_from_ready_to_scheduled,
1849 Scheduler_SMP_Allocate_processor allocate_processor,
1850 Scheduler_Get_idle_node get_idle_node,
1851 Scheduler_Release_idle_node release_idle_node
1856 node_state = _Scheduler_SMP_Node_state( node );
1861 idle = _Scheduler_Node_get_idle( node );
1863 if ( idle != NULL ) {
1866 context = _Scheduler_Get_context( scheduler );
1868 _Scheduler_Release_idle_thread( node, idle, release_idle_node,
context );
1869 _Scheduler_SMP_Schedule_highest_ready(
1872 _Thread_Get_CPU( idle ),
1873 extract_from_scheduled,
1876 move_from_ready_to_scheduled,
1892static inline void _Scheduler_SMP_Do_start_idle(
1896 Scheduler_SMP_Register_idle register_idle
1902 self = _Scheduler_SMP_Get_self(
context );
1903 node = _Scheduler_SMP_Thread_get_node( idle );
1905 _Scheduler_Thread_change_state( idle, THREAD_SCHEDULER_SCHEDULED );
1908 _Thread_Set_CPU( idle, cpu );
1909 ( *register_idle )(
context, &node->Base, cpu );
1910 _Chain_Append_unprotected( &self->
Scheduled, &node->Base.Node.Chain );
1922static inline void _Scheduler_SMP_Add_processor(
1925 Scheduler_SMP_Has_ready has_ready,
1926 Scheduler_SMP_Enqueue_scheduled enqueue_scheduled,
1927 Scheduler_SMP_Register_idle register_idle
1933 self = _Scheduler_SMP_Get_self(
context );
1934 idle->
Scheduler.state = THREAD_SCHEDULER_SCHEDULED;
1935 node = _Thread_Scheduler_get_home_node( idle );
1937 ( *register_idle )(
context, node, _Thread_Get_CPU( idle ) );
1939 if ( ( *has_ready )( &self->
Base ) ) {
1942 insert_priority = _Scheduler_SMP_Node_priority( node );
1944 ( *enqueue_scheduled )( &self->
Base, node, insert_priority );
1946 _Chain_Append_unprotected( &self->
Scheduled, &node->Node.Chain );
1966 Scheduler_SMP_Extract extract_from_scheduled,
1967 Scheduler_SMP_Extract extract_from_ready,
1968 Scheduler_SMP_Enqueue enqueue,
1969 Scheduler_Get_idle_node get_idle_node,
1970 Scheduler_Release_idle_node release_idle_node
1980 self = _Scheduler_SMP_Get_self(
context );
1981 chain_node = _Chain_First( &self->
Scheduled );
1986 victim_user = _Scheduler_Node_get_user( victim_node );
1987 chain_node = _Chain_Next( chain_node );
1988 }
while ( _Thread_Get_CPU( victim_user ) != cpu );
1990 ( *extract_from_scheduled )( &self->
Base, victim_node );
1991 victim_owner = _Scheduler_Node_get_owner( victim_node );
1993 if ( !victim_owner->is_idle ) {
1998 victim_idle = _Scheduler_Release_idle_thread_if_necessary(
2003 idle_node = ( *get_idle_node )( &self->
Base );
2004 idle = _Scheduler_Node_get_owner( idle_node );
2005 _Scheduler_SMP_Preempt(
2010 _Scheduler_SMP_Allocate_processor_exact
2014 insert_priority = _Scheduler_SMP_Node_priority( victim_node );
2016 ( *enqueue )( &self->
Base, victim_node, insert_priority );
2018 _Assert( victim_owner == victim_user );
2019 _Assert( _Scheduler_Node_get_idle( victim_node ) == NULL );
2020 idle = victim_owner;
2047static inline void _Scheduler_SMP_Set_affinity(
2052 Scheduler_SMP_Set_affinity set_affinity,
2053 Scheduler_SMP_Extract extract_from_scheduled,
2054 Scheduler_SMP_Extract extract_from_ready,
2055 Scheduler_SMP_Get_highest_ready get_highest_ready,
2056 Scheduler_SMP_Move move_from_ready_to_scheduled,
2057 Scheduler_SMP_Enqueue enqueue,
2058 Scheduler_SMP_Allocate_processor allocate_processor,
2059 Scheduler_Get_idle_node get_idle_node,
2060 Scheduler_Release_idle_node release_idle_node
2066 node_state = _Scheduler_SMP_Node_state( node );
2067 insert_priority = _Scheduler_SMP_Node_priority( node );
2071 ( *extract_from_scheduled )(
context, node );
2072 _Scheduler_SMP_Preempt_and_schedule_highest_ready(
2077 move_from_ready_to_scheduled,
2082 ( *set_affinity )(
context, node, arg );
2083 ( *enqueue )(
context, node, insert_priority );
2085 ( *extract_from_ready )(
context, node );
2086 ( *set_affinity )(
context, node, arg );
2087 ( *enqueue )(
context, node, insert_priority );
2090 ( *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:732
#define RTEMS_PREDICT_TRUE(_exp)
Evaluates the integral expression and tells the compiler that the predicted value is true (1).
Definition: basedefs.h:751
#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:847
#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
rtems_termios_device_context * context
Definition: console-config.c:62
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