39#ifndef _RTEMS_SCORE_SCHEDULERIMPL_H
40#define _RTEMS_SCORE_SCHEDULERIMPL_H
122#if defined(RTEMS_SMP)
123 return cpu->Scheduler.control;
138static inline void _Scheduler_Acquire_critical(
143#if defined(RTEMS_SMP)
146 context = _Scheduler_Get_context( scheduler );
162static inline void _Scheduler_Release_critical(
167#if defined(RTEMS_SMP)
170 context = _Scheduler_Get_context( scheduler );
178#if defined(RTEMS_SMP)
188static inline bool _Scheduler_Is_non_preempt_mode_supported(
192 return scheduler->is_non_preempt_mode_supported;
219static inline void _Scheduler_Schedule(
Thread_Control *the_thread )
224 scheduler = _Thread_Scheduler_get_home( the_thread );
225 _Scheduler_Acquire_critical( scheduler, &lock_context );
229 _Scheduler_Release_critical( scheduler, &lock_context );
245 scheduler = _Thread_Scheduler_get_home( the_thread );
246 _Scheduler_Acquire_critical( scheduler, &lock_context );
250 _Thread_Scheduler_get_home_node( the_thread )
252 _Scheduler_Release_critical( scheduler, &lock_context );
267#if defined(RTEMS_SMP)
274 node = _Chain_First( &the_thread->
Scheduler.Scheduler_nodes );
275 tail = _Chain_Immutable_tail( &the_thread->
Scheduler.Scheduler_nodes );
277 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
278 scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
280 _Scheduler_Acquire_critical( scheduler, &lock_context );
286 _Scheduler_Release_critical( scheduler, &lock_context );
288 node = _Chain_Next( node );
290 while ( node != tail ) {
291 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
292 scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
294 _Scheduler_Acquire_critical( scheduler, &lock_context );
299 THREAD_SCHEDULER_BLOCKED
301 _Scheduler_Release_critical( scheduler, &lock_context );
303 node = _Chain_Next( node );
308 scheduler = _Thread_Scheduler_get_home( the_thread );
312 _Thread_Scheduler_get_home_node( the_thread )
327static inline void _Scheduler_Unblock(
Thread_Control *the_thread )
333#if defined(RTEMS_SMP)
334 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE(
335 _Chain_First( &the_thread->
Scheduler.Scheduler_nodes )
337 scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
339 scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
340 scheduler = _Thread_Scheduler_get_home( the_thread );
343 _Scheduler_Acquire_critical( scheduler, &lock_context );
345 _Scheduler_Release_critical( scheduler, &lock_context );
362static inline void _Scheduler_Update_priority(
Thread_Control *the_thread )
364#if defined(RTEMS_SMP)
368 _Thread_Scheduler_process_requests( the_thread );
370 node = _Chain_First( &the_thread->
Scheduler.Scheduler_nodes );
371 tail = _Chain_Immutable_tail( &the_thread->
Scheduler.Scheduler_nodes );
378 scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
379 scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
381 _Scheduler_Acquire_critical( scheduler, &lock_context );
387 _Scheduler_Release_critical( scheduler, &lock_context );
389 node = _Chain_Next( node );
390 }
while ( node != tail );
394 scheduler = _Thread_Scheduler_get_home( the_thread );
398 _Thread_Scheduler_get_home_node( the_thread )
453static inline void _Scheduler_Node_initialize(
477static inline void _Scheduler_Node_destroy(
494static inline void _Scheduler_Release_job(
503 _Thread_queue_Context_clear_priority_updates( queue_context );
521static inline void _Scheduler_Cancel_job(
529 _Thread_queue_Context_clear_priority_updates( queue_context );
547static inline void _Scheduler_Start_idle(
566static inline bool _Scheduler_Has_processor_ownership(
571#if defined(RTEMS_SMP)
575 cpu = _Per_CPU_Get_by_index( cpu_index );
576 scheduler_of_cpu = _Scheduler_Get_by_CPU( cpu );
578 return scheduler_of_cpu == scheduler;
594static inline const Processor_mask *_Scheduler_Get_processors(
598#if defined(RTEMS_SMP)
599 return &_Scheduler_Get_context( scheduler )->Processors;
601 return &_Processor_mask_The_one_and_only;
639 const Processor_mask *affinity
646 if ( !_Processor_mask_Is_subset( affinity, _SMP_Get_online_processors() ) ) {
647 return STATUS_INVALID_NUMBER;
650 return STATUS_SUCCESSFUL;
668 const cpu_set_t *cpuset
678static inline uint32_t _Scheduler_Get_processor_count(
682#if defined(RTEMS_SMP)
685 return _Processor_mask_Count( &
context->Processors );
700static inline Objects_Id _Scheduler_Build_id( uint32_t scheduler_index )
703 OBJECTS_FAKE_OBJECTS_API,
704 OBJECTS_FAKE_OBJECTS_SCHEDULERS,
706 (uint16_t) ( scheduler_index + 1 )
717static inline uint32_t _Scheduler_Get_index_by_id(
Objects_Id id )
719 uint32_t minimum_id = _Scheduler_Build_id( 0 );
721 return id - minimum_id;
737 index = _Scheduler_Get_index_by_id(
id );
753static inline uint32_t _Scheduler_Get_index(
760#if defined(RTEMS_SMP)
779typedef void ( *Scheduler_Release_idle_node )(
790static inline void _Scheduler_Thread_change_state(
792 Thread_Scheduler_state new_state
796 _ISR_lock_Is_owner( &the_thread->
Scheduler.Lock )
797 || the_thread->
Scheduler.state == THREAD_SCHEDULER_BLOCKED
798 || !_System_state_Is_up( _System_state_Get() )
815 Scheduler_Get_idle_node get_idle_node,
822 idle_node = ( *get_idle_node )( arg );
823 idle = _Scheduler_Node_get_owner( idle_node );
825 _Scheduler_Node_set_idle_user( node, idle );
841static inline void _Scheduler_Release_idle_thread(
844 Scheduler_Release_idle_node release_idle_node,
851 owner = _Scheduler_Node_get_owner( node );
852 _Assert( _Scheduler_Node_get_user( node ) == idle );
853 _Scheduler_Node_set_user( node, owner );
855 idle_node = _Thread_Scheduler_get_home_node( idle );
856 ( *release_idle_node )( idle_node, arg );
873static inline Thread_Control *_Scheduler_Release_idle_thread_if_necessary(
875 Scheduler_Release_idle_node release_idle_node,
881 idle = _Scheduler_Node_get_idle( node );
883 if ( idle != NULL ) {
884 _Scheduler_Release_idle_thread( node, idle, release_idle_node, arg );
901static inline void _Scheduler_Discard_idle_thread(
904 Scheduler_Release_idle_node release_idle_node,
911 idle = _Scheduler_Node_get_idle( node );
912 _Scheduler_Release_idle_thread( node, idle, release_idle_node, arg );
914 cpu = _Thread_Get_CPU( idle );
915 _Thread_Set_CPU( the_thread, cpu );
916 _Thread_Dispatch_update_heir( _Per_CPU_Get(), cpu, the_thread );
939#if defined(RTEMS_SMP)
945#if defined(RTEMS_SCORE_THREAD_HAS_SCHEDULER_CHANGE_INHIBITORS)
946 if ( the_thread->is_scheduler_change_inhibited ) {
947 return STATUS_RESOURCE_IN_USE;
952 return STATUS_RESOURCE_IN_USE;
955 old_scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
956 _Priority_Plain_extract(
957 &old_scheduler_node->
Wait.Priority,
962 !_Priority_Is_empty( &old_scheduler_node->
Wait.Priority )
963#
if defined(RTEMS_SMP)
964 || !_Chain_Has_only_one_node( &the_thread->
Scheduler.Wait_nodes )
968 _Priority_Plain_insert(
969 &old_scheduler_node->
Wait.Priority,
973 return STATUS_RESOURCE_IN_USE;
976#if defined(RTEMS_SMP)
977 old_scheduler = _Thread_Scheduler_get_home( the_thread );
978 new_scheduler_node = _Thread_Scheduler_get_node_by_index(
980 _Scheduler_Get_index( new_scheduler )
983 _Scheduler_Acquire_critical( new_scheduler, &lock_context );
986 _Scheduler_Get_processor_count( new_scheduler ) == 0
987 || ( *new_scheduler->
Operations.set_affinity )(
992 ) != STATUS_SUCCESSFUL
994 _Scheduler_Release_critical( new_scheduler, &lock_context );
995 _Priority_Plain_insert(
996 &old_scheduler_node->
Wait.Priority,
1000 return STATUS_UNSATISFIED;
1004 the_thread->
Scheduler.home_scheduler = new_scheduler;
1006 _Scheduler_Release_critical( new_scheduler, &lock_context );
1008 _Thread_Scheduler_process_requests( the_thread );
1010 new_scheduler_node = old_scheduler_node;
1014 _Priority_Node_set_priority( &the_thread->
Real_priority, priority );
1015 _Priority_Initialize_one(
1016 &new_scheduler_node->
Wait.Priority,
1020#if defined(RTEMS_SMP)
1021 if ( old_scheduler != new_scheduler ) {
1026 if ( _States_Is_ready( current_state ) ) {
1027 _Scheduler_Block( the_thread );
1030 _Assert( old_scheduler_node->sticky_level == 0 );
1031 _Assert( new_scheduler_node->sticky_level == 0 );
1033 _Chain_Extract_unprotected( &old_scheduler_node->Thread.Wait_node );
1035 _Chain_Initialize_one(
1037 &new_scheduler_node->Thread.Wait_node
1039 _Chain_Extract_unprotected(
1040 &old_scheduler_node->Thread.Scheduler_node.Chain
1043 _Chain_Initialize_one(
1045 &new_scheduler_node->Thread.Scheduler_node.Chain
1048 _Scheduler_Node_set_priority(
1054 if ( _States_Is_ready( current_state ) ) {
1055 _Scheduler_Unblock( the_thread );
1058 return STATUS_SUCCESSFUL;
1062 _Scheduler_Node_set_priority(
1067 _Scheduler_Update_priority( the_thread );
1068 return STATUS_SUCCESSFUL;
This header file provides the interfaces of the Assert Handler.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG and static analysis runs.
Definition: assert.h:96
#define _ISR_lock_Release(_lock, _context)
Releases an ISR lock inside an ISR disabled section.
Definition: isrlock.h:282
#define _ISR_lock_Acquire(_lock, _context)
Acquires an ISR lock inside an ISR disabled section.
Definition: isrlock.h:259
uint32_t Objects_Id
Definition: object.h:101
#define _Objects_Build_id(the_api, the_class, node, index)
Builds an object ID from its components.
Definition: object.h:338
#define _Objects_Local_node
The local MPCI node number.
Definition: object.h:368
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:91
@ PRIORITY_GROUP_LAST
Priority group last option requests that the priority node is inserted as the last node into its prio...
Definition: priorityimpl.h:73
void _Scheduler_Handler_initialization(void)
Initializes the scheduler to the policy chosen by the user.
Definition: scheduler.c:44
Status_Control _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.
Definition: schedulergetaffinity.c:43
#define _Scheduler_Count
This constant contains the count of configured schedulers.
Definition: scheduler.h:395
const Scheduler_Control _Scheduler_Table[]
This table contains the configured schedulers.
Status_Control _Scheduler_Set_affinity(Thread_Control *the_thread, size_t cpusetsize, const cpu_set_t *cpuset)
Sets the thread's scheduler's affinity.
Definition: schedulersetaffinity.c:43
uint32_t States_Control
Definition: states.h:65
Status_Control
Status codes.
Definition: status.h:111
rtems_termios_device_context * context
Definition: console-config.c:62
This header file provides interfaces of the Priority Handler which are only used by the implementatio...
This header file provides interfaces of the Scheduler Handler which are used by the implementation an...
This header file provides the interfaces of the Operation Status Support.
This header file provides interfaces of the SMP Support which are only used by the implementation.
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
The priority node to build up a priority aggregation.
Definition: priority.h:112
Priority_Control priority
The priority value of this node.
Definition: priority.h:124
Scheduler context.
Definition: scheduler.h:318
Scheduler node for per-thread data.
Definition: schedulernode.h:94
struct Scheduler_Node::@4406 Wait
Thread wait support block.
void(* yield)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *)
Definition: scheduler.h:70
Priority_Control(* unmap_priority)(const Scheduler_Control *, Priority_Control)
Definition: scheduler.h:104
void(* unblock)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *)
Definition: scheduler.h:84
Priority_Control(* map_priority)(const Scheduler_Control *, Priority_Control)
Definition: scheduler.h:98
void(* cancel_job)(const Scheduler_Control *, Thread_Control *, Priority_Node *, Thread_queue_Context *)
Definition: scheduler.h:287
void(* block)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *)
Definition: scheduler.h:77
void(* release_job)(const Scheduler_Control *, Thread_Control *, Priority_Node *, uint64_t, Thread_queue_Context *)
Definition: scheduler.h:278
void(* node_destroy)(const Scheduler_Control *, Scheduler_Node *)
Definition: scheduler.h:275
void(* node_initialize)(const Scheduler_Control *, Scheduler_Node *, Thread_Control *, Priority_Control)
Definition: scheduler.h:267
void(* update_priority)(const Scheduler_Control *, Thread_Control *, Scheduler_Node *)
Definition: scheduler.h:91
void(* schedule)(const Scheduler_Control *, Thread_Control *)
Definition: scheduler.h:67
void(* start_idle)(const Scheduler_Control *, Thread_Control *, struct Per_CPU_Control *)
Definition: scheduler.h:295
Thread queue context for the thread queue methods.
Definition: threadq.h:216
Scheduler control.
Definition: scheduler.h:337
Scheduler_Context * context
Reference to a statically allocated scheduler context.
Definition: scheduler.h:341
Scheduler_Operations Operations
The scheduler operations.
Definition: scheduler.h:346
Thread_Wait_information Wait
Definition: thread.h:877
Priority_Node Real_priority
The base priority of this thread in its home scheduler instance.
Definition: thread.h:864
States_Control current_state
Definition: thread.h:859
Thread_Scheduler_control Scheduler
Scheduler related control.
Definition: thread.h:874
Thread_Start_information Start
Definition: thread.h:956
bool is_idle
Definition: thread.h:908
This header file provides interfaces of the Thread Handler which are only used by the implementation.