23 #ifndef _RTEMS_SCORE_SCHEDULERSMPIMPL_H 24 #define _RTEMS_SCORE_SCHEDULERSMPIMPL_H 27 #include <rtems/score/assert.h> 278 typedef bool ( *Scheduler_SMP_Has_ready )(
292 typedef void ( *Scheduler_SMP_Extract )(
297 typedef void ( *Scheduler_SMP_Insert )(
303 typedef void ( *Scheduler_SMP_Move )(
308 typedef bool ( *Scheduler_SMP_Ask_for_help )(
314 typedef void ( *Scheduler_SMP_Update )(
320 typedef void ( *Scheduler_SMP_Set_affinity )(
326 typedef bool ( *Scheduler_SMP_Enqueue )(
332 typedef void ( *Scheduler_SMP_Allocate_processor )(
339 typedef void ( *Scheduler_SMP_Register_idle )(
345 static inline void _Scheduler_SMP_Do_nothing_register_idle(
356 static inline bool _Scheduler_SMP_Priority_less_equal(
357 const void *to_insert,
367 return *priority_to_insert <= node_next->
priority;
377 static inline void _Scheduler_SMP_Initialize(
420 static inline void _Scheduler_SMP_Node_initialize(
427 _Scheduler_Node_do_initialize( scheduler, &node->
Base, thread, priority );
432 static inline void _Scheduler_SMP_Node_update_priority(
440 static inline void _Scheduler_SMP_Node_change_state(
447 the_node = _Scheduler_SMP_Node_downcast( node );
448 the_node->
state = new_state;
451 static inline bool _Scheduler_SMP_Is_processor_owned_by_us(
456 return cpu->Scheduler.context ==
context;
472 static inline void _Scheduler_SMP_Release_idle_thread(
482 static inline void _Scheduler_SMP_Exctract_idle_thread(
489 static inline void _Scheduler_SMP_Allocate_processor_lazy(
496 Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
497 Thread_Control *victim_thread = _Scheduler_Node_get_user( victim );
504 if ( _Thread_Is_executing_on_a_processor( scheduled_thread ) ) {
505 if ( _Scheduler_SMP_Is_processor_owned_by_us( context, scheduled_cpu ) ) {
506 heir = scheduled_cpu->
heir;
507 _Thread_Dispatch_update_heir(
514 heir = scheduled_thread;
517 heir = scheduled_thread;
520 if ( heir != victim_thread ) {
521 _Thread_Set_CPU( heir, victim_cpu );
522 _Thread_Dispatch_update_heir( cpu_self, victim_cpu, heir );
532 static inline void _Scheduler_SMP_Allocate_processor_exact(
539 Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
545 _Thread_Set_CPU( scheduled_thread, victim_cpu );
546 _Thread_Dispatch_update_heir( cpu_self, victim_cpu, scheduled_thread );
549 static inline void _Scheduler_SMP_Allocate_processor(
554 Scheduler_SMP_Allocate_processor allocate_processor
558 ( *allocate_processor )(
context, scheduled, victim, victim_cpu );
565 Scheduler_SMP_Allocate_processor allocate_processor
572 victim_thread = _Scheduler_Node_get_user( victim );
575 _Thread_Scheduler_acquire_critical( victim_thread, &lock_context );
577 victim_cpu = _Thread_Get_CPU( victim_thread );
579 if ( victim_thread->
Scheduler.state == THREAD_SCHEDULER_SCHEDULED ) {
580 _Scheduler_Thread_change_state( victim_thread, THREAD_SCHEDULER_READY );
582 if ( victim_thread->
Scheduler.helping_nodes > 0 ) {
583 _Per_CPU_Acquire( victim_cpu );
585 &victim_cpu->Threads_in_need_for_help,
588 _Per_CPU_Release( victim_cpu );
592 _Thread_Scheduler_release_critical( victim_thread, &lock_context );
594 _Scheduler_SMP_Allocate_processor(
602 return victim_thread;
605 static inline Scheduler_Node *_Scheduler_SMP_Get_lowest_scheduled(
617 _Assert( &lowest_scheduled->Node.Chain !=
_Chain_Tail( scheduled ) );
622 return lowest_scheduled;
625 static inline void _Scheduler_SMP_Enqueue_to_scheduled(
630 Scheduler_SMP_Insert insert_scheduled,
631 Scheduler_SMP_Move move_from_scheduled_to_ready,
632 Scheduler_SMP_Allocate_processor allocate_processor
635 Scheduler_Try_to_schedule_action action;
637 action = _Scheduler_Try_to_schedule_node(
640 _Scheduler_Node_get_idle( lowest_scheduled ),
641 _Scheduler_SMP_Get_idle_thread
644 if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
645 _Scheduler_SMP_Preempt(
652 ( *insert_scheduled )(
context, node, priority );
653 ( *move_from_scheduled_to_ready )(
context, lowest_scheduled );
655 _Scheduler_Release_idle_thread(
658 _Scheduler_SMP_Release_idle_thread
660 }
else if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_IDLE_EXCHANGE ) {
661 _Scheduler_SMP_Node_change_state(
667 ( *insert_scheduled )(
context, node, priority );
668 ( *move_from_scheduled_to_ready )(
context, lowest_scheduled );
670 _Scheduler_Exchange_idle_thread(
673 _Scheduler_Node_get_idle( lowest_scheduled )
676 _Assert( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
703 static inline bool _Scheduler_SMP_Enqueue(
708 Scheduler_SMP_Insert insert_ready,
709 Scheduler_SMP_Insert insert_scheduled,
710 Scheduler_SMP_Move move_from_scheduled_to_ready,
711 Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled,
712 Scheduler_SMP_Allocate_processor allocate_processor
718 lowest_scheduled = ( *get_lowest_scheduled )(
context, node );
720 if ( ( *order )( &insert_priority, &lowest_scheduled->Node.Chain ) ) {
721 _Scheduler_SMP_Enqueue_to_scheduled(
727 move_from_scheduled_to_ready,
732 ( *insert_ready )(
context, node, insert_priority );
758 static inline bool _Scheduler_SMP_Enqueue_scheduled(
763 Scheduler_SMP_Extract extract_from_ready,
764 Scheduler_SMP_Get_highest_ready get_highest_ready,
765 Scheduler_SMP_Insert insert_ready,
766 Scheduler_SMP_Insert insert_scheduled,
767 Scheduler_SMP_Move move_from_ready_to_scheduled,
768 Scheduler_SMP_Allocate_processor allocate_processor
773 Scheduler_Try_to_schedule_action action;
775 highest_ready = ( *get_highest_ready )(
context, node );
782 node->sticky_level > 0
783 && ( *order )( &insert_priority, &highest_ready->Node.Chain )
785 ( *insert_scheduled )(
context, node, insert_priority );
787 if ( _Scheduler_Node_get_idle( node ) !=
NULL ) {
791 owner = _Scheduler_Node_get_owner( node );
792 _Thread_Scheduler_acquire_critical( owner, &lock_context );
794 if ( owner->
Scheduler.state == THREAD_SCHEDULER_READY ) {
795 _Thread_Scheduler_cancel_need_for_help(
797 _Thread_Get_CPU( owner )
799 _Scheduler_Discard_idle_thread(
803 _Scheduler_SMP_Release_idle_thread
805 _Scheduler_Thread_change_state( owner, THREAD_SCHEDULER_SCHEDULED );
808 _Thread_Scheduler_release_critical( owner, &lock_context );
814 action = _Scheduler_Try_to_schedule_node(
817 _Scheduler_Node_get_idle( node ),
818 _Scheduler_SMP_Get_idle_thread
821 if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
824 _Scheduler_SMP_Preempt(
831 ( *insert_ready )(
context, node, insert_priority );
832 ( *move_from_ready_to_scheduled )(
context, highest_ready );
834 idle = _Scheduler_Release_idle_thread(
837 _Scheduler_SMP_Release_idle_thread
839 return ( idle ==
NULL );
840 }
else if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_IDLE_EXCHANGE ) {
842 _Scheduler_SMP_Node_change_state(
847 ( *insert_ready )(
context, node, insert_priority );
848 ( *move_from_ready_to_scheduled )(
context, highest_ready );
850 _Scheduler_Exchange_idle_thread(
853 _Scheduler_Node_get_idle( node )
857 _Assert( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
859 _Scheduler_SMP_Node_change_state(
864 ( *extract_from_ready )(
context, highest_ready );
869 static inline void _Scheduler_SMP_Extract_from_scheduled(
878 static inline void _Scheduler_SMP_Schedule_highest_ready(
882 Scheduler_SMP_Extract extract_from_ready,
883 Scheduler_SMP_Get_highest_ready get_highest_ready,
884 Scheduler_SMP_Move move_from_ready_to_scheduled,
885 Scheduler_SMP_Allocate_processor allocate_processor
888 Scheduler_Try_to_schedule_action action;
893 action = _Scheduler_Try_to_schedule_node(
897 _Scheduler_SMP_Get_idle_thread
900 if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
901 _Scheduler_SMP_Allocate_processor(
909 ( *move_from_ready_to_scheduled )(
context, highest_ready );
911 _Assert( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
913 _Scheduler_SMP_Node_change_state(
918 ( *extract_from_ready )(
context, highest_ready );
920 }
while ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
923 static inline void _Scheduler_SMP_Preempt_and_schedule_highest_ready(
927 Scheduler_SMP_Extract extract_from_ready,
928 Scheduler_SMP_Get_highest_ready get_highest_ready,
929 Scheduler_SMP_Move move_from_ready_to_scheduled,
930 Scheduler_SMP_Allocate_processor allocate_processor
933 Scheduler_Try_to_schedule_action action;
938 action = _Scheduler_Try_to_schedule_node(
942 _Scheduler_SMP_Get_idle_thread
945 if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
946 _Scheduler_SMP_Preempt(
953 ( *move_from_ready_to_scheduled )(
context, highest_ready );
955 _Assert( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
957 _Scheduler_SMP_Node_change_state(
962 ( *extract_from_ready )(
context, highest_ready );
964 }
while ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
981 static inline void _Scheduler_SMP_Block(
985 Scheduler_SMP_Extract extract_from_scheduled,
986 Scheduler_SMP_Extract extract_from_ready,
987 Scheduler_SMP_Get_highest_ready get_highest_ready,
988 Scheduler_SMP_Move move_from_ready_to_scheduled,
989 Scheduler_SMP_Allocate_processor allocate_processor
995 node_state = _Scheduler_SMP_Node_state( node );
997 thread_cpu = _Scheduler_Block_node(
1002 _Scheduler_SMP_Get_idle_thread
1005 if ( thread_cpu !=
NULL ) {
1009 ( *extract_from_scheduled )(
context, node );
1010 _Scheduler_SMP_Schedule_highest_ready(
1016 move_from_ready_to_scheduled,
1020 ( *extract_from_ready )(
context, node );
1025 static inline void _Scheduler_SMP_Unblock(
1029 Scheduler_SMP_Update update,
1030 Scheduler_SMP_Enqueue enqueue
1036 node_state = _Scheduler_SMP_Node_state( node );
1037 unblock = _Scheduler_Unblock_node(
1042 _Scheduler_SMP_Release_idle_thread
1049 priority = _Scheduler_Node_get_priority( node );
1052 if ( priority != _Scheduler_SMP_Node_priority( node ) ) {
1053 ( *update )(
context, node, priority );
1061 needs_help = ( *enqueue )(
context, node, insert_priority );
1064 _Assert( node->sticky_level > 0 );
1065 _Assert( node->idle ==
NULL );
1070 _Scheduler_Ask_for_help( thread );
1075 static inline void _Scheduler_SMP_Update_priority(
1079 Scheduler_SMP_Extract extract_from_ready,
1080 Scheduler_SMP_Update update,
1081 Scheduler_SMP_Enqueue enqueue,
1082 Scheduler_SMP_Enqueue enqueue_scheduled,
1083 Scheduler_SMP_Ask_for_help ask_for_help
1090 insert_priority = _Scheduler_Node_get_priority( node );
1093 if ( priority == _Scheduler_SMP_Node_priority( node ) ) {
1094 if ( _Thread_Is_ready( thread ) ) {
1095 ( *ask_for_help )(
context, thread, node );
1101 node_state = _Scheduler_SMP_Node_state( node );
1104 _Scheduler_SMP_Extract_from_scheduled( context, node );
1105 ( *update )(
context, node, priority );
1106 ( *enqueue_scheduled )(
context, node, insert_priority );
1108 ( *extract_from_ready )(
context, node );
1109 ( *update )(
context, node, priority );
1110 ( *enqueue )(
context, node, insert_priority );
1112 ( *update )(
context, node, priority );
1114 if ( _Thread_Is_ready( thread ) ) {
1115 ( *ask_for_help )(
context, thread, node );
1120 static inline void _Scheduler_SMP_Yield(
1124 Scheduler_SMP_Extract extract_from_ready,
1125 Scheduler_SMP_Enqueue enqueue,
1126 Scheduler_SMP_Enqueue enqueue_scheduled
1133 node_state = _Scheduler_SMP_Node_state( node );
1134 insert_priority = _Scheduler_SMP_Node_priority( node );
1138 _Scheduler_SMP_Extract_from_scheduled( context, node );
1139 ( *enqueue_scheduled )(
context, node, insert_priority );
1142 ( *extract_from_ready )(
context, node );
1144 needs_help = ( *enqueue )(
context, node, insert_priority );
1150 _Scheduler_Ask_for_help( thread );
1154 static inline void _Scheduler_SMP_Insert_scheduled(
1162 self = _Scheduler_SMP_Get_self( context );
1166 &node_to_insert->Node.Chain,
1167 &priority_to_insert,
1168 _Scheduler_SMP_Priority_less_equal
1172 static inline bool _Scheduler_SMP_Ask_for_help(
1177 Scheduler_SMP_Insert insert_ready,
1178 Scheduler_SMP_Insert insert_scheduled,
1179 Scheduler_SMP_Move move_from_scheduled_to_ready,
1180 Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled,
1181 Scheduler_SMP_Allocate_processor allocate_processor
1196 lowest_scheduled = ( *get_lowest_scheduled )(
context, node );
1198 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1200 if ( thread->
Scheduler.state == THREAD_SCHEDULER_READY ) {
1203 node_state = _Scheduler_SMP_Node_state( node );
1208 insert_priority = _Scheduler_SMP_Node_priority( node );
1210 if ( ( *order )( &insert_priority, &lowest_scheduled->Node.Chain ) ) {
1211 _Thread_Scheduler_cancel_need_for_help(
1213 _Thread_Get_CPU( thread )
1215 _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_SCHEDULED );
1216 _Thread_Scheduler_release_critical( thread, &lock_context );
1218 _Scheduler_SMP_Preempt(
1225 ( *insert_scheduled )(
context, node, insert_priority );
1226 ( *move_from_scheduled_to_ready )(
context, lowest_scheduled );
1228 _Scheduler_Release_idle_thread(
1231 _Scheduler_SMP_Release_idle_thread
1235 _Thread_Scheduler_release_critical( thread, &lock_context );
1237 ( *insert_ready )(
context, node, insert_priority );
1241 _Thread_Scheduler_cancel_need_for_help(
1243 _Thread_Get_CPU( thread )
1245 _Scheduler_Discard_idle_thread(
1249 _Scheduler_SMP_Release_idle_thread
1251 _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_SCHEDULED );
1252 _Thread_Scheduler_release_critical( thread, &lock_context );
1255 _Thread_Scheduler_release_critical( thread, &lock_context );
1259 _Thread_Scheduler_release_critical( thread, &lock_context );
1266 static inline void _Scheduler_SMP_Reconsider_help_request(
1270 Scheduler_SMP_Extract extract_from_ready
1275 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1278 thread->
Scheduler.state == THREAD_SCHEDULER_SCHEDULED
1280 && node->sticky_level == 1
1283 ( *extract_from_ready )(
context, node );
1286 _Thread_Scheduler_release_critical( thread, &lock_context );
1289 static inline void _Scheduler_SMP_Withdraw_node(
1293 Thread_Scheduler_state next_state,
1294 Scheduler_SMP_Extract extract_from_ready,
1295 Scheduler_SMP_Get_highest_ready get_highest_ready,
1296 Scheduler_SMP_Move move_from_ready_to_scheduled,
1297 Scheduler_SMP_Allocate_processor allocate_processor
1303 _Thread_Scheduler_acquire_critical( thread, &lock_context );
1305 node_state = _Scheduler_SMP_Node_state( node );
1311 thread_cpu = _Thread_Get_CPU( thread );
1312 _Scheduler_Thread_change_state( thread, next_state );
1313 _Thread_Scheduler_release_critical( thread, &lock_context );
1315 _Scheduler_SMP_Extract_from_scheduled( context, node );
1316 _Scheduler_SMP_Schedule_highest_ready(
1322 move_from_ready_to_scheduled,
1326 _Thread_Scheduler_release_critical( thread, &lock_context );
1327 ( *extract_from_ready )(
context, node );
1330 _Thread_Scheduler_release_critical( thread, &lock_context );
1334 static inline void _Scheduler_SMP_Do_start_idle(
1338 Scheduler_SMP_Register_idle register_idle
1344 self = _Scheduler_SMP_Get_self( context );
1345 node = _Scheduler_SMP_Thread_get_node( idle );
1347 _Scheduler_Thread_change_state( idle, THREAD_SCHEDULER_SCHEDULED );
1350 _Thread_Set_CPU( idle, cpu );
1353 _Scheduler_SMP_Release_idle_thread( &self->Base, idle );
1356 static inline void _Scheduler_SMP_Add_processor(
1359 Scheduler_SMP_Has_ready has_ready,
1360 Scheduler_SMP_Enqueue enqueue_scheduled,
1361 Scheduler_SMP_Register_idle register_idle
1367 self = _Scheduler_SMP_Get_self( context );
1368 idle->
Scheduler.state = THREAD_SCHEDULER_SCHEDULED;
1369 _Scheduler_SMP_Release_idle_thread( &self->Base, idle );
1370 node = _Thread_Scheduler_get_home_node( idle );
1372 ( *register_idle )(
context, node, _Thread_Get_CPU( idle ) );
1374 if ( ( *has_ready )( &
self->Base ) ) {
1377 insert_priority = _Scheduler_SMP_Node_priority( node );
1379 ( *enqueue_scheduled )( &
self->Base, node, insert_priority );
1388 Scheduler_SMP_Extract extract_from_ready,
1389 Scheduler_SMP_Enqueue enqueue
1399 self = _Scheduler_SMP_Get_self( context );
1405 victim_user = _Scheduler_Node_get_user( victim_node );
1407 }
while ( _Thread_Get_CPU( victim_user ) != cpu );
1409 _Scheduler_SMP_Extract_from_scheduled( context, victim_node );
1410 victim_owner = _Scheduler_Node_get_owner( victim_node );
1412 if ( !victim_owner->
is_idle ) {
1415 _Scheduler_Release_idle_thread(
1418 _Scheduler_SMP_Release_idle_thread
1420 idle = _Scheduler_SMP_Get_idle_thread( &self->Base );
1421 idle_node = _Thread_Scheduler_get_home_node( idle );
1422 ( *extract_from_ready )( &
self->Base, idle_node );
1423 _Scheduler_SMP_Preempt(
1427 _Scheduler_SMP_Allocate_processor_exact
1433 insert_priority = _Scheduler_SMP_Node_priority( victim_node );
1435 ( *enqueue )(
context, victim_node, insert_priority );
1438 _Assert( victim_owner == victim_user );
1439 _Assert( _Scheduler_Node_get_idle( victim_node ) ==
NULL );
1440 idle = victim_owner;
1441 _Scheduler_SMP_Exctract_idle_thread( idle );
1447 static inline void _Scheduler_SMP_Set_affinity(
1452 Scheduler_SMP_Set_affinity set_affinity,
1453 Scheduler_SMP_Extract extract_from_ready,
1454 Scheduler_SMP_Get_highest_ready get_highest_ready,
1455 Scheduler_SMP_Move move_from_ready_to_scheduled,
1456 Scheduler_SMP_Enqueue enqueue,
1457 Scheduler_SMP_Allocate_processor allocate_processor
1463 node_state = _Scheduler_SMP_Node_state( node );
1464 insert_priority = _Scheduler_SMP_Node_priority( node );
1468 _Scheduler_SMP_Extract_from_scheduled( context, node );
1469 _Scheduler_SMP_Preempt_and_schedule_highest_ready(
1472 _Thread_Get_CPU( thread ),
1475 move_from_ready_to_scheduled,
1478 ( *set_affinity )(
context, node, arg );
1479 ( *enqueue )(
context, node, insert_priority );
1481 ( *extract_from_ready )(
context, node );
1482 ( *set_affinity )(
context, node, arg );
1483 ( *enqueue )(
context, node, insert_priority );
1486 ( *set_affinity )(
context, node, arg );
RTEMS_INLINE_ROUTINE void _Chain_Append_unprotected(Chain_Control *the_chain, Chain_Node *the_node)
Append a node (unprotected).
Definition: chainimpl.h:679
Scheduler context specialization for SMP schedulers.
Definition: schedulersmp.h:44
RTEMS_INLINE_ROUTINE void _Chain_Insert_ordered_unprotected(Chain_Control *the_chain, Chain_Node *to_insert, const void *left, Chain_Node_order order)
Inserts a node into the chain according to the order relation.
Definition: chainimpl.h:860
Inlined Routines Associated with the Manipulation of the Priority-Based Scheduling Structures...
This scheduler node is blocked.
Definition: schedulersmp.h:74
Scheduler context.
Definition: scheduler.h:249
Priority_Control priority
The current priority of thread owning this node.
Definition: schedulersmp.h:112
Thread_Scheduler_control Scheduler
Scheduler related control.
Definition: thread.h:767
RTEMS_INLINE_ROUTINE Chain_Node * _Chain_Next(const Chain_Node *the_node)
Return pointer the next node from this node.
Definition: chainimpl.h:324
RTEMS_INLINE_ROUTINE void _Chain_Extract_unprotected(Chain_Node *the_node)
Extract this node (unprotected).
Definition: chainimpl.h:557
#define _ISR_Get_level()
Return current interrupt level.
Definition: isrlevel.h:125
RTEMS_INLINE_ROUTINE void _Chain_Initialize_empty(Chain_Control *the_chain)
Initialize this chain as empty.
Definition: chainimpl.h:504
Scheduler_SMP_Node_state state
The state of this node.
Definition: schedulersmp.h:107
#define SCHEDULER_PRIORITY_PURIFY(priority)
Clears the priority append indicator bit.
Definition: schedulerimpl.h:52
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:66
RTEMS_INLINE_ROUTINE bool _Chain_Is_empty(const Chain_Control *the_chain)
Is the chain empty.
Definition: chainimpl.h:390
RTEMS_INLINE_ROUTINE Chain_Node * _Chain_First(const Chain_Control *the_chain)
Return pointer to chain's first node.
Definition: chainimpl.h:257
Per CPU Core Structure.
Definition: percpu.h:290
Chain_Node Node
Definition: objectdata.h:41
Objects_Control Object
Definition: thread.h:730
This scheduler node is ready.
Definition: schedulersmp.h:92
The scheduler node is scheduled.
Definition: schedulersmp.h:84
Scheduler node specialization for SMP schedulers.
Definition: schedulersmp.h:98
RTEMS_INLINE_ROUTINE Chain_Node * _Chain_Tail(Chain_Control *the_chain)
Return pointer to chain tail.
Definition: chainimpl.h:224
bool(* Chain_Node_order)(const void *left, const Chain_Node *right)
Chain node order.
Definition: chainimpl.h:840
Interface to Kernel Print Methods.
struct _Thread_Control * heir
This is the heir thread for this processor.
Definition: percpu.h:378
Scheduler_Node Base
Basic scheduler node.
Definition: schedulersmp.h:102
unsigned context
Definition: tlb.h:108
Scheduler control.
Definition: scheduler.h:266
Scheduler node for per-thread data.
Definition: schedulernode.h:65
RTEMS_INLINE_ROUTINE Chain_Node * _Chain_Get_first_unprotected(Chain_Control *the_chain)
Get the first node (unprotected).
Definition: chainimpl.h:591
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
RTEMS_INLINE_ROUTINE const Chain_Node * _Chain_Immutable_tail(const Chain_Control *the_chain)
Return pointer to immutable chain tail.
Definition: chainimpl.h:240
RTEMS_INLINE_ROUTINE Chain_Node * _Chain_Last(const Chain_Control *the_chain)
Return pointer to chain's last node.
Definition: chainimpl.h:291
#define SCHEDULER_PRIORITY_APPEND(priority)
Returns the priority control with the append indicator bit set.
Definition: schedulerimpl.h:58
RTEMS_INLINE_ROUTINE void _Chain_Prepend_unprotected(Chain_Control *the_chain, Chain_Node *the_node)
Prepend a node (unprotected).
Definition: chainimpl.h:728
#define NULL
Requests a GPIO pin group configuration.
Definition: bestcomm_api.h:77
Scheduler_SMP_Node_state
SMP scheduler node states.
Definition: schedulersmp.h:68
bool is_idle
Definition: thread.h:792