<p><br>
On May 18, 2013 3:06 PM, "Joel Sherrill" <<a href="mailto:Joel.Sherrill@oarcorp.com">Joel.Sherrill@oarcorp.com</a>> wrote:<br>
><br>
> When the other test works should we remove the original test submitted with this code?<br>
><br>
No. Even when we fix the bugs, the tests will probably help coverage and avoid regressions. The fixes should at least be ported back to 4.10 too.</p>
<p>> I think we should switch to this as the default behavior when it works.<br>
><br>
Agreed for priority semaphores. Although I wonder if a better solution exists that does not need strict LIFO p/v operations.</p>
<p>> We do need to check coverage.<br>
><br>
Ok. I stumbled on a compile error when turning on strict mutex. :(</p>
<p>I also noticed that sp36, which uses strict mutex, is disabled / missing from Makefile.am.</p>
<p>-Gedare<br>
><br>
><br>
> Gedare Bloom <<a href="mailto:gedare@rtems.org">gedare@rtems.org</a>> wrote:<br>
><br>
><br>
> This test exposes a potential priority inversion when priority<br>
> inheritance is used and multiple locks are acquired by a low priority<br>
> task. The scenario consists of 2 tasks of different priority and 2<br>
> semaphore/mutexes using priority inheritance.<br>
><br>
> Using ENABLE_STRICT_ORDER_MUTEX=1 prevents the priority inversion.<br>
><br>
> I hope to write another test soon that demonstrates a different<br>
> priority inversion when there are 3 tasks and 2 mutexes while using<br>
> the current implementation of strict order mutex.<br>
><br>
> -Gedare<br>
><br>
> On Sat, May 18, 2013 at 2:57 PM, Gedare Bloom <<a href="mailto:gedare@rtems.org">gedare@rtems.org</a>> wrote:<br>
> > ---<br>
> >  testsuites/sptests/Makefile.am         |    2 +-<br>
> >  testsuites/sptests/<a href="http://configure.ac">configure.ac</a>        |    1 +<br>
> >  testsuites/sptests/spsem01/Makefile.am |   21 +++++<br>
> >  testsuites/sptests/spsem01/init.c      |  154 ++++++++++++++++++++++++++++++++<br>
> >  testsuites/sptests/spsem01/spsem01.doc |   19 ++++<br>
> >  testsuites/sptests/spsem01/spsem01.scn |   16 ++++<br>
> >  6 files changed, 212 insertions(+), 1 deletions(-)<br>
> >  create mode 100644 testsuites/sptests/spsem01/Makefile.am<br>
> >  create mode 100644 testsuites/sptests/spsem01/init.c<br>
> >  create mode 100644 testsuites/sptests/spsem01/spsem01.doc<br>
> >  create mode 100644 testsuites/sptests/spsem01/spsem01.scn<br>
> ><br>
> > diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am<br>
> > index 4b0fff6..9acf477 100644<br>
> > --- a/testsuites/sptests/Makefile.am<br>
> > +++ b/testsuites/sptests/Makefile.am<br>
> > @@ -25,7 +25,7 @@ SUBDIRS = \<br>
> >      spintrcritical09 spintrcritical10 spintrcritical11 spintrcritical12 \<br>
> >      spintrcritical13 spintrcritical14 spintrcritical15 spintrcritical16 \<br>
> >      spintrcritical17 spintrcritical18 spmkdir spmountmgr01 spheapprot \<br>
> > -    spsimplesched01 spsimplesched02 spsimplesched03 spnsext01 \<br>
> > +    spsem01 spsimplesched01 spsimplesched02 spsimplesched03 spnsext01 \<br>
> >      spedfsched01 spedfsched02 spedfsched03 \<br>
> >      spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01 \<br>
> >      spatomic01 spatomic02 spatomic03 spatomic04 spatomic05 \<br>
> > diff --git a/testsuites/sptests/<a href="http://configure.ac">configure.ac</a> b/testsuites/sptests/<a href="http://configure.ac">configure.ac</a><br>
> > index ba3aa92..9f40fa1 100644<br>
> > --- a/testsuites/sptests/<a href="http://configure.ac">configure.ac</a><br>
> > +++ b/testsuites/sptests/<a href="http://configure.ac">configure.ac</a><br>
> > @@ -188,6 +188,7 @@ spprintk/Makefile<br>
> >  spprivenv01/Makefile<br>
> >  spqreslib/Makefile<br>
> >  sprbtree01/Makefile<br>
> > +spsem01/Makefile<br>
> >  spsimplesched01/Makefile<br>
> >  spsimplesched02/Makefile<br>
> >  spsimplesched03/Makefile<br>
> > diff --git a/testsuites/sptests/spsem01/Makefile.am b/testsuites/sptests/spsem01/Makefile.am<br>
> > new file mode 100644<br>
> > index 0000000..a957b05<br>
> > --- /dev/null<br>
> > +++ b/testsuites/sptests/spsem01/Makefile.am<br>
> > @@ -0,0 +1,21 @@<br>
> > +<br>
> > +rtems_tests_PROGRAMS = spsem01<br>
> > +spsem01_SOURCES = init.c<br>
> > +<br>
> > +dist_rtems_tests_DATA = spsem01.scn<br>
> > +dist_rtems_tests_DATA += spsem01.doc<br>
> > +<br>
> > +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg<br>
> > +include $(top_srcdir)/../automake/<a href="http://compile.am">compile.am</a><br>
> > +include $(top_srcdir)/../automake/<a href="http://leaf.am">leaf.am</a><br>
> > +<br>
> > +AM_CPPFLAGS += -I$(top_srcdir)/../support/include<br>
> > +<br>
> > +LINK_OBJS = $(spsem01_OBJECTS)<br>
> > +LINK_LIBS = $(spsem01_LDLIBS)<br>
> > +<br>
> > +spsem01$(EXEEXT): $(spsem01_OBJECTS) $(spsem01_DEPENDENCIES)<br>
> > +       @rm -f spsem01$(EXEEXT)<br>
> > +       $(make-exe)<br>
> > +<br>
> > +include $(top_srcdir)/../automake/<a href="http://local.am">local.am</a><br>
> > diff --git a/testsuites/sptests/spsem01/init.c b/testsuites/sptests/spsem01/init.c<br>
> > new file mode 100644<br>
> > index 0000000..4a123f4<br>
> > --- /dev/null<br>
> > +++ b/testsuites/sptests/spsem01/init.c<br>
> > @@ -0,0 +1,154 @@<br>
> > +/*<br>
> > + * Copyright (c) 2013 Gedare Bloom.<br>
> > + *<br>
> > + * The license and distribution terms for this file may be<br>
> > + * found in the file LICENSE in this distribution or at<br>
> > + * <a href="http://www.rtems.com/license/LICENSE">http://www.rtems.com/license/LICENSE</a>.<br>
> > + */<br>
> > +<br>
> > +#include <rtems.h><br>
> > +<br>
> > +#include <stdio.h><br>
> > +#include "tmacros.h"<br>
> > +<br>
> > +/* configuration information */<br>
> > +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER<br>
> > +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER<br>
> > +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE<br>
> > +#define CONFIGURE_EXTRA_TASK_STACKS (RTEMS_MINIMUM_STACK_SIZE * 3)<br>
> > +#define CONFIGURE_MAXIMUM_TASKS 3<br>
> > +#define CONFIGURE_MAXIMUM_SEMAPHORES 2<br>
> > +#define CONFIGURE_INIT<br>
> > +#include <rtems/confdefs.h><br>
> > +<br>
> > +rtems_task Task01(rtems_task_argument ignored);<br>
> > +rtems_task Task02(rtems_task_argument ignored);<br>
> > +rtems_task Init(rtems_task_argument ignored);<br>
> > +<br>
> > +static int getprio(void)<br>
> > +{<br>
> > +  rtems_status_code status;<br>
> > +  rtems_task_priority pri;<br>
> > +<br>
> > +  status = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &pri);<br>
> > +  directive_failed( status, "rtems_task_set_priority");<br>
> > +  return (int)pri;<br>
> > +}<br>
> > +<br>
> > +rtems_id   Task_id[2];<br>
> > +rtems_name Task_name[2];<br>
> > +<br>
> > +rtems_id   sem_id[2];<br>
> > +rtems_name sem_name[2];<br>
> > +<br>
> > +rtems_task Init(rtems_task_argument ignored)<br>
> > +{<br>
> > +  rtems_status_code status;<br>
> > +  rtems_attribute sem_attr;<br>
> > +<br>
> > +  printf("\n*** TEST SEMAPHORE01 ***\n");<br>
> > +<br>
> > +  sem_attr = RTEMS_INHERIT_PRIORITY | RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY;<br>
> > +<br>
> > +  sem_name[0] = rtems_build_name( 'S','0',' ',' ');<br>
> > +  status = rtems_semaphore_create(<br>
> > +    sem_name[0],<br>
> > +    1,<br>
> > +    sem_attr,<br>
> > +    0,<br>
> > +    &sem_id[0]<br>
> > +  );<br>
> > +  directive_failed( status, "rtems_semaphore_create of S0");<br>
> > +  printf("init: S0 created\n");<br>
> > +<br>
> > +  sem_name[1] = rtems_build_name( 'S','1',' ',' ');<br>
> > +  status = rtems_semaphore_create(<br>
> > +    sem_name[1],<br>
> > +    1,<br>
> > +    sem_attr,<br>
> > +    0,<br>
> > +    &sem_id[1]<br>
> > +  );<br>
> > +  directive_failed( status, "rtems_semaphore_create of S1");<br>
> > +  printf("init: S1 created\n");<br>
> > +<br>
> > +  Task_name[0] = rtems_build_name( 'T','A','0','1');<br>
> > +  status = rtems_task_create(<br>
> > +    Task_name[0],<br>
> > +    36,<br>
> > +    RTEMS_MINIMUM_STACK_SIZE*2,<br>
> > +    RTEMS_DEFAULT_MODES,<br>
> > +    RTEMS_DEFAULT_ATTRIBUTES,<br>
> > +    &Task_id[0]<br>
> > +  );<br>
> > +  directive_failed( status, "rtems_task_create of TA01");<br>
> > +  printf("init: TA01 created with priority 36\n");<br>
> > +<br>
> > +  Task_name[1] = rtems_build_name( 'T','A','0','2');<br>
> > +  status = rtems_task_create(<br>
> > +    Task_name[1],<br>
> > +    34,<br>
> > +    RTEMS_MINIMUM_STACK_SIZE*2,<br>
> > +    RTEMS_DEFAULT_MODES,<br>
> > +    RTEMS_DEFAULT_ATTRIBUTES,<br>
> > +    &Task_id[1]<br>
> > +  );<br>
> > +  directive_failed( status , "rtems_task_create of TA02\n");<br>
> > +  printf("init: TA02 created with priority 34\n");<br>
> > +<br>
> > +  status = rtems_task_start( Task_id[0], Task01, 0);<br>
> > +  directive_failed( status, "rtems_task_start of TA01");<br>
> > +<br>
> > +  status = rtems_task_delete( RTEMS_SELF);<br>
> > +  directive_failed( status, "rtems_task_delete of INIT");<br>
> > +}<br>
> > +<br>
> > +/* Task01 starts with priority 36 */<br>
> > +rtems_task Task01(rtems_task_argument ignored)<br>
> > +{<br>
> > +  rtems_status_code status;<br>
> > +  printf("TA01: started with priority %d\n", getprio());<br>
> > +<br>
> > +  status = rtems_semaphore_obtain( sem_id[0], RTEMS_WAIT, 0 );<br>
> > +  directive_failed( status, "rtems_semaphore_obtain of S0\n");<br>
> > +  printf("TA01: priority %d, holding S0\n", getprio());<br>
> > +<br>
> > +  status = rtems_semaphore_obtain( sem_id[1], RTEMS_WAIT, 0 );<br>
> > +  directive_failed( status, "rtems_semaphore_obtain of S1");<br>
> > +  printf("TA01: priority %d, holding S0, S1\n", getprio());<br>
> > +<br>
> > +  /* Start Task 2 (TA02) with priority 34. It will run immediately. */<br>
> > +  status = rtems_task_start( Task_id[1], Task02, 0);<br>
> > +  directive_failed( status, "rtems_task_start of TA02\n");<br>
> > +<br>
> > +  status = rtems_semaphore_release(sem_id[1]);<br>
> > +  directive_failed( status, "rtems_semaphore_release of S1\n");<br>
> > +  printf("TA01: priority %d, holding S0\n", getprio());<br>
> > +<br>
> > +  status = rtems_semaphore_release(sem_id[0]);<br>
> > +  directive_failed( status, "rtems_semaphore_release of S0\n");<br>
> > +  printf("TA01: priority %d\n", getprio());<br>
> > +<br>
> > +  printf("TA01: exiting\n");<br>
> > +  printf("*** END OF SEMAPHORE01 ***\n");<br>
> > +  status = rtems_task_delete( RTEMS_SELF);<br>
> > +  directive_failed( status, "rtems_task_delete TA01");<br>
> > +}<br>
> > +<br>
> > +/* TA02 starts at Task02 with priority 34 */<br>
> > +rtems_task Task02(rtems_task_argument ignored)<br>
> > +{<br>
> > +  rtems_status_code status;<br>
> > +<br>
> > +  printf("TA02: started with priority %d\n", getprio());<br>
> > +<br>
> > +  /* Obtain S1, which should be held by TA01 by now */<br>
> > +  status = rtems_semaphore_obtain( sem_id[1], RTEMS_WAIT, 0 );<br>
> > +  directive_failed( status, " rtems_semaphore_obtain S1");<br>
> > +  printf("TA02: priority %d, holding S1\n", getprio());<br>
> > +<br>
> > +  printf("TA02: exiting\n");<br>
> > +  status = rtems_task_delete( RTEMS_SELF);<br>
> > +  directive_failed( status, "rtems_task_delete TA02");<br>
> > +}<br>
> > +<br>
> > diff --git a/testsuites/sptests/spsem01/spsem01.doc b/testsuites/sptests/spsem01/spsem01.doc<br>
> > new file mode 100644<br>
> > index 0000000..8a09526<br>
> > --- /dev/null<br>
> > +++ b/testsuites/sptests/spsem01/spsem01.doc<br>
> > @@ -0,0 +1,19 @@<br>
> > +This test exposes a potential priority inversion when priority inheritance is<br>
> > +used and multiple locks are acquired by a low priority task. The scenario<br>
> > +consists of 2 tasks of different priority and 2 semaphore/mutexes using<br>
> > +priority inheritance. The scenario is:<br>
> > +<br>
> > +Task 1 has priority 36.  Task 2 has priority 34.<br>
> > +<br>
> > +1. Task 1 obtains semaphore S1.<br>
> > +2. Task 1 obtains semaphore S2<br>
> > +3. Task 2 preempts Task 1.<br>
> > +4. Task 2 blocks on S2.  Task 1 inherits priority 34.<br>
> > +5. Task 1 resumes. Task 1 releases S2. Task 1 continues to run at priority 34.<br>
> > +6. Task 1 releases S1. Task 1 changes priority back to 36.<br>
> > +7. Task 2 now preempts Task 1 and begins operating again.<br>
> > +<br>
> > +During steps 5-6 Task 1 executes when Task 2 should be able to execute.<br>
> > +<br>
> > +Stepping down the priority of Task 1 when it releases S2 back to its original<br>
> > +priority when it obtained S2 fixes the priority inversion.<br>
> > diff --git a/testsuites/sptests/spsem01/spsem01.scn b/testsuites/sptests/spsem01/spsem01.scn<br>
> > new file mode 100644<br>
> > index 0000000..54efd16<br>
> > --- /dev/null<br>
> > +++ b/testsuites/sptests/spsem01/spsem01.scn<br>
> > @@ -0,0 +1,16 @@<br>
> > +*** TEST SEMAPHORE01 ***<br>
> > +init: S0 created<br>
> > +init: S1 created<br>
> > +init: TA01 created with priority 36<br>
> > +init: TA02 created with priority 34<br>
> > +TA01: started with priority 36<br>
> > +TA01: priority 36, holding S0<br>
> > +TA01: priority 36, holding S0, S1<br>
> > +TA02: started with priority 34<br>
> > +TA02: priority 34, holding S1<br>
> > +TA02: exiting<br>
> > +TA01: priority 36, holding S0<br>
> > +TA01: priority 36<br>
> > +TA01: exiting<br>
> > +*** END OF SEMAPHORE01 ***<br>
> > +<br>
> > --<br>
> > 1.7.1<br>
> ><br>
> _______________________________________________<br>
> rtems-devel mailing list<br>
> <a href="mailto:rtems-devel@rtems.org">rtems-devel@rtems.org</a><br>
> <a href="http://www.rtems.org/mailman/listinfo/rtems-devel">http://www.rtems.org/mailman/listinfo/rtems-devel</a><br>
</p>