<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 6, 2017 at 12:25 AM, Sebastian Huber <span dir="ltr"><<a href="mailto:sebastian.huber@embedded-brains.de" target="_blank">sebastian.huber@embedded-brains.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 05/12/17 17:13, Joel Sherrill wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Also use single conditional expressions to simplify error checking.<br>
Combined, this all resulted in a block of SMP enabled error checking.<br>
<br>
Updates #3000.<br>
---<br>
  cpukit/rtems/src/taskmode.c | 33 ++++++++++++++++++++++++++++++<wbr>+--<br>
  1 file changed, 31 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c<br>
index a345409..49648ac 100644<br>
--- a/cpukit/rtems/src/taskmode.c<br>
+++ b/cpukit/rtems/src/taskmode.c<br>
@@ -43,6 +43,33 @@ rtems_status_code rtems_task_mode(<br>
    if ( !previous_mode_set )<br>
      return RTEMS_INVALID_ADDRESS;<br>
  +#if defined( RTEMS_SMP )<br>
+  /*<br>
+   * When in SMP, you cannot disable preemption for a thread or<br>
+   * alter its interrupt level. It must be fully preemptible with<br>
+   * all interrupts enabled.<br>
+   */<br>
+  if ( rtems_configuration_is_smp_ena<wbr>bled() ) {<br>
+    if ( mask & RTEMS_PREEMPT_MASK ) {<br>
+      if ( !_Modes_Is_preempt( mode_set ) ) {<br>
+        return RTEMS_NOT_IMPLEMENTED;<br>
+      }<br>
+    }<br>
+<br>
+    if ( mask & RTEMS_INTERRUPT_MASK ) {<br>
+      if (_Modes_Get_interrupt_level( mode_set ) != 0 ) {<br>
</blockquote>
<br></div></div>
if ( _Modes...<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        return RTEMS_NOT_IMPLEMENTED;<br>
+      }<br>
</blockquote>
<br>
There should be a test case for the new else path _Modes_Get_interrupt_level( mode_set ) == 0.</blockquote><div><br></div><div>Looking at this again, I think adding a test case is OK but we should also given</div><div>an error anytime RTEMS_INTERRUPT_MASK is specified. A user thinking they</div><div>are changing the level to 0 (all enabled) is just as wrong as setting it to non-zero.</div><div>The error we are catching is use of RTEMS_INTERRUPT_MASK in SMP mode.</div><div><br></div><div>Thanks for catching this.</div><div><br></div><div>--joel</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    }<br>
+  }<br>
+#endif<br>
+<br>
+  /*<br>
+   * Complete all error checking before doing any operations which<br>
+   * impact the executing thread. There should be no errors returned<br>
+   * past this point.<br>
+   */<br>
+<br>
    executing     = _Thread_Get_executing();<br>
    api = executing->API_Extensions[ THREAD_API_RTEMS ];<br>
    asr = &api->Signal;<br>
@@ -63,18 +90,18 @@ rtems_status_code rtems_task_mode(<br>
     *  These are generic thread scheduling characteristics.<br>
     */<br>
    preempt_enabled = false;<br>
+#if !defined( RTEMS_SMP )<br>
    if ( mask & RTEMS_PREEMPT_MASK ) {<br>
-#if defined( RTEMS_SMP )<br>
      if ( rtems_configuration_is_smp_ena<wbr>bled() &&<br>
           !_Modes_Is_preempt( mode_set ) ) {<br>
        return RTEMS_NOT_IMPLEMENTED;<br>
      }<br>
-#endif<br>
      bool is_preempt_enabled = _Modes_Is_preempt( mode_set );<br>
        preempt_enabled = !executing->is_preemptible && is_preempt_enabled;<br>
      executing->is_preemptible = is_preempt_enabled;<br>
    }<br>
+#endif<br>
      if ( mask & RTEMS_TIMESLICE_MASK ) {<br>
      if ( _Modes_Is_timeslice(mode_set) ) {<br>
@@ -88,8 +115,10 @@ rtems_status_code rtems_task_mode(<br>
    /*<br>
     *  Set the new interrupt level<br>
     */<br>
+#if !defined( RTEMS_SMP )<br>
    if ( mask & RTEMS_INTERRUPT_MASK )<br>
      _Modes_Set_interrupt_level( mode_set );<br>
+#endif<br>
      /*<br>
     *  This is specific to the RTEMS API<br>
</blockquote>
<br>
-- <br></div></div>
Sebastian Huber, embedded brains GmbH<br>
<br>
Address : Dornierstr. 4, D-82178 Puchheim, Germany<br>
Phone   : <a href="tel:%2B49%2089%20189%2047%2041-16" value="+4989189474116" target="_blank">+49 89 189 47 41-16</a><br>
Fax     : <a href="tel:%2B49%2089%20189%2047%2041-09" value="+4989189474109" target="_blank">+49 89 189 47 41-09</a><br>
E-Mail  : <a href="mailto:sebastian.huber@embedded-brains.de" target="_blank">sebastian.huber@embedded-brain<wbr>s.de</a><br>
PGP     : Public key available on request.<br>
<br>
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.<br>
<br>
</blockquote></div><br></div></div>