<p>I have a couple of changes to make, but this test implements the scenario presented on the rtems-users ml that is fixed by strict order mutex. With strict order the .scn output should be correct though I have not verified it yet. Without strict order the output differs and a priority inversion bug occurs. We should have strict order on by default to fix this bug.</p>

<p>I will work on another test that exposes a different bug when strict order is used and three tasks vie for two semaphores.</p>
<p>-Gedare</p>
<div class="gmail_quote">On May 18, 2013 10:17 AM, "Gedare Bloom" <<a href="mailto:gedare@rtems.org">gedare@rtems.org</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
---<br>
 testsuites/sptests/Makefile.am                   |    2 +-<br>
 testsuites/sptests/<a href="http://configure.ac" target="_blank">configure.ac</a>                  |    1 +<br>
 testsuites/sptests/spsemaphore01/Makefile.am     |   21 +++<br>
 testsuites/sptests/spsemaphore01/init.c          |  155 ++++++++++++++++++++++<br>
 testsuites/sptests/spsemaphore01/spsemaphore.doc |    1 +<br>
 testsuites/sptests/spsemaphore01/spsemaphore.scn |   15 ++<br>
 6 files changed, 194 insertions(+), 1 deletions(-)<br>
 create mode 100644 testsuites/sptests/spsemaphore01/Makefile.am<br>
 create mode 100644 testsuites/sptests/spsemaphore01/init.c<br>
 create mode 100644 testsuites/sptests/spsemaphore01/spsemaphore.doc<br>
 create mode 100644 testsuites/sptests/spsemaphore01/spsemaphore.scn<br>
<br>
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am<br>
index 4b0fff6..5c2300f 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>
+    spsemaphore01 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" target="_blank">configure.ac</a> b/testsuites/sptests/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
index ba3aa92..8a60767 100644<br>
--- a/testsuites/sptests/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
+++ b/testsuites/sptests/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
@@ -188,6 +188,7 @@ spprintk/Makefile<br>
 spprivenv01/Makefile<br>
 spqreslib/Makefile<br>
 sprbtree01/Makefile<br>
+spsemaphore01/Makefile<br>
 spsimplesched01/Makefile<br>
 spsimplesched02/Makefile<br>
 spsimplesched03/Makefile<br>
diff --git a/testsuites/sptests/spsemaphore01/Makefile.am b/testsuites/sptests/spsemaphore01/Makefile.am<br>
new file mode 100644<br>
index 0000000..c3638ba<br>
--- /dev/null<br>
+++ b/testsuites/sptests/spsemaphore01/Makefile.am<br>
@@ -0,0 +1,21 @@<br>
+<br>
+rtems_tests_PROGRAMS = spsemaphore<br>
+spsemaphore_SOURCES = init.c<br>
+<br>
+dist_rtems_tests_DATA = spsemaphore.scn<br>
+dist_rtems_tests_DATA += spsemaphore.doc<br>
+<br>
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg<br>
+include $(top_srcdir)/../automake/<a href="http://compile.am" target="_blank">compile.am</a><br>
+include $(top_srcdir)/../automake/<a href="http://leaf.am" target="_blank">leaf.am</a><br>
+<br>
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include<br>
+<br>
+LINK_OBJS = $(spsemaphore_OBJECTS)<br>
+LINK_LIBS = $(spsemaphore_LDLIBS)<br>
+<br>
+spsemaphore$(EXEEXT): $(spsemaphore_OBJECTS) $(spsemaphore_DEPENDENCIES)<br>
+       @rm -f spsemaphore$(EXEEXT)<br>
+       $(make-exe)<br>
+<br>
+include $(top_srcdir)/../automake/<a href="http://local.am" target="_blank">local.am</a><br>
diff --git a/testsuites/sptests/spsemaphore01/init.c b/testsuites/sptests/spsemaphore01/init.c<br>
new file mode 100644<br>
index 0000000..2f38baf<br>
--- /dev/null<br>
+++ b/testsuites/sptests/spsemaphore01/init.c<br>
@@ -0,0 +1,155 @@<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" target="_blank">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: 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: 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>
+<br>
diff --git a/testsuites/sptests/spsemaphore01/spsemaphore.doc b/testsuites/sptests/spsemaphore01/spsemaphore.doc<br>
new file mode 100644<br>
index 0000000..8b13789<br>
--- /dev/null<br>
+++ b/testsuites/sptests/spsemaphore01/spsemaphore.doc<br>
@@ -0,0 +1 @@<br>
+<br>
diff --git a/testsuites/sptests/spsemaphore01/spsemaphore.scn b/testsuites/sptests/spsemaphore01/spsemaphore.scn<br>
new file mode 100644<br>
index 0000000..977af61<br>
--- /dev/null<br>
+++ b/testsuites/sptests/spsemaphore01/spsemaphore.scn<br>
@@ -0,0 +1,15 @@<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: priority 36<br>
+TA01: priority 36, holding S0<br>
+TA01: priority 36, holding S0, S1<br>
+TA02: priority 34<br>
+TA02: priority 34, holding S1<br>
+TA02: exiting<br>
+TA01: priority 34, holding S0<br>
+TA01: priority 36<br>
+TA01: exiting<br>
+*** END OF SEMAPHORE01 ***<br>
--<br>
1.7.1<br>
<br>
</blockquote></div>