42 static inline bool _Scheduler_EDF_SMP_Priority_less_equal(
55 prio_left = *the_left;
58 return prio_left <= prio_right;
64 _Scheduler_EDF_SMP_Get_context( scheduler );
84 static inline void _Scheduler_EDF_SMP_Do_update(
105 static inline bool _Scheduler_EDF_SMP_Overall_less(
120 _Scheduler_EDF_SMP_Challenge_highest_ready(
123 RBTree_Control *ready_queue
131 if ( _Scheduler_EDF_SMP_Overall_less( other, highest_ready ) ) {
135 return highest_ready;
138 static inline Scheduler_Node *_Scheduler_EDF_SMP_Get_highest_ready(
150 self = _Scheduler_EDF_SMP_Get_self( context );
153 _Assert( highest_ready != NULL );
165 highest_ready = _Scheduler_EDF_SMP_Challenge_highest_ready(
168 &self->Ready[ rqi ].Queue
175 while ( next != tail ) {
179 highest_ready = _Scheduler_EDF_SMP_Challenge_highest_ready(
188 return &highest_ready->Base.
Base;
191 static inline void _Scheduler_EDF_SMP_Set_scheduled(
197 self->Ready[ _Per_CPU_Get_index( cpu ) + 1 ].scheduled = scheduled;
205 return self->Ready[ rqi ].scheduled;
208 static inline Scheduler_Node *_Scheduler_EDF_SMP_Get_lowest_scheduled(
216 filter = _Scheduler_EDF_SMP_Node_downcast( filter_base );
223 self = _Scheduler_EDF_SMP_Get_self( context );
224 node = _Scheduler_EDF_SMP_Get_scheduled(
self, rqi );
228 return &node->Base.
Base;
235 static inline void _Scheduler_EDF_SMP_Insert_ready(
245 int generation_index;
249 self = _Scheduler_EDF_SMP_Get_self( context );
250 node = _Scheduler_EDF_SMP_Node_downcast( node_base );
253 increment = ( generation_index << 1 ) - 1;
254 ready_queue = &
self->Ready[ rqi ];
256 generation =
self->generations[ generation_index ];
258 self->generations[ generation_index ] = generation + increment;
265 _Scheduler_EDF_SMP_Priority_less_equal
271 scheduled = _Scheduler_EDF_SMP_Get_scheduled(
self, rqi );
279 static inline void _Scheduler_EDF_SMP_Extract_from_scheduled(
289 self = _Scheduler_EDF_SMP_Get_self( context );
290 node = _Scheduler_EDF_SMP_Node_downcast( node_to_extract );
295 ready_queue = &
self->Ready[ rqi ];
302 static inline void _Scheduler_EDF_SMP_Extract_from_ready(
312 self = _Scheduler_EDF_SMP_Get_self( context );
313 node = _Scheduler_EDF_SMP_Node_downcast( node_to_extract );
315 ready_queue = &
self->Ready[ rqi ];
330 static inline void _Scheduler_EDF_SMP_Move_from_scheduled_to_ready(
339 _Scheduler_EDF_SMP_Insert_ready(
346 static inline void _Scheduler_EDF_SMP_Move_from_ready_to_scheduled(
353 _Scheduler_EDF_SMP_Extract_from_ready( context, ready_to_scheduled );
363 static inline void _Scheduler_EDF_SMP_Allocate_processor(
375 self = _Scheduler_EDF_SMP_Get_self( context );
376 scheduled = _Scheduler_EDF_SMP_Node_downcast( scheduled_base );
383 ready_queue = &
self->Ready[ rqi ];
390 desired_cpu = _Per_CPU_Get_by_index( rqi - 1 );
392 if ( victim_cpu != desired_cpu ) {
395 node = _Scheduler_EDF_SMP_Get_scheduled(
self, rqi );
397 _Scheduler_EDF_SMP_Set_scheduled(
self, node, victim_cpu );
404 victim_cpu = desired_cpu;
408 _Scheduler_EDF_SMP_Set_scheduled(
self, scheduled, victim_cpu );
411 &scheduled->Base.
Base,
429 _Scheduler_EDF_SMP_Extract_from_scheduled,
430 _Scheduler_EDF_SMP_Extract_from_ready,
431 _Scheduler_EDF_SMP_Get_highest_ready,
432 _Scheduler_EDF_SMP_Move_from_ready_to_scheduled,
433 _Scheduler_EDF_SMP_Allocate_processor
437 static inline bool _Scheduler_EDF_SMP_Enqueue(
448 _Scheduler_EDF_SMP_Insert_ready,
450 _Scheduler_EDF_SMP_Move_from_scheduled_to_ready,
451 _Scheduler_EDF_SMP_Get_lowest_scheduled,
452 _Scheduler_EDF_SMP_Allocate_processor
456 static inline bool _Scheduler_EDF_SMP_Enqueue_scheduled(
467 _Scheduler_EDF_SMP_Extract_from_ready,
468 _Scheduler_EDF_SMP_Get_highest_ready,
469 _Scheduler_EDF_SMP_Insert_ready,
471 _Scheduler_EDF_SMP_Move_from_ready_to_scheduled,
472 _Scheduler_EDF_SMP_Allocate_processor
488 _Scheduler_EDF_SMP_Do_update,
489 _Scheduler_EDF_SMP_Enqueue
493 static inline bool _Scheduler_EDF_SMP_Do_ask_for_help(
504 _Scheduler_EDF_SMP_Insert_ready,
506 _Scheduler_EDF_SMP_Move_from_scheduled_to_ready,
507 _Scheduler_EDF_SMP_Get_lowest_scheduled,
508 _Scheduler_EDF_SMP_Allocate_processor
524 _Scheduler_EDF_SMP_Extract_from_ready,
525 _Scheduler_EDF_SMP_Do_update,
526 _Scheduler_EDF_SMP_Enqueue,
527 _Scheduler_EDF_SMP_Enqueue_scheduled,
528 _Scheduler_EDF_SMP_Do_ask_for_help
540 return _Scheduler_EDF_SMP_Do_ask_for_help( context, the_thread, node );
555 _Scheduler_EDF_SMP_Extract_from_ready
573 _Scheduler_EDF_SMP_Extract_from_ready,
574 _Scheduler_EDF_SMP_Get_highest_ready,
575 _Scheduler_EDF_SMP_Move_from_ready_to_scheduled,
576 _Scheduler_EDF_SMP_Allocate_processor
580 static inline void _Scheduler_EDF_SMP_Register_idle(
589 self = _Scheduler_EDF_SMP_Get_self( context );
590 idle = _Scheduler_EDF_SMP_Node_downcast( idle_base );
591 _Scheduler_EDF_SMP_Set_scheduled(
self, idle, cpu );
604 _Scheduler_EDF_SMP_Has_ready,
605 _Scheduler_EDF_SMP_Enqueue_scheduled,
606 _Scheduler_EDF_SMP_Register_idle
620 _Scheduler_EDF_SMP_Extract_from_ready,
621 _Scheduler_EDF_SMP_Enqueue
637 _Scheduler_EDF_SMP_Extract_from_ready,
638 _Scheduler_EDF_SMP_Enqueue,
639 _Scheduler_EDF_SMP_Enqueue_scheduled
643 static inline void _Scheduler_EDF_SMP_Do_set_affinity(
652 node = _Scheduler_EDF_SMP_Node_downcast( node_base );
671 _Scheduler_EDF_SMP_Register_idle
686 node = _Scheduler_EDF_SMP_Node_downcast( node_base );
687 rqi = (uint8_t) _Per_CPU_Get_index( cpu ) + 1;
693 node = _Scheduler_EDF_SMP_Node_downcast( node_base );
709 node = _Scheduler_EDF_SMP_Node_downcast( node_base );
723 const Processor_mask *affinity
728 Processor_mask local_affinity;
744 node = _Scheduler_EDF_SMP_Node_downcast( node_base );
753 _Scheduler_EDF_SMP_Do_set_affinity,
754 _Scheduler_EDF_SMP_Extract_from_ready,
755 _Scheduler_EDF_SMP_Get_highest_ready,
756 _Scheduler_EDF_SMP_Move_from_ready_to_scheduled,
757 _Scheduler_EDF_SMP_Enqueue,
758 _Scheduler_EDF_SMP_Allocate_processor
#define SCHEDULER_PRIORITY_IS_APPEND(priority)
Returns true, if the item should be appended to its priority group, otherwise returns false and the i...
uint8_t ready_queue_index
The ready queue index depending on the processor affinity and pinning of the thread.
uint8_t pinning_ready_queue_index
Ready queue index according to thread pinning.
RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_zero(const Processor_mask *mask)
Checks if the mask is zero, also considers CPU_MAXIMUM_PROCESSORS.
static __inline__ Chain_Node * _Chain_First(const Chain_Control *the_chain)
Returns pointer to chain's first node.
static void _Scheduler_SMP_Add_processor(Scheduler_Context *context, Thread_Control *idle, Scheduler_SMP_Has_ready has_ready, Scheduler_SMP_Enqueue enqueue_scheduled, Scheduler_SMP_Register_idle register_idle)
Adds the idle thread to the processor.
RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_equal(const Processor_mask *a, const Processor_mask *b)
Checks if the processor sets a and b are equal.
uint64_t Priority_Control
The thread priority control.
static __inline__ bool _RBTree_Insert_inline(RBTree_Control *the_rbtree, RBTree_Node *the_node, const void *key, bool(*less)(const void *, const RBTree_Node *))
Inserts the node into the red-black tree.
void _Scheduler_EDF_SMP_Initialize(const Scheduler_Control *scheduler)
Initializes the context of the scheduler control.
static __inline__ bool _Chain_Is_node_off_chain(const Chain_Node *node)
Checks if the node is off chain.
static void _Scheduler_SMP_Extract_from_scheduled(Scheduler_Context *context, Scheduler_Node *node)
Extracts a scheduled node from the scheduled nodes.
static void _Scheduler_SMP_Withdraw_node(Scheduler_Context *context, Thread_Control *thread, Scheduler_Node *node, Thread_Scheduler_state next_state, Scheduler_SMP_Extract extract_from_ready, Scheduler_SMP_Get_highest_ready get_highest_ready, Scheduler_SMP_Move move_from_ready_to_scheduled, Scheduler_SMP_Allocate_processor allocate_processor)
Withdraws the node.
static Scheduler_SMP_Node_state _Scheduler_SMP_Node_state(const Scheduler_Node *node)
Gets the state of the node.
#define SCHEDULER_PRIORITY_APPEND(priority)
Returns the priority control with the append indicator bit set.
static __inline__ void _Chain_Initialize_node(Chain_Node *the_node)
Initializes a chain node.
union Scheduler_Node::@18 Node
Chain node for usage in various scheduler data structures.
bool _Scheduler_EDF_SMP_Set_affinity(const Scheduler_Control *scheduler, Thread_Control *thread, Scheduler_Node *node_base, const Processor_mask *affinity)
Checks if the processor set of the scheduler is the subset of the affinity set.
Priority_Control priority
The current priority of thread owning this node.
static void _Scheduler_SMP_Reconsider_help_request(Scheduler_Context *context, Thread_Control *thread, Scheduler_Node *node, Scheduler_SMP_Extract extract_from_ready)
Reconsiders help request.
static bool _Scheduler_SMP_Ask_for_help(Scheduler_Context *context, Thread_Control *thread, Scheduler_Node *node, Chain_Node_order order, Scheduler_SMP_Insert insert_ready, Scheduler_SMP_Insert insert_scheduled, Scheduler_SMP_Move move_from_scheduled_to_ready, Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled, Scheduler_SMP_Allocate_processor allocate_processor)
Asks for help.
void _Scheduler_EDF_SMP_Unblock(const Scheduler_Control *scheduler, Thread_Control *thread, Scheduler_Node *node)
Unblocks the thread.
static bool _Scheduler_SMP_Priority_less_equal(const void *to_insert, const Chain_Node *next)
Checks if to_insert is less or equal than the priority of the chain node.
RBTree_Node * _RBTree_Minimum(const RBTree_Control *the_rbtree)
Returns the minimum node of the red-black tree.
static Thread_Control * _Scheduler_SMP_Remove_processor(Scheduler_Context *context, Per_CPU_Control *cpu, Scheduler_SMP_Extract extract_from_ready, Scheduler_SMP_Enqueue enqueue)
Removes an idle thread from the processor.
RTEMS_INLINE_ROUTINE uint32_t _Processor_mask_Find_last_set(const Processor_mask *a)
Finds the last set of the processor mask.
void _Scheduler_EDF_SMP_Update_priority(const Scheduler_Control *scheduler, Thread_Control *thread, Scheduler_Node *node)
Updates the priority of the node.
static void _Scheduler_SMP_Block(Scheduler_Context *context, Thread_Control *thread, Scheduler_Node *node, Scheduler_SMP_Extract extract_from_scheduled, Scheduler_SMP_Extract extract_from_ready, Scheduler_SMP_Get_highest_ready get_highest_ready, Scheduler_SMP_Move move_from_ready_to_scheduled, Scheduler_SMP_Allocate_processor allocate_processor)
Blocks the thread.
void _Scheduler_EDF_SMP_Pin(const Scheduler_Control *scheduler, Thread_Control *thread, Scheduler_Node *node_base, struct Per_CPU_Control *cpu)
Pin thread operation.
static void _Scheduler_SMP_Set_affinity(Scheduler_Context *context, Thread_Control *thread, Scheduler_Node *node, void *arg, Scheduler_SMP_Set_affinity set_affinity, Scheduler_SMP_Extract extract_from_ready, Scheduler_SMP_Get_highest_ready get_highest_ready, Scheduler_SMP_Move move_from_ready_to_scheduled, Scheduler_SMP_Enqueue enqueue, Scheduler_SMP_Allocate_processor allocate_processor)
Sets the affinity of the node.
#define RTEMS_CONTAINER_OF(_m, _type, _member_name)
Returns the pointer to the container of a specified member pointer.
static __inline__ void _Chain_Append_unprotected(Chain_Control *the_chain, Chain_Node *the_node)
Appends a node (unprotected).
static void _Scheduler_SMP_Node_initialize(const Scheduler_Control *scheduler, Scheduler_SMP_Node *node, Thread_Control *thread, Priority_Control priority)
Initializes the scheduler smp node.
static __inline__ bool _RBTree_Is_empty(const RBTree_Control *the_rbtree)
Checks if the RBTree is empty.
This scheduler node is blocked.
Thread_Scheduler_state
The thread state with respect to the scheduler.
RTEMS_INLINE_ROUTINE void _Processor_mask_And(Processor_mask *a, const Processor_mask *b, const Processor_mask *c)
Performs a bitwise a = b & c.
static __inline__ Chain_Node * _Chain_Next(const Chain_Node *the_node)
Returns pointer to the next node from this node.
void _Scheduler_EDF_SMP_Block(const Scheduler_Control *scheduler, Thread_Control *thread, Scheduler_Node *node)
Blocks the thread.
static Priority_Control _Scheduler_SMP_Node_priority(const Scheduler_Node *node)
Gets the priority of the node.
Processor_mask Processors
Lock to protect this scheduler instance.
static bool _Scheduler_SMP_Enqueue_scheduled(Scheduler_Context *context, Scheduler_Node *const node, Priority_Control insert_priority, Chain_Node_order order, Scheduler_SMP_Extract extract_from_ready, Scheduler_SMP_Get_highest_ready get_highest_ready, Scheduler_SMP_Insert insert_ready, Scheduler_SMP_Insert insert_scheduled, Scheduler_SMP_Move move_from_ready_to_scheduled, Scheduler_SMP_Allocate_processor allocate_processor)
Enqueues a scheduled node according to the specified order function.
static __inline__ void _Chain_Extract_unprotected(Chain_Node *the_node)
Extracts this node (unprotected).
Scheduler node specialization for SMP schedulers.
SMP Scheduler Implementation.
static void _Scheduler_SMP_Do_start_idle(Scheduler_Context *context, Thread_Control *idle, Per_CPU_Control *cpu, Scheduler_SMP_Register_idle register_idle)
Starts the idle thread on the given processor.
static void _Scheduler_SMP_Yield(Scheduler_Context *context, Thread_Control *thread, Scheduler_Node *node, Scheduler_SMP_Extract extract_from_ready, Scheduler_SMP_Enqueue enqueue, Scheduler_SMP_Enqueue enqueue_scheduled)
Performs a yield and asks for help if necessary.
void _Scheduler_EDF_SMP_Yield(const Scheduler_Control *scheduler, Thread_Control *thread, Scheduler_Node *node)
Performs the yield of a thread.
int64_t generation
Generation number to ensure FIFO/LIFO order for threads of the same priority across different ready q...
Scheduler_Node Base
Basic scheduler node.
static bool _Scheduler_SMP_Enqueue(Scheduler_Context *context, Scheduler_Node *node, Priority_Control insert_priority, Chain_Node_order order, Scheduler_SMP_Insert insert_ready, Scheduler_SMP_Insert insert_scheduled, Scheduler_SMP_Move move_from_scheduled_to_ready, Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled, Scheduler_SMP_Allocate_processor allocate_processor)
Enqueues a node according to the specified order function.
RBTree_Control Queue
The ready threads of the corresponding affinity.
static void _Scheduler_SMP_Node_update_priority(Scheduler_SMP_Node *node, Priority_Control new_priority)
Updates the priority of the node to the new priority.
void _Scheduler_EDF_SMP_Withdraw_node(const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node, Thread_Scheduler_state next_state)
Withdraws node operation.
static Scheduler_SMP_Node * _Scheduler_SMP_Node_downcast(Scheduler_Node *node)
Gets the scheduler smp node.
static __inline__ void _Chain_Initialize_empty(Chain_Control *the_chain)
Initializes this chain as empty.
void _Scheduler_EDF_SMP_Add_processor(const Scheduler_Control *scheduler, Thread_Control *idle)
Adds processor.
static void _Scheduler_SMP_Unblock(Scheduler_Context *context, Thread_Control *thread, Scheduler_Node *node, Scheduler_SMP_Update update, Scheduler_SMP_Enqueue enqueue)
Unblocks the thread.
static __inline__ void _RBTree_Initialize_node(RBTree_Node *the_node)
Initializes a red-black tree node.
static Scheduler_Node * _Scheduler_SMP_Get_lowest_scheduled(Scheduler_Context *context, Scheduler_Node *filter)
Returns the lowest member of the scheduled nodes.
Processor_mask _SMP_Online_processors
Set of online processors.
Scheduler node for per-thread data.
static __inline__ Scheduler_Context * _Scheduler_Get_context(const Scheduler_Control *scheduler)
Gets the context of the scheduler.
void _Scheduler_EDF_SMP_Unpin(const Scheduler_Control *scheduler, Thread_Control *thread, Scheduler_Node *node_base, struct Per_CPU_Control *cpu)
Unpin thread operation.
static void _Scheduler_SMP_Insert_scheduled(Scheduler_Context *context, Scheduler_Node *node_to_insert, Priority_Control priority_to_insert)
Inserts the node with the given priority into the scheduled nodes.
static void _Scheduler_SMP_Allocate_processor_exact(Scheduler_Context *context, Scheduler_Node *scheduled, Scheduler_Node *victim, Per_CPU_Control *victim_cpu)
Allocates the cpu for the scheduled thread.
static __inline__ void _Chain_Set_off_chain(Chain_Node *node)
Sets off chain.
void _Scheduler_EDF_SMP_Node_initialize(const Scheduler_Control *scheduler, Scheduler_Node *node, Thread_Control *the_thread, Priority_Control priority)
Initializes the node with the given priority.
void _RBTree_Extract(RBTree_Control *the_rbtree, RBTree_Node *the_node)
Extracts (removes) the node from the red-black tree.
Chain_Node Node
Chain node for Scheduler_SMP_Context::Affine_queues.
Thread_Control * _Scheduler_EDF_SMP_Remove_processor(const Scheduler_Control *scheduler, Per_CPU_Control *cpu)
Removes an idle thread from the given cpu.
Chain_Node Chain
The node for Thread_Control::Scheduler::Scheduler_nodes.
void _Scheduler_EDF_SMP_Reconsider_help_request(const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node)
Reconsiders help operation.
static __inline__ const Chain_Node * _Chain_Immutable_tail(const Chain_Control *the_chain)
Returns pointer to immutable chain tail.
static void _Scheduler_SMP_Update_priority(Scheduler_Context *context, Thread_Control *thread, Scheduler_Node *node, Scheduler_SMP_Extract extract_from_ready, Scheduler_SMP_Update update, Scheduler_SMP_Enqueue enqueue, Scheduler_SMP_Enqueue enqueue_scheduled, Scheduler_SMP_Ask_for_help ask_for_help)
Updates the priority of the node and the position in the queues it is in.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
void _Scheduler_EDF_SMP_Start_idle(const Scheduler_Control *scheduler, Thread_Control *idle, Per_CPU_Control *cpu)
Starts an idle thread.
static void _Scheduler_SMP_Initialize(Scheduler_SMP_Context *self)
Initializes the scheduler smp context.
uint8_t affinity_ready_queue_index
Ready queue index according to thread affinity.
bool _Scheduler_EDF_SMP_Ask_for_help(const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node)
Asks for help operation.