22 #ifndef _RTEMS_SCORE_SCHEDULERIMPL_H 23 #define _RTEMS_SCORE_SCHEDULERIMPL_H 29 #include <rtems/score/status.h> 103 #if defined(RTEMS_SMP) 124 #if defined(RTEMS_SMP) 148 #if defined(RTEMS_SMP) 159 #if defined(RTEMS_SMP) 177 #if defined(RTEMS_SMP) 178 void _Scheduler_Request_ask_for_help(
Thread_Control *the_thread );
193 _Assert( _Thread_State_is_owner( the_thread ) );
196 _Scheduler_Request_ask_for_help( the_thread );
272 #if defined(RTEMS_SMP) 282 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
295 while ( node != tail ) {
296 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
338 #if defined(RTEMS_SMP) 339 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE(
369 #if defined(RTEMS_SMP) 383 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
395 }
while ( node != tail );
408 #if defined(RTEMS_SMP) 419 int sticky_level_change
431 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
450 while ( node != tail ) {
451 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
617 if ( scheduler != NULL && executing != NULL ) {
655 #if defined(RTEMS_SMP) 659 cpu = _Per_CPU_Get_by_index( cpu_index );
662 return scheduler_of_cpu == scheduler;
682 #if defined(RTEMS_SMP) 685 return &_Processor_mask_The_one_and_only;
720 const Processor_mask *affinity
742 const cpu_set_t *cpuset
770 ( *extract )( scheduler, the_thread, node );
775 ( *schedule )( scheduler, the_thread, true );
790 #if defined(RTEMS_SMP) 811 OBJECTS_FAKE_OBJECTS_API,
812 OBJECTS_FAKE_OBJECTS_SCHEDULERS,
814 (uint16_t) ( scheduler_index + 1 )
829 return id - minimum_id;
868 #if defined(RTEMS_SMP) 964 SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE,
965 SCHEDULER_TRY_TO_SCHEDULE_DO_IDLE_EXCHANGE,
966 SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK
1012 action = SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE;
1026 action = SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK;
1028 action = SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK;
1029 }
else if ( idle != NULL ) {
1030 action = SCHEDULER_TRY_TO_SCHEDULE_DO_IDLE_EXCHANGE;
1062 if ( idle != NULL ) {
1067 ( *release_idle_thread )( context, idle );
1087 uses_idle->
idle = NULL;
1133 if ( sticky_level > 0 ) {
1178 ( *release_idle_thread )( context, idle );
1210 if ( is_scheduled ) {
1242 if ( heir != new_heir && ( heir->
is_preemptible || force_dispatch ) ) {
1243 #if defined(RTEMS_SMP) 1254 _Thread_Heir = new_heir;
1255 _Thread_Dispatch_necessary =
true;
1278 #if defined(RTEMS_SMP) 1285 return STATUS_RESOURCE_IN_USE;
1290 &old_scheduler_node->
Wait.Priority,
1296 #
if defined(RTEMS_SMP)
1302 &old_scheduler_node->
Wait.Priority,
1306 return STATUS_RESOURCE_IN_USE;
1309 #if defined(RTEMS_SMP) 1329 &old_scheduler_node->
Wait.Priority,
1333 return STATUS_UNSATISFIED;
1343 new_scheduler_node = old_scheduler_node;
1349 &new_scheduler_node->
Wait.Priority,
1353 #if defined(RTEMS_SMP) 1354 if ( old_scheduler != new_scheduler ) {
1387 return STATUS_SUCCESSFUL;
1393 return STATUS_SUCCESSFUL;
const struct _Scheduler_Control * home_scheduler
The home scheduler of this thread.
int sticky_level
The sticky level determines if this scheduler node should use an idle thread in case this node is sch...
static __inline__ const Scheduler_Control * _Scheduler_Get_by_CPU(const Per_CPU_Control *cpu)
Gets the scheduler for the cpu.
static __inline__ Chain_Node * _Chain_First(const Chain_Control *the_chain)
Returns pointer to chain's first node.
static __inline__ void _Priority_Initialize_one(Priority_Aggregation *aggregation, Priority_Node *node)
Initializes the priority aggregation with the given information.
void _Thread_Scheduler_process_requests(Thread_Control *the_thread)
Process the thread's scheduler requests.
static __inline__ void _Scheduler_Schedule(Thread_Control *the_thread)
General scheduling decision.
Scheduler_Try_to_schedule_action
This enumeration defines what a scheduler should do with a node which could be scheduled.
bool _Scheduler_Set_affinity(Thread_Control *the_thread, size_t cpusetsize, const cpu_set_t *cpuset)
Sets the thread's scheduler's affinity.
uint64_t Priority_Control
The thread priority control.
static __inline__ void _Scheduler_Acquire_critical(const Scheduler_Control *scheduler, ISR_lock_Context *lock_context)
Acquires the scheduler instance inside a critical section (interrupts disabled).
static __inline__ void _Scheduler_Exchange_idle_thread(Scheduler_Node *needs_idle, Scheduler_Node *uses_idle, Thread_Control *idle)
Exchanges an idle thread from the scheduler node that uses it right now to another scheduler node...
Thread_Wait_information Wait
Thread queue context for the thread queue methods.
static __inline__ Scheduler_Node * _Thread_Scheduler_get_node_by_index(const Thread_Control *the_thread, size_t scheduler_index)
Gets the thread's scheduler node by index.
The priority node to build up a priority aggregation.
static __inline__ bool _System_state_Is_up(System_state_Codes state)
Checks if the state is up.
struct _Thread_Control * executing
This is the thread executing on this processor.
static __inline__ bool _Thread_Is_heir(const Thread_Control *the_thread)
Checks if the thread is the heir.
static __inline__ const Scheduler_Control * _Thread_Scheduler_get_home(const Thread_Control *the_thread)
Gets the home scheduler of the thread.
void(* block)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *)
RTEMS_INLINE_ROUTINE uint32_t _Processor_mask_Count(const Processor_mask *a)
Gets the number of set bits in the processor mask.
static __inline__ Status_Control _Scheduler_Set(const Scheduler_Control *new_scheduler, Thread_Control *the_thread, Priority_Control priority)
Sets a new scheduler.
static __inline__ Priority_Control _Scheduler_Map_priority(const Scheduler_Control *scheduler, Priority_Control priority)
Maps a thread priority from the user domain to the scheduler domain.
Thread_Start_information Start
static __inline__ const Processor_mask * _SMP_Get_online_processors(void)
Gets all online processors.
Thread_Control *(* Scheduler_Get_idle_thread)(Scheduler_Context *context)
Gets an idle thread from the scheduler instance.
static __inline__ void _Scheduler_Cancel_job(Thread_Control *the_thread, Priority_Node *priority_node, Thread_queue_Context *queue_context)
Cancels a job of a thread with respect to the scheduler.
This thread is scheduled with respect to the scheduler.
Priority_Control priority
The priority value of this node.
This thread is ready with respect to the scheduler.
static __inline__ void _Scheduler_Node_initialize(const Scheduler_Control *scheduler, Scheduler_Node *node, Thread_Control *the_thread, Priority_Control priority)
Initializes a scheduler node.
Thread_Scheduler_control Scheduler
Scheduler related control.
Priority_Control(* unmap_priority)(const Scheduler_Control *, Priority_Control)
static __inline__ void _Scheduler_Start_idle(const Scheduler_Control *scheduler, Thread_Control *the_thread, Per_CPU_Control *cpu)
Starts the idle thread for a particular processor.
bool is_non_preempt_mode_supported
True if the non-preempt mode for threads is supported by the scheduler, otherwise false...
void(* withdraw_node)(const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node, Thread_Scheduler_state next_state)
Withdraw node operation.
void(* yield)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *)
bool(* set_affinity)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *, const Processor_mask *)
static __inline__ void _Priority_Plain_extract(Priority_Aggregation *aggregation, Priority_Node *node)
Extracts the priority node from the aggregation.
void(* node_initialize)(const Scheduler_Control *, Scheduler_Node *, Thread_Control *, Priority_Control)
struct Scheduler_Node::@19 Thread
Block to register and manage this scheduler node in the thread control block of the owner of this sch...
void _Scheduler_Handler_initialization(void)
Initializes the scheduler to the policy chosen by the user.
static __inline__ void _Scheduler_Update_heir(Thread_Control *new_heir, bool force_dispatch)
Updates the heir.
void(* node_destroy)(const Scheduler_Control *, Scheduler_Node *)
struct _Thread_Control * idle
The idle thread claimed by this node in case the sticky level is greater than zero and the thread is ...
size_t helping_nodes
Count of nodes scheduler nodes minus one.
Information for the Assert Handler.
static __inline__ void _Scheduler_Tick(const Per_CPU_Control *cpu)
Scheduler method invoked at each clock tick.
Chain_Node Wait_node
Node to add this scheduler node to Thread_Control::Scheduler::Wait_nodes.
static __inline__ void _Scheduler_Thread_change_state(Thread_Control *the_thread, Thread_Scheduler_state new_state)
Changes the threads state to the given new state.
Processor_mask Affinity
The thread processor affinity set.
static __inline__ void _Scheduler_Release_critical(const Scheduler_Control *scheduler, ISR_lock_Context *lock_context)
Releases the scheduler instance inside a critical section (interrupts disabled).
static __inline__ uint32_t _Scheduler_Get_processor_count(const Scheduler_Control *scheduler)
Gets the number of processors of the scheduler.
This thread is blocked with respect to the scheduler.
static __inline__ Priority_Control _Scheduler_Unmap_priority(const Scheduler_Control *scheduler, Priority_Control priority)
Unmaps a thread priority from the scheduler domain to the user domain.
static __inline__ Per_CPU_Control * _Scheduler_Block_node(Scheduler_Context *context, Thread_Control *thread, Scheduler_Node *node, bool is_scheduled, Scheduler_Get_idle_thread get_idle_thread)
Blocks this scheduler node.
void(* tick)(const Scheduler_Control *, Thread_Control *)
static __inline__ void _Thread_Scheduler_cancel_need_for_help(Thread_Control *the_thread, Per_CPU_Control *cpu)
Cancels the thread's need for help.
int pin_level
The thread pinning to current processor level.
Thread_Scheduler_state
The thread state with respect to the scheduler.
static __inline__ void _Scheduler_Set_idle_thread(Scheduler_Node *node, Thread_Control *idle)
Sets the scheduler node's idle thread.
static __inline__ void _Scheduler_Ask_for_help(Thread_Control *the_thread)
Registers an ask for help request if necessary.
static __inline__ Scheduler_Node * _Thread_Scheduler_get_home_node(const Thread_Control *the_thread)
Gets the scheduler's home node.
static __inline__ Chain_Node * _Chain_Next(const Chain_Node *the_node)
Returns pointer to the next node from this node.
static __inline__ void _Scheduler_Unblock(Thread_Control *the_thread)
Unblocks a thread with respect to the scheduler.
static __inline__ void _Thread_Set_CPU(Thread_Control *thread, Per_CPU_Control *cpu)
Sets the cpu of the thread's scheduler.
static __inline__ void _Scheduler_Priority_and_sticky_update(Thread_Control *the_thread, int sticky_level_change)
Changes the sticky level of the home scheduler node and propagates a priority change of a thread to t...
static __inline__ Thread_Control * _Scheduler_Node_get_owner(const Scheduler_Node *node)
Gets the owner of the node.
Processor_mask Processors
Lock to protect this scheduler instance.
static __inline__ void _Scheduler_Generic_block(const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node, void(*extract)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *), void(*schedule)(const Scheduler_Control *, Thread_Control *, bool))
Blocks the thread.
static __inline__ const Processor_mask * _Scheduler_Get_processors(const Scheduler_Control *scheduler)
Gets the processors of the scheduler.
static __inline__ bool _Chain_Has_only_one_node(const Chain_Control *the_chain)
Checks if this chain has only one node.
void(* schedule)(const Scheduler_Control *, Thread_Control *)
static __inline__ void _Chain_Extract_unprotected(Chain_Node *the_node)
Extracts this node (unprotected).
static __inline__ Thread_Control * _Scheduler_Node_get_idle(const Scheduler_Node *node)
Gets the idle thread of the node.
States_Control current_state
static __inline__ void _Scheduler_Discard_idle_thread(Scheduler_Context *context, Thread_Control *the_thread, Scheduler_Node *node, Scheduler_Release_idle_thread release_idle_thread)
Discard the idle thread from the scheduler node.
void(* unblock)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *)
void(* cancel_job)(const Scheduler_Control *, Thread_Control *, Priority_Node *, Thread_queue_Context *)
#define _ISR_lock_Acquire(_lock, _context)
Acquires an ISR lock inside an ISR disabled section.
const struct _Scheduler_Control * control
The scheduler control of the scheduler owning this processor.
static __inline__ void _Scheduler_Block(Thread_Control *the_thread)
Blocks a thread with respect to the scheduler.
static __inline__ void _Thread_Scheduler_acquire_critical(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Acquires the lock context in a critical section.
static __inline__ bool _Scheduler_Has_processor_ownership(const Scheduler_Control *scheduler, uint32_t cpu_index)
Checks if the scheduler of the cpu with the given index is equal to the given scheduler.
const Scheduler_Control _Scheduler_Table[]
This table contains the configured schedulers.
#define _ISR_lock_Release(_lock, _context)
Releases an ISR lock inside an ISR disabled section.
static __inline__ void _Thread_Scheduler_release_critical(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Releases the lock context in a critical section.
static __inline__ void _Priority_Node_set_priority(Priority_Node *node, Priority_Control priority)
Sets the priority of the priority node to the given priority.
bool _Scheduler_Get_affinity(Thread_Control *the_thread, size_t cpusetsize, cpu_set_t *cpuset)
Copies the thread's scheduler's affinity to the given cpuset.
static __inline__ void _Thread_queue_Context_clear_priority_updates(Thread_queue_Context *queue_context)
Clears the priority update count of the thread queue context.
Thread_Scheduler_state state
The current scheduler state of this thread.
static __inline__ bool _States_Is_ready(States_Control the_states)
Checks if the state is ready.
static __inline__ Thread_Control * _Scheduler_Release_idle_thread(Scheduler_Context *context, Scheduler_Node *node, Scheduler_Release_idle_thread release_idle_thread)
Releases an idle thread using this scheduler node.
static __inline__ bool _Scheduler_Is_non_preempt_mode_supported(const Scheduler_Control *scheduler)
Indicate if the thread non-preempt mode is supported by the scheduler.
const struct _Scheduler_Control * pinned_scheduler
The pinned scheduler of this thread.
void(* Scheduler_Release_idle_thread)(Scheduler_Context *context, Thread_Control *idle)
Releases an idle thread to the scheduler instance for reuse.
static __inline__ bool _Scheduler_Unblock_node(Scheduler_Context *context, Thread_Control *the_thread, Scheduler_Node *node, bool is_scheduled, Scheduler_Release_idle_thread release_idle_thread)
Unblocks this scheduler node.
static __inline__ bool _Thread_Is_executing(const Thread_Control *the_thread)
Checks if the thread is the currently executing thread.
static __inline__ Scheduler_Try_to_schedule_action _Scheduler_Try_to_schedule_node(Scheduler_Context *context, Scheduler_Node *node, const Thread_Control *idle, Scheduler_Get_idle_thread get_idle_thread)
Tries to schedule the scheduler node.
static __inline__ bool _Priority_Is_empty(const Priority_Aggregation *aggregation)
Checks if the priority aggregation is empty.
Chain_Control Scheduler_nodes
Scheduler nodes immediately available to the schedulers for this thread.
static __inline__ Objects_Id _Scheduler_Build_id(uint32_t scheduler_index)
Builds an object build id.
static __inline__ void _Chain_Initialize_one(Chain_Control *the_chain, Chain_Node *the_node)
Initializes this chain to contain exactly the specified node.
struct Scheduler_Node::@20 Wait
Thread wait support block.
Priority_Control(* map_priority)(const Scheduler_Control *, Priority_Control)
static __inline__ System_state_Codes _System_state_Get(void)
Gets the current system state.
static __inline__ Per_CPU_Control * _Thread_Get_CPU(const Thread_Control *thread)
Gets the cpu of the thread's scheduler.
#define _Objects_Local_node
The local MPCI node number.
static __inline__ void _Scheduler_Update_priority(Thread_Control *the_thread)
Propagates a priority change of a thread to the scheduler.
static __inline__ void _Scheduler_Node_set_priority(Scheduler_Node *node, Priority_Control new_priority, bool prepend_it)
Sets the priority of the node.
Priority Handler API Implementation.
void(* update_priority)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *)
static __inline__ const Scheduler_Control * _Scheduler_Node_get_scheduler(const Scheduler_Node *node)
Gets the scheduler of the node.
#define _Objects_Build_id(the_api, the_class, node, index)
Builds an object ID from its components.
static __inline__ void _Scheduler_Yield(Thread_Control *the_thread)
Scheduler yield with a particular thread.
Scheduler_Operations Operations
The scheduler operations.
const size_t _Scheduler_Count
This constant contains the count of configured schedulers.
Scheduler node for per-thread data.
static __inline__ Scheduler_Context * _Scheduler_Get_context(const Scheduler_Control *scheduler)
Gets the context of the scheduler.
Inlined Routines from the Thread Handler.
static __inline__ uint32_t _Scheduler_Get_index_by_id(Objects_Id id)
Gets the scheduler index from the given object build id.
static __inline__ void _Thread_Dispatch_update_heir(Per_CPU_Control *cpu_self, Per_CPU_Control *cpu_for_heir, Thread_Control *heir)
Updates the used cpu time for the heir and dispatches a new heir.
Chain_Control Wait_nodes
Scheduler nodes immediately available to the thread by its home scheduler and due to thread queue own...
RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_subset(const Processor_mask *big, const Processor_mask *small)
Checks if the processor set small is a subset of processor set big.
void(* start_idle)(const Scheduler_Control *, Thread_Control *, struct Per_CPU_Control *)
Scheduler_Context * context
Reference to a statically allocated scheduler context.
Local ISR lock context for acquire and release pairs.
#define RTEMS_INLINE_ROUTINE
Gives a hint to the compiler in a function declaration to inline this function.
static __inline__ Thread_Control * _Scheduler_Use_idle_thread(Scheduler_Context *context, Scheduler_Node *node, Per_CPU_Control *cpu, Scheduler_Get_idle_thread get_idle_thread)
Uses an idle thread for this scheduler node.
ISR_lock_Control Lock
Lock to protect the scheduler node change requests.
static __inline__ void _Scheduler_Release_job(Thread_Control *the_thread, Priority_Node *priority_node, uint64_t deadline, Thread_queue_Context *queue_context)
Releases a job of a thread with respect to the scheduler.
static __inline__ bool _Chain_Is_empty(const Chain_Control *the_chain)
Checks if the chain is empty.
Priority_Node Real_priority
The base priority of this thread in its home scheduler instance.
Constants and Structures Associated with the Scheduler.
static __inline__ bool _Scheduler_default_Set_affinity_body(const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node, const Processor_mask *affinity)
Checks if the affinity is a subset of the online processors.
static __inline__ void _Scheduler_Node_destroy(const Scheduler_Control *scheduler, Scheduler_Node *node)
Destroys a scheduler node.
union Scheduler_Node::@19::@22 Scheduler_node
Node to add this scheduler node to Thread_Control::Scheduler::Scheduler_nodes or a temporary remove l...
static __inline__ Thread_Control * _Scheduler_Node_get_user(const Scheduler_Node *node)
Gets the user of the node.
static __inline__ uint32_t _Scheduler_Get_index(const Scheduler_Control *scheduler)
Gets the index of the scheduler.
void(* release_job)(const Scheduler_Control *, Thread_Control *, Priority_Node *, uint64_t, Thread_queue_Context *)
static __inline__ const Chain_Node * _Chain_Immutable_tail(const Chain_Control *the_chain)
Returns pointer to immutable chain tail.
static __inline__ const Scheduler_Control * _Scheduler_Get_by_id(Objects_Id id)
Gets the scheduler from the given object build id.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
static __inline__ void _Thread_Update_CPU_time_used(Thread_Control *the_thread, Per_CPU_Control *cpu)
Updates the cpu time used of the thread.
SuperCore SMP Implementation.
static __inline__ bool _Priority_Plain_insert(Priority_Aggregation *aggregation, Priority_Node *node, Priority_Control priority)
Inserts the node with the given priority into the priority aggregation's contributors.
static __inline__ void _Scheduler_Node_set_user(Scheduler_Node *node, Thread_Control *user)
Sets the user of the node.