[PATCH] Return invalid mode for !preempt and interrupt disable modes when SMP

Joel Sherrill joel at rtems.org
Fri Oct 27 20:57:39 UTC 2017


This impacts rtems_task_mode() and rtems_task_create().

updates #3000.
---
 c/src/ada/rtems.ads                         |  3 ++-
 cpukit/rtems/include/rtems/rtems/status.h   | 10 ++++++++--
 cpukit/rtems/src/statustext.c               |  1 +
 cpukit/rtems/src/taskcreate.c               | 19 ++++++++++++++++---
 cpukit/rtems/src/taskmode.c                 | 19 +++++++++++++------
 testsuites/smptests/smpunsupported01/init.c |  6 +++---
 6 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/c/src/ada/rtems.ads b/c/src/ada/rtems.ads
index 2b59c74..cd23185 100644
--- a/c/src/ada/rtems.ads
+++ b/c/src/ada/rtems.ads
@@ -10,7 +10,7 @@
 --    RTEMS initialization and configuration are called from
 --    the BSP side, therefore should never be called from ADA.
 --
---  COPYRIGHT (c) 1997-2011.
+--  COPYRIGHT (c) 1997-2011, 2017.
 --  On-Line Applications Research Corporation (OAR).
 --
 --  The license and distribution terms for this file may in
@@ -351,6 +351,7 @@ pragma Elaborate_Body (RTEMS);
       Internal_Error,           -- RTEMS inconsistency detected
       No_Memory,                -- no memory left in heap
       IO_Error,                 -- driver IO error
+      Invalid_Mode,             -- invalid mode for RTEMS configuration
       Proxy_Blocking            -- internal multiprocessing only
    );
 
diff --git a/cpukit/rtems/include/rtems/rtems/status.h b/cpukit/rtems/include/rtems/rtems/status.h
index c54404b..ede43cc 100644
--- a/cpukit/rtems/include/rtems/rtems/status.h
+++ b/cpukit/rtems/include/rtems/rtems/status.h
@@ -10,7 +10,7 @@
  * executive directives.
  */
 
-/* COPYRIGHT (c) 1989-2013.
+/* COPYRIGHT (c) 1989-2017.
  * On-Line Applications Research Corporation (OAR).
  *
  * The license and distribution terms for this file may be
@@ -170,6 +170,12 @@ typedef enum {
    */
   RTEMS_IO_ERROR                 = 27,
   /**
+   *  This is the status to indicate an invalid mode was specified.
+   *  This can occur when using a mode that is not supported in
+   *  the current RTEMS functional configuration.
+   */
+  RTEMS_INVALID_MODE             = 28,
+  /**
    *  This is the status is used internally to RTEMS when performing
    *  operations on behalf of remote tasks.  This is referred to as
    *  proxying operations and this status indicates that the operation
@@ -177,7 +183,7 @@ typedef enum {
    *
    *  @note This status will @b NOT be returned to the user.
    */
-  RTEMS_PROXY_BLOCKING           = 28
+  RTEMS_PROXY_BLOCKING           = 29
 } rtems_status_code;
 
 /**
diff --git a/cpukit/rtems/src/statustext.c b/cpukit/rtems/src/statustext.c
index f701ebd..f2af24f 100644
--- a/cpukit/rtems/src/statustext.c
+++ b/cpukit/rtems/src/statustext.c
@@ -53,6 +53,7 @@ static const char *const status_code_text[] = {
   "RTEMS_INTERNAL_ERROR",
   "RTEMS_NO_MEMORY",
   "RTEMS_IO_ERROR",
+  "RTEMS_INVALID_MODE",
   "RTEMS_PROXY_BLOCKING"
 };
 
diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c
index 2695382..7a68c6f 100644
--- a/cpukit/rtems/src/taskcreate.c
+++ b/cpukit/rtems/src/taskcreate.c
@@ -6,7 +6,7 @@
  */
 
 /*
- *  COPYRIGHT (c) 1989-2014,2016.
+ *  COPYRIGHT (c) 1989-2014,2016,2017.
  *  On-Line Applications Research Corporation (OAR).
  *
  *  The license and distribution terms for this file may be
@@ -50,15 +50,28 @@ rtems_status_code rtems_task_create(
   RTEMS_API_Control       *api;
   ASR_Information         *asr;
 
-
   if ( !id )
    return RTEMS_INVALID_ADDRESS;
 
   if ( !rtems_is_name_valid( name ) )
     return RTEMS_INVALID_NAME;
 
+#if defined(RTEMS_SMP)
+  /*
+   *  Per task preemption and interrupt disable are unsafe and not
+   *  supported on SMP configurations.
+   */
+  if ( rtems_configuration_is_smp_enabled() ) {
+    if ( !_Modes_Is_preempt(initial_modes) )
+      return RTEMS_INVALID_MODE;
+
+    if ( _Modes_Get_interrupt_level(initial_modes) != 0 )
+      return RTEMS_INVALID_MODE;
+  }
+#endif
+
   /*
-   *  Core Thread Initialize insures we get the minimum amount of
+   *  Core Thread Initialize ensures we get the minimum amount of
    *  stack space.
    */
 
diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c
index a345409..d26fdc2 100644
--- a/cpukit/rtems/src/taskmode.c
+++ b/cpukit/rtems/src/taskmode.c
@@ -6,7 +6,7 @@
  */
 
 /*
- *  COPYRIGHT (c) 1989-2014.
+ *  COPYRIGHT (c) 1989-2014,2017.
  *  On-Line Applications Research Corporation (OAR).
  *
  *  The license and distribution terms for this file may be
@@ -64,10 +64,10 @@ rtems_status_code rtems_task_mode(
    */
   preempt_enabled = false;
   if ( mask & RTEMS_PREEMPT_MASK ) {
-#if defined( RTEMS_SMP )
-    if ( rtems_configuration_is_smp_enabled() &&
-         !_Modes_Is_preempt( mode_set ) ) {
-      return RTEMS_NOT_IMPLEMENTED;
+#if defined(RTEMS_SMP)
+    if ( rtems_configuration_is_smp_enabled() ) {
+      if ( !_Modes_Is_preempt( mode_set ) )
+        return RTEMS_INVALID_MODE;
     }
 #endif
     bool is_preempt_enabled = _Modes_Is_preempt( mode_set );
@@ -88,8 +88,15 @@ rtems_status_code rtems_task_mode(
   /*
    *  Set the new interrupt level
    */
-  if ( mask & RTEMS_INTERRUPT_MASK )
+  if ( mask & RTEMS_INTERRUPT_MASK ) {
     _Modes_Set_interrupt_level( mode_set );
+#if defined(RTEMS_SMP)
+    if ( rtems_configuration_is_smp_enabled() ) {
+      if ( _Modes_Get_interrupt_level(mode_set) != 0 )
+        return RTEMS_INVALID_MODE;
+    }
+#endif
+  }
 
   /*
    *  This is specific to the RTEMS API
diff --git a/testsuites/smptests/smpunsupported01/init.c b/testsuites/smptests/smpunsupported01/init.c
index 56212a4..9e0ded2 100644
--- a/testsuites/smptests/smpunsupported01/init.c
+++ b/testsuites/smptests/smpunsupported01/init.c
@@ -32,7 +32,7 @@ static void test(void)
   rtems_test_assert(rtems_configuration_is_smp_enabled());
 
   sc = rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &mode);
-  rtems_test_assert(sc == RTEMS_NOT_IMPLEMENTED);
+  rtems_test_assert(sc == RTEMS_INVALID_MODE);
 
   sc = rtems_task_create(
     rtems_build_name('T', 'A', 'S', 'K'),
@@ -42,7 +42,7 @@ static void test(void)
     RTEMS_DEFAULT_ATTRIBUTES,
     &id
   );
-  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+  rtems_test_assert(sc == RTEMS_INVALID_MODE);
 
   mode = RTEMS_INTERRUPT_LEVEL(1);
 
@@ -55,7 +55,7 @@ static void test(void)
       RTEMS_DEFAULT_ATTRIBUTES,
       &id
     );
-    rtems_test_assert(sc == RTEMS_UNSATISFIED);
+    rtems_test_assert(sc == RTEMS_INVALID_MODE);
   } else {
     puts("RTEMS_INTERRUPT_LEVEL(1) not supported on this platform");
   }
-- 
1.8.3.1




More information about the devel mailing list