summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-02-15 11:52:00 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-02-25 07:18:35 +0100
commite50e42b820c4163a1c5e07c6697c3102fc2d4740 (patch)
tree845deffec09923b3a284512397298132c3a8f26a
parentconfig: CONFIGURE_INIT_TASK_INITIAL_MODES (diff)
downloadrtems-e50e42b820c4163a1c5e07c6697c3102fc2d4740.tar.bz2
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.
-rw-r--r--cpukit/include/rtems/scheduler.h16
-rw-r--r--cpukit/include/rtems/score/scheduler.h8
-rw-r--r--cpukit/include/rtems/score/schedulerimpl.h18
-rw-r--r--cpukit/rtems/src/taskmode.c9
-rw-r--r--cpukit/score/src/threadinitialize.c5
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
@@ -27,6 +27,13 @@
_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
@@ -130,6 +130,24 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Release_critical(
}
#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