From e50e42b820c4163a1c5e07c6697c3102fc2d4740 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Sat, 15 Feb 2020 11:52:00 +0100 Subject: score: _Scheduler_Is_non_preempt_mode_supported() If the non-preempt mode for threads is supported depends on the scheduler implementation. Add _Scheduler_Is_non_preempt_mode_supported() to indicate this. Update #3876. --- cpukit/include/rtems/scheduler.h | 16 ++++++++++++++++ cpukit/include/rtems/score/scheduler.h | 8 ++++++++ cpukit/include/rtems/score/schedulerimpl.h | 18 ++++++++++++++++++ cpukit/rtems/src/taskmode.c | 9 ++++++--- cpukit/score/src/threadinitialize.c | 5 ++++- 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/cpukit/include/rtems/scheduler.h b/cpukit/include/rtems/scheduler.h index dbc161a69d..955a83cfb4 100644 --- a/cpukit/include/rtems/scheduler.h +++ b/cpukit/include/rtems/scheduler.h @@ -26,6 +26,13 @@ #define SCHEDULER_CONTEXT_NAME( name ) \ _Configuration_Scheduler_ ## name +#if defined(RTEMS_SMP) + #define SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( value ) \ + , value +#else + #define SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( value ) +#endif + #if defined(RTEMS_SMP) /* This object doesn't exist and indicates a configuration error */ extern const Scheduler_Control RTEMS_SCHEDULER_INVALID_INDEX; @@ -72,6 +79,7 @@ SCHEDULER_CBS_ENTRY_POINTS, \ SCHEDULER_CBS_MAXIMUM_PRIORITY, \ ( obj_name ) \ + SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( true ) \ } /* Provided for backward compatibility */ @@ -98,6 +106,7 @@ SCHEDULER_EDF_ENTRY_POINTS, \ SCHEDULER_EDF_MAXIMUM_PRIORITY, \ ( obj_name ) \ + SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( true ) \ } /* Provided for backward compatibility */ @@ -131,6 +140,7 @@ SCHEDULER_EDF_SMP_ENTRY_POINTS, \ SCHEDULER_EDF_MAXIMUM_PRIORITY, \ ( obj_name ) \ + SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( false ) \ } /* Provided for backward compatibility */ @@ -162,6 +172,7 @@ SCHEDULER_PRIORITY_CONTEXT_NAME( name ).Ready \ ) - 1, \ ( obj_name ) \ + SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( true ) \ } /* Provided for backward compatibility */ @@ -193,6 +204,7 @@ SCHEDULER_PRIORITY_AFFINITY_SMP_CONTEXT_NAME( name ).Ready \ ) - 1, \ ( obj_name ) \ + SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( false ) \ } /* Provided for backward compatibility */ @@ -224,6 +236,7 @@ SCHEDULER_PRIORITY_SMP_CONTEXT_NAME( name ).Ready \ ) - 1, \ ( obj_name ) \ + SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( false ) \ } /* Provided for backward compatibility */ @@ -255,6 +268,7 @@ SCHEDULER_STRONG_APA_CONTEXT_NAME( name ).Ready \ ) - 1, \ ( obj_name ) \ + SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( false ) \ } /* Provided for backward compatibility */ @@ -282,6 +296,7 @@ SCHEDULER_SIMPLE_ENTRY_POINTS, \ SCHEDULER_SIMPLE_MAXIMUM_PRIORITY, \ ( obj_name ) \ + SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( true ) \ } /* Provided for backward compatibility */ @@ -309,6 +324,7 @@ SCHEDULER_SIMPLE_SMP_ENTRY_POINTS, \ SCHEDULER_SIMPLE_SMP_MAXIMUM_PRIORITY, \ ( obj_name ) \ + SCHEDULER_CONTROL_IS_NON_PREEMPT_MODE_SUPPORTED( false ) \ } /* Provided for backward compatibility */ diff --git a/cpukit/include/rtems/score/scheduler.h b/cpukit/include/rtems/score/scheduler.h index 15effd462c..9a6515ba1e 100644 --- a/cpukit/include/rtems/score/scheduler.h +++ b/cpukit/include/rtems/score/scheduler.h @@ -289,6 +289,14 @@ struct _Scheduler_Control { * @brief The scheduler name. */ uint32_t name; + +#if defined(RTEMS_SMP) + /** + * @brief True if the non-preempt mode for threads is supported by the + * scheduler, otherwise false. + */ + bool is_non_preempt_mode_supported; +#endif }; /** diff --git a/cpukit/include/rtems/score/schedulerimpl.h b/cpukit/include/rtems/score/schedulerimpl.h index dcc81fcbbf..e7fbb8b166 100644 --- a/cpukit/include/rtems/score/schedulerimpl.h +++ b/cpukit/include/rtems/score/schedulerimpl.h @@ -129,6 +129,24 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Release_critical( #endif } +#if defined(RTEMS_SMP) +/** + * @brief Indicate if the thread non-preempt mode is supported by the + * scheduler. + * + * @param scheduler The scheduler instance. + * + * @return True if the non-preempt mode for threads is supported by the + * scheduler, otherwise false. + */ +RTEMS_INLINE_ROUTINE bool _Scheduler_Is_non_preempt_mode_supported( + const Scheduler_Control *scheduler +) +{ + return scheduler->is_non_preempt_mode_supported; +} +#endif + #if defined(RTEMS_SMP) void _Scheduler_Request_ask_for_help( Thread_Control *the_thread ); diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c index 8830f6bb5d..3ba5ce7f95 100644 --- a/cpukit/rtems/src/taskmode.c +++ b/cpukit/rtems/src/taskmode.c @@ -41,6 +41,8 @@ rtems_status_code rtems_task_mode( bool needs_asr_dispatching; rtems_mode old_mode; + executing = _Thread_Get_executing(); + if ( !previous_mode_set ) return RTEMS_INVALID_ADDRESS; @@ -48,7 +50,9 @@ rtems_status_code rtems_task_mode( if ( ( mask & RTEMS_PREEMPT_MASK ) != 0 && !_Modes_Is_preempt( mode_set ) - && rtems_configuration_is_smp_enabled() + && !_Scheduler_Is_non_preempt_mode_supported( + _Thread_Scheduler_get_home( executing ) + ) ) { return RTEMS_NOT_IMPLEMENTED; } @@ -71,8 +75,7 @@ rtems_status_code rtems_task_mode( * impact the executing thread. There should be no errors returned * past this point. */ - - executing = _Thread_Get_executing(); + api = executing->API_Extensions[ THREAD_API_RTEMS ]; asr = &api->Signal; diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index 976c97701a..5145bcfdd8 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -63,7 +63,10 @@ bool _Thread_Initialize( the_thread->Start.allocated_stack = config->allocated_stack; #if defined(RTEMS_SMP) - if ( !config->is_preemptible && rtems_configuration_is_smp_enabled() ) { + if ( + !config->is_preemptible + && !_Scheduler_Is_non_preempt_mode_supported( config->scheduler ) + ) { goto failed; } #endif -- cgit v1.2.3