[PATCH] cpukit: Return RTEMS_INVALID_MODE if the rtems_task_create mode is invalid.

Chris Johns chrisj at rtems.org
Wed Apr 19 03:35:57 UTC 2017


The mode's RTEMS_NO_PREEMPT and RTEMS_INTERRUPT_LEVEL(n) are not valid
with SMP. This change reports the error as RTEMS_INVALID_MODE rather
than RTEMS_UNSATISFIED.

Closes #3000.
---
 cpukit/rtems/include/rtems/rtems/status.h |  8 ++++++--
 cpukit/rtems/src/status.c                 |  3 ++-
 cpukit/rtems/src/statustext.c             |  3 ++-
 cpukit/rtems/src/taskcreate.c             | 20 ++++++++++++++++++--
 cpukit/score/src/threadinitialize.c       |  9 ++-------
 5 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/cpukit/rtems/include/rtems/rtems/status.h b/cpukit/rtems/include/rtems/rtems/status.h
index c54404ba14..cc22d8e574 100644
--- a/cpukit/rtems/include/rtems/rtems/status.h
+++ b/cpukit/rtems/include/rtems/rtems/status.h
@@ -177,7 +177,11 @@ typedef enum {
    *
    *  @note This status will @b NOT be returned to the user.
    */
-  RTEMS_PROXY_BLOCKING           = 28
+  RTEMS_PROXY_BLOCKING           = 28,
+  /**
+   *  This is the status to indicate the mode is invalid.
+   */
+  RTEMS_INVALID_MODE             = 29
 } rtems_status_code;
 
 /**
@@ -188,7 +192,7 @@ typedef enum {
 /**
  *  This is the highest valid value for a Classic API status code.
  */
-#define RTEMS_STATUS_CODES_LAST  RTEMS_PROXY_BLOCKING
+#define RTEMS_STATUS_CODES_LAST  RTEMS_INVALID_MODE
 
 /**
  *  @brief Checks if the status code is equal to RTEMS_SUCCESSFUL.
diff --git a/cpukit/rtems/src/status.c b/cpukit/rtems/src/status.c
index 810c0e18de..c0015a9345 100644
--- a/cpukit/rtems/src/status.c
+++ b/cpukit/rtems/src/status.c
@@ -58,7 +58,8 @@ static const int status_code_to_errno [RTEMS_STATUS_CODES_LAST + 1] = {
   [RTEMS_INTERNAL_ERROR]           = EIO,
   [RTEMS_NO_MEMORY]                = ENOMEM,
   [RTEMS_IO_ERROR]                 = EIO,
-  [RTEMS_PROXY_BLOCKING]           = EIO
+  [RTEMS_PROXY_BLOCKING]           = EIO,
+  [RTEMS_INVALID_MODE]             = EINVAL
 };
 
 int rtems_status_code_to_errno(rtems_status_code sc)
diff --git a/cpukit/rtems/src/statustext.c b/cpukit/rtems/src/statustext.c
index f701ebd356..2f5ea59854 100644
--- a/cpukit/rtems/src/statustext.c
+++ b/cpukit/rtems/src/statustext.c
@@ -53,7 +53,8 @@ static const char *const status_code_text[] = {
   "RTEMS_INTERNAL_ERROR",
   "RTEMS_NO_MEMORY",
   "RTEMS_IO_ERROR",
-  "RTEMS_PROXY_BLOCKING"
+  "RTEMS_PROXY_BLOCKING",
+  "RTEMS_INVALID_MODE"
 };
 
 const char *rtems_status_text( rtems_status_code code )
diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c
index 26953828e9..d63e1c11e2 100644
--- a/cpukit/rtems/src/taskcreate.c
+++ b/cpukit/rtems/src/taskcreate.c
@@ -49,6 +49,8 @@ rtems_status_code rtems_task_create(
   Priority_Control         priority;
   RTEMS_API_Control       *api;
   ASR_Information         *asr;
+  bool                     is_preemptible;
+  uint32_t                 isr_level;
 
 
   if ( !id )
@@ -138,6 +140,20 @@ rtems_status_code rtems_task_create(
 #endif
 
   /*
+   * Setting the mode to non-preemptible and/or the ISR level is not allowed
+   * with SMP. It provides no protection to any data because the setting is
+   * specific to only one core.
+   */
+  is_preemptible = _Modes_Is_preempt(initial_modes) ? true : false;
+  isr_level = _Modes_Get_interrupt_level(initial_modes);
+#if defined( RTEMS_SMP )
+  if ( rtems_configuration_is_smp_enabled() ) {
+    if ( !is_preemptible || isr_level != 0 )
+      return RTEMS_INVALID_MODE;
+  }
+#endif
+
+  /*
    *  Initialize the core thread for this task.
    */
 
@@ -149,12 +165,12 @@ rtems_status_code rtems_task_create(
     stack_size,
     is_fp,
     priority,
-    _Modes_Is_preempt(initial_modes)   ? true : false,
+    is_preemptible,
     _Modes_Is_timeslice(initial_modes) ?
       THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :
       THREAD_CPU_BUDGET_ALGORITHM_NONE,
     NULL,        /* no budget algorithm callout */
-    _Modes_Get_interrupt_level(initial_modes),
+    isr_level,
     (Objects_Name) name
   );
 
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index c34113db3d..2a76035e69 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -61,13 +61,8 @@ bool _Thread_Initialize(
 
 #if defined( RTEMS_SMP )
   if ( rtems_configuration_is_smp_enabled() ) {
-    if ( !is_preemptible ) {
-      return false;
-    }
-
-    if ( isr_level != 0 ) {
-      return false;
-    }
+    _Assert( is_preemptible );
+    _Assert( isr_level == 0 );
   }
 #endif
 
-- 
2.11.0



More information about the devel mailing list