summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-12-13 15:29:20 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-12-13 15:29:20 +0000
commit7d91d722baf1f1ff275fd31500526bb2fd6df632 (patch)
tree4200d45e53e783ea350265ba4267083b51566523
parentCorrected order of output. (diff)
downloadrtems-7d91d722baf1f1ff275fd31500526bb2fd6df632.tar.bz2
First attempt at adding simple binary semaphore in addition to the current
"mutex" and counting semaphore. This is at the request of Eric Norum and his EPICS porting effort.
-rw-r--r--c/src/exec/rtems/include/rtems/rtems/attr.h6
-rw-r--r--c/src/exec/rtems/inline/rtems/rtems/attr.inl17
-rw-r--r--c/src/exec/rtems/macros/rtems/rtems/attr.inl9
-rw-r--r--c/src/exec/rtems/src/semcreate.c9
-rw-r--r--c/src/exec/rtems/src/semtranslatereturncode.c2
-rw-r--r--c/src/exec/score/src/coremutexseize.c1
-rw-r--r--c/src/exec/score/src/coremutexsurrender.c31
-rw-r--r--c/src/tests/sptests/Makefile.am3
-rw-r--r--c/src/tests/sptests/configure.in1
-rw-r--r--c/src/tests/sptests/sp29/Makefile.am36
-rw-r--r--c/src/tests/sptests/sp29/init.c177
-rw-r--r--c/src/tests/sptests/sp29/sp29.doc0
-rw-r--r--c/src/tests/sptests/sp29/sp29.scn0
-rw-r--r--cpukit/rtems/include/rtems/rtems/attr.h6
-rw-r--r--cpukit/rtems/inline/rtems/rtems/attr.inl17
-rw-r--r--cpukit/rtems/macros/rtems/rtems/attr.inl9
-rw-r--r--cpukit/rtems/src/semcreate.c9
-rw-r--r--cpukit/rtems/src/semtranslatereturncode.c2
-rw-r--r--cpukit/score/src/coremutexseize.c1
-rw-r--r--cpukit/score/src/coremutexsurrender.c31
-rw-r--r--testsuites/sptests/Makefile.am3
-rw-r--r--testsuites/sptests/sp29/Makefile.am36
-rw-r--r--testsuites/sptests/sp29/init.c177
-rw-r--r--testsuites/sptests/sp29/sp29.doc0
-rw-r--r--testsuites/sptests/sp29/sp29.scn0
25 files changed, 547 insertions, 36 deletions
diff --git a/c/src/exec/rtems/include/rtems/rtems/attr.h b/c/src/exec/rtems/include/rtems/rtems/attr.h
index cf9b073360..20d8eebe01 100644
--- a/c/src/exec/rtems/include/rtems/rtems/attr.h
+++ b/c/src/exec/rtems/include/rtems/rtems/attr.h
@@ -46,8 +46,12 @@ typedef unsigned32 rtems_attribute;
#define RTEMS_NO_PRIORITY_CEILING 0x00000000
#define RTEMS_PRIORITY_CEILING 0x00000040
+#define RTEMS_NESTING_ALLOWED 0x00000000
+#define RTEMS_NO_NESTING_ALLOWED 0x00000080
+
#define RTEMS_APPLICATION_TASK 0x00000000
-#define RTEMS_SYSTEM_TASK 0x00000080
+#define RTEMS_SYSTEM_TASK 0x00000100
+
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
#define ATTRIBUTES_NOT_SUPPORTED 0
diff --git a/c/src/exec/rtems/inline/rtems/rtems/attr.inl b/c/src/exec/rtems/inline/rtems/rtems/attr.inl
index 0f9e3bbbf9..94a8052648 100644
--- a/c/src/exec/rtems/inline/rtems/rtems/attr.inl
+++ b/c/src/exec/rtems/inline/rtems/rtems/attr.inl
@@ -158,6 +158,23 @@ RTEMS_INLINE_ROUTINE boolean _Attributes_Is_priority_ceiling(
/*PAGE
*
+ * _Attributes_Is_nesting_allowed
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the nesting allowed attribute
+ * is enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_nesting_allowed(
+ rtems_attribute attribute_set
+)
+{
+ return ( !(attribute_set & RTEMS_NO_NESTING_ALLOWED) );
+}
+
+/*PAGE
+ *
* _Attributes_Is_system_task
*
* DESCRIPTION:
diff --git a/c/src/exec/rtems/macros/rtems/rtems/attr.inl b/c/src/exec/rtems/macros/rtems/rtems/attr.inl
index 035a6b8bc5..516752b7d1 100644
--- a/c/src/exec/rtems/macros/rtems/rtems/attr.inl
+++ b/c/src/exec/rtems/macros/rtems/rtems/attr.inl
@@ -90,6 +90,15 @@
/*PAGE
*
+ * _Attributes_Is_nesting_allowed
+ *
+ */
+
+#define _Attributes_Is_nesting_allowed( _attribute_set ) \
+ ( !((_attribute_set) & RTEMS_NO_NESTING_ALLOWED) )
+
+/*PAGE
+ *
* _Attributes_Is_system_task
*
*/
diff --git a/c/src/exec/rtems/src/semcreate.c b/c/src/exec/rtems/src/semcreate.c
index 84a960f5b2..a63814acfe 100644
--- a/c/src/exec/rtems/src/semcreate.c
+++ b/c/src/exec/rtems/src/semcreate.c
@@ -129,14 +129,17 @@ rtems_status_code rtems_semaphore_create(
if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
if ( _Attributes_Is_inherit_priority( attribute_set ) )
the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
- else if (_Attributes_Is_priority_ceiling( attribute_set ) )
+ else if ( _Attributes_Is_priority_ceiling( attribute_set ) )
the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
- else if (_Attributes_Is_priority( attribute_set ) )
+ else if ( _Attributes_Is_priority( attribute_set ) )
the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY;
else
the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
- the_mutex_attributes.allow_nesting = TRUE;
+ if ( _Attributes_Is_nesting_allowed( attribute_set ) )
+ the_mutex_attributes.allow_nesting = TRUE;
+ else
+ the_mutex_attributes.allow_nesting = FALSE;
/* Add priority ceiling code here ????? */
diff --git a/c/src/exec/rtems/src/semtranslatereturncode.c b/c/src/exec/rtems/src/semtranslatereturncode.c
index 0f9bf7d3f5..adae1df600 100644
--- a/c/src/exec/rtems/src/semtranslatereturncode.c
+++ b/c/src/exec/rtems/src/semtranslatereturncode.c
@@ -67,7 +67,7 @@ rtems_status_code _Semaphore_Translate_core_mutex_return_code (
case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
return RTEMS_UNSATISFIED;
case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
- return RTEMS_INTERNAL_ERROR;
+ return RTEMS_UNSATISFIED;
case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
return RTEMS_NOT_OWNER_OF_RESOURCE;
case CORE_MUTEX_WAS_DELETED:
diff --git a/c/src/exec/score/src/coremutexseize.c b/c/src/exec/score/src/coremutexseize.c
index 0fe5fd288a..c2a70da762 100644
--- a/c/src/exec/score/src/coremutexseize.c
+++ b/c/src/exec/score/src/coremutexseize.c
@@ -90,6 +90,7 @@ void _CORE_mutex_Seize(
);
}
}
+ executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
return;
}
diff --git a/c/src/exec/score/src/coremutexsurrender.c b/c/src/exec/score/src/coremutexsurrender.c
index fbd75fd8e8..7f5fc2e911 100644
--- a/c/src/exec/score/src/coremutexsurrender.c
+++ b/c/src/exec/score/src/coremutexsurrender.c
@@ -61,24 +61,31 @@ CORE_mutex_Status _CORE_mutex_Surrender(
* must be released by the thread which acquired them.
*/
- if ( !_Objects_Are_ids_equal(
- _Thread_Executing->Object.id, the_mutex->holder_id ) ) {
-
- switch ( the_mutex->Attributes.discipline ) {
- case CORE_MUTEX_DISCIPLINES_FIFO:
- case CORE_MUTEX_DISCIPLINES_PRIORITY:
- break;
- case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
- case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
- return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
- break;
+ if ( the_mutex->Attributes.allow_nesting ) {
+ if ( !_Objects_Are_ids_equal(
+ _Thread_Executing->Object.id, the_mutex->holder_id ) ) {
+
+ switch ( the_mutex->Attributes.discipline ) {
+ case CORE_MUTEX_DISCIPLINES_FIFO:
+ case CORE_MUTEX_DISCIPLINES_PRIORITY:
+ break;
+ case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
+ case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
+ return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
+ break;
+ }
}
}
+ /* XXX already unlocked -- not right status */
+
+ if ( !the_mutex->nest_count )
+ return( CORE_MUTEX_STATUS_SUCCESSFUL );
+
the_mutex->nest_count--;
if ( the_mutex->nest_count != 0 )
- return( CORE_MUTEX_STATUS_SUCCESSFUL );
+ return( CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED );
_Thread_Executing->resource_count--;
the_mutex->holder = NULL;
diff --git a/c/src/tests/sptests/Makefile.am b/c/src/tests/sptests/Makefile.am
index e483267102..7452d72394 100644
--- a/c/src/tests/sptests/Makefile.am
+++ b/c/src/tests/sptests/Makefile.am
@@ -7,7 +7,8 @@ ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
## sp10 and spfatal are not included for now
SUBDIRS = sp01 sp02 sp03 sp04 sp05 sp06 sp07 sp08 sp09 sp11 sp12 sp13 sp14 \
- sp15 sp16 sp17 sp19 sp20 sp21 sp22 sp23 sp24 sp25 sp26 sp27 sp28 spsize
+ sp15 sp16 sp17 sp19 sp20 sp21 sp22 sp23 sp24 sp25 sp26 sp27 sp28 sp29 \
+ spsize
EXTRA_DIST = sptests.am spfatal
diff --git a/c/src/tests/sptests/configure.in b/c/src/tests/sptests/configure.in
index 9724f05bfb..1c3f871405 100644
--- a/c/src/tests/sptests/configure.in
+++ b/c/src/tests/sptests/configure.in
@@ -66,6 +66,7 @@ sp25/Makefile
sp26/Makefile
sp27/Makefile
sp28/Makefile
+sp29/Makefile
spsize/Makefile
)
diff --git a/c/src/tests/sptests/sp29/Makefile.am b/c/src/tests/sptests/sp29/Makefile.am
new file mode 100644
index 0000000000..ec543997de
--- /dev/null
+++ b/c/src/tests/sptests/sp29/Makefile.am
@@ -0,0 +1,36 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+TEST = sp29
+
+MANAGERS = all
+
+# C source names, if any, go here -- minus the .c
+C_FILES = init.c
+C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
+
+DOCTYPES = scn
+DOCS = $(DOCTYPES:%=$(TEST).%)
+
+SRCS = $(C_FILES) $(H_FILES)
+OBJS = $(C_O_FILES)
+
+PRINT_SRCS = $(DOCS)
+
+PGM = ${ARCH}/$(TEST).exe
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+include $(top_srcdir)/sptests.am
+
+${PGM}: $(OBJS) $(LINK_FILES)
+ $(make-exe)
+
+all-local: $(ARCH) $(TMPINSTALL_FILES)
+
+EXTRA_DIST = $(C_FILES) $(DOCS)
+
+include $(top_srcdir)/../../../../automake/local.am
diff --git a/c/src/tests/sptests/sp29/init.c b/c/src/tests/sptests/sp29/init.c
new file mode 100644
index 0000000000..032b1ac42e
--- /dev/null
+++ b/c/src/tests/sptests/sp29/init.c
@@ -0,0 +1,177 @@
+/*
+ * Test for rtems_semaphore_flush
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+
+rtems_task Init (rtems_task_argument argument);
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_INIT
+
+#include <confdefs.h>
+
+#include <rtems/error.h>
+#include <stdio.h>
+
+rtems_interval ticksPerSecond;
+
+rtems_task
+subtask (rtems_task_argument arg)
+{
+ int i;
+ rtems_status_code sc;
+ rtems_id sem = (rtems_id)arg;
+
+ for (;;) {
+ rtems_task_wake_after (ticksPerSecond * 2);
+
+ sc = rtems_semaphore_release (sem);
+ if (sc != RTEMS_SUCCESSFUL)
+ printf ("%d: Can't release semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+}
+
+void
+startTask (rtems_id arg)
+{
+ rtems_id tid;
+ rtems_status_code sc;
+
+ sc = rtems_task_create (rtems_build_name ('S', 'R', 'V', 'A'),
+ 100,
+ 10000,
+ RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &tid);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Can't create task: %s\n", rtems_status_text (sc));
+ rtems_task_suspend (RTEMS_SELF);
+ }
+ sc = rtems_task_start (tid, subtask, arg);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Can't start task: %s\n", rtems_status_text (sc));
+ rtems_task_suspend (RTEMS_SELF);
+ }
+}
+
+rtems_task Init (rtems_task_argument ignored)
+{
+ int i;
+ rtems_id semrec, semnorec;
+ rtems_status_code sc;
+ rtems_interval then, now;
+
+ sc = rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticksPerSecond);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Can't get ticks per second: %s\n", rtems_status_text (sc));
+ exit (1);
+ }
+ sc = rtems_semaphore_create (rtems_build_name ('S', 'M', 'r', 'c'),
+ 1,
+ RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY |RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
+ 0,
+ &semrec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't create recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ exit (1);
+ }
+ sc = rtems_semaphore_create (rtems_build_name ('S', 'M', 'n', 'c'),
+ 1,
+ RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_NO_NESTING_ALLOWED|RTEMS_INHERIT_PRIORITY |RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
+ 0,
+ &semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't create non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ exit (1);
+ }
+
+ sc = rtems_semaphore_obtain (semrec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't obtain recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semrec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't reobtain recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't obtain non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc == RTEMS_SUCCESSFUL) {
+ printf ("%d: Reobtain non-recursive-lock semaphore -- and should not have.\n", __LINE__);
+ }
+
+ sc = rtems_semaphore_release (semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't release non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_release (semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't rerelease non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't obtain non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc == RTEMS_SUCCESSFUL) {
+ printf ("%d: Reobtain non-recursive-lock semaphore -- and should not have.\n", __LINE__);
+ }
+ else if (sc != RTEMS_UNSATISFIED) {
+ printf ("%d: Reobtain non-recursive-lock semaphore failed, but error is %d (%s), not RTEMS_UNSATISFIED.\n", __LINE__, sc, rtems_status_text (sc));
+ }
+
+ sc = rtems_semaphore_release (semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't release non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_release (semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't rerelease non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't obtain non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ /*
+ * Since this task is holding this, there is no reason to block.
+ * It is obviously an error to reobtain it.
+ */
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_WAIT, 5);
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ if (sc == RTEMS_SUCCESSFUL) {
+ printf ("%d: Reobtain non-recursive-lock semaphore -- and should not have.\n", __LINE__);
+ }
+ else if (sc != RTEMS_UNSATISFIED) {
+ printf ("%d: Reobtain non-recursive-lock semaphore failed, but error is %d (%s), not RTEMS_UNSATISFIED.\n", __LINE__, sc, rtems_status_text (sc));
+ }
+ if ((then - now) < 4)
+ printf ("%d: Reobtain non-recursive-lock semaphore failed without timeout.\n", __LINE__);
+
+ startTask (semnorec);
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
+ for (i = 0 ; i < 5 ; i++) {
+ int diff;
+
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ diff = now - then;
+ then = now;
+ if (sc != RTEMS_SUCCESSFUL)
+ printf ("%d: Failed to obtain non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ else if (diff < (2 * ticksPerSecond + 1))
+ printf ("%d: Obtained obtain non-recursive-lock semaphore too quickly -- %d ticks\n", __LINE__, diff);
+ }
+
+ exit (0);
+}
diff --git a/c/src/tests/sptests/sp29/sp29.doc b/c/src/tests/sptests/sp29/sp29.doc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/c/src/tests/sptests/sp29/sp29.doc
diff --git a/c/src/tests/sptests/sp29/sp29.scn b/c/src/tests/sptests/sp29/sp29.scn
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/c/src/tests/sptests/sp29/sp29.scn
diff --git a/cpukit/rtems/include/rtems/rtems/attr.h b/cpukit/rtems/include/rtems/rtems/attr.h
index cf9b073360..20d8eebe01 100644
--- a/cpukit/rtems/include/rtems/rtems/attr.h
+++ b/cpukit/rtems/include/rtems/rtems/attr.h
@@ -46,8 +46,12 @@ typedef unsigned32 rtems_attribute;
#define RTEMS_NO_PRIORITY_CEILING 0x00000000
#define RTEMS_PRIORITY_CEILING 0x00000040
+#define RTEMS_NESTING_ALLOWED 0x00000000
+#define RTEMS_NO_NESTING_ALLOWED 0x00000080
+
#define RTEMS_APPLICATION_TASK 0x00000000
-#define RTEMS_SYSTEM_TASK 0x00000080
+#define RTEMS_SYSTEM_TASK 0x00000100
+
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
#define ATTRIBUTES_NOT_SUPPORTED 0
diff --git a/cpukit/rtems/inline/rtems/rtems/attr.inl b/cpukit/rtems/inline/rtems/rtems/attr.inl
index 0f9e3bbbf9..94a8052648 100644
--- a/cpukit/rtems/inline/rtems/rtems/attr.inl
+++ b/cpukit/rtems/inline/rtems/rtems/attr.inl
@@ -158,6 +158,23 @@ RTEMS_INLINE_ROUTINE boolean _Attributes_Is_priority_ceiling(
/*PAGE
*
+ * _Attributes_Is_nesting_allowed
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the nesting allowed attribute
+ * is enabled in the attribute_set and FALSE otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE boolean _Attributes_Is_nesting_allowed(
+ rtems_attribute attribute_set
+)
+{
+ return ( !(attribute_set & RTEMS_NO_NESTING_ALLOWED) );
+}
+
+/*PAGE
+ *
* _Attributes_Is_system_task
*
* DESCRIPTION:
diff --git a/cpukit/rtems/macros/rtems/rtems/attr.inl b/cpukit/rtems/macros/rtems/rtems/attr.inl
index 035a6b8bc5..516752b7d1 100644
--- a/cpukit/rtems/macros/rtems/rtems/attr.inl
+++ b/cpukit/rtems/macros/rtems/rtems/attr.inl
@@ -90,6 +90,15 @@
/*PAGE
*
+ * _Attributes_Is_nesting_allowed
+ *
+ */
+
+#define _Attributes_Is_nesting_allowed( _attribute_set ) \
+ ( !((_attribute_set) & RTEMS_NO_NESTING_ALLOWED) )
+
+/*PAGE
+ *
* _Attributes_Is_system_task
*
*/
diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c
index 84a960f5b2..a63814acfe 100644
--- a/cpukit/rtems/src/semcreate.c
+++ b/cpukit/rtems/src/semcreate.c
@@ -129,14 +129,17 @@ rtems_status_code rtems_semaphore_create(
if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
if ( _Attributes_Is_inherit_priority( attribute_set ) )
the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
- else if (_Attributes_Is_priority_ceiling( attribute_set ) )
+ else if ( _Attributes_Is_priority_ceiling( attribute_set ) )
the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
- else if (_Attributes_Is_priority( attribute_set ) )
+ else if ( _Attributes_Is_priority( attribute_set ) )
the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY;
else
the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
- the_mutex_attributes.allow_nesting = TRUE;
+ if ( _Attributes_Is_nesting_allowed( attribute_set ) )
+ the_mutex_attributes.allow_nesting = TRUE;
+ else
+ the_mutex_attributes.allow_nesting = FALSE;
/* Add priority ceiling code here ????? */
diff --git a/cpukit/rtems/src/semtranslatereturncode.c b/cpukit/rtems/src/semtranslatereturncode.c
index 0f9bf7d3f5..adae1df600 100644
--- a/cpukit/rtems/src/semtranslatereturncode.c
+++ b/cpukit/rtems/src/semtranslatereturncode.c
@@ -67,7 +67,7 @@ rtems_status_code _Semaphore_Translate_core_mutex_return_code (
case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
return RTEMS_UNSATISFIED;
case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
- return RTEMS_INTERNAL_ERROR;
+ return RTEMS_UNSATISFIED;
case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
return RTEMS_NOT_OWNER_OF_RESOURCE;
case CORE_MUTEX_WAS_DELETED:
diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c
index 0fe5fd288a..c2a70da762 100644
--- a/cpukit/score/src/coremutexseize.c
+++ b/cpukit/score/src/coremutexseize.c
@@ -90,6 +90,7 @@ void _CORE_mutex_Seize(
);
}
}
+ executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
return;
}
diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c
index fbd75fd8e8..7f5fc2e911 100644
--- a/cpukit/score/src/coremutexsurrender.c
+++ b/cpukit/score/src/coremutexsurrender.c
@@ -61,24 +61,31 @@ CORE_mutex_Status _CORE_mutex_Surrender(
* must be released by the thread which acquired them.
*/
- if ( !_Objects_Are_ids_equal(
- _Thread_Executing->Object.id, the_mutex->holder_id ) ) {
-
- switch ( the_mutex->Attributes.discipline ) {
- case CORE_MUTEX_DISCIPLINES_FIFO:
- case CORE_MUTEX_DISCIPLINES_PRIORITY:
- break;
- case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
- case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
- return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
- break;
+ if ( the_mutex->Attributes.allow_nesting ) {
+ if ( !_Objects_Are_ids_equal(
+ _Thread_Executing->Object.id, the_mutex->holder_id ) ) {
+
+ switch ( the_mutex->Attributes.discipline ) {
+ case CORE_MUTEX_DISCIPLINES_FIFO:
+ case CORE_MUTEX_DISCIPLINES_PRIORITY:
+ break;
+ case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
+ case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
+ return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
+ break;
+ }
}
}
+ /* XXX already unlocked -- not right status */
+
+ if ( !the_mutex->nest_count )
+ return( CORE_MUTEX_STATUS_SUCCESSFUL );
+
the_mutex->nest_count--;
if ( the_mutex->nest_count != 0 )
- return( CORE_MUTEX_STATUS_SUCCESSFUL );
+ return( CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED );
_Thread_Executing->resource_count--;
the_mutex->holder = NULL;
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index e483267102..7452d72394 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -7,7 +7,8 @@ ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
## sp10 and spfatal are not included for now
SUBDIRS = sp01 sp02 sp03 sp04 sp05 sp06 sp07 sp08 sp09 sp11 sp12 sp13 sp14 \
- sp15 sp16 sp17 sp19 sp20 sp21 sp22 sp23 sp24 sp25 sp26 sp27 sp28 spsize
+ sp15 sp16 sp17 sp19 sp20 sp21 sp22 sp23 sp24 sp25 sp26 sp27 sp28 sp29 \
+ spsize
EXTRA_DIST = sptests.am spfatal
diff --git a/testsuites/sptests/sp29/Makefile.am b/testsuites/sptests/sp29/Makefile.am
new file mode 100644
index 0000000000..ec543997de
--- /dev/null
+++ b/testsuites/sptests/sp29/Makefile.am
@@ -0,0 +1,36 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+TEST = sp29
+
+MANAGERS = all
+
+# C source names, if any, go here -- minus the .c
+C_FILES = init.c
+C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
+
+DOCTYPES = scn
+DOCS = $(DOCTYPES:%=$(TEST).%)
+
+SRCS = $(C_FILES) $(H_FILES)
+OBJS = $(C_O_FILES)
+
+PRINT_SRCS = $(DOCS)
+
+PGM = ${ARCH}/$(TEST).exe
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+include $(top_srcdir)/sptests.am
+
+${PGM}: $(OBJS) $(LINK_FILES)
+ $(make-exe)
+
+all-local: $(ARCH) $(TMPINSTALL_FILES)
+
+EXTRA_DIST = $(C_FILES) $(DOCS)
+
+include $(top_srcdir)/../../../../automake/local.am
diff --git a/testsuites/sptests/sp29/init.c b/testsuites/sptests/sp29/init.c
new file mode 100644
index 0000000000..032b1ac42e
--- /dev/null
+++ b/testsuites/sptests/sp29/init.c
@@ -0,0 +1,177 @@
+/*
+ * Test for rtems_semaphore_flush
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+
+rtems_task Init (rtems_task_argument argument);
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_INIT
+
+#include <confdefs.h>
+
+#include <rtems/error.h>
+#include <stdio.h>
+
+rtems_interval ticksPerSecond;
+
+rtems_task
+subtask (rtems_task_argument arg)
+{
+ int i;
+ rtems_status_code sc;
+ rtems_id sem = (rtems_id)arg;
+
+ for (;;) {
+ rtems_task_wake_after (ticksPerSecond * 2);
+
+ sc = rtems_semaphore_release (sem);
+ if (sc != RTEMS_SUCCESSFUL)
+ printf ("%d: Can't release semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+}
+
+void
+startTask (rtems_id arg)
+{
+ rtems_id tid;
+ rtems_status_code sc;
+
+ sc = rtems_task_create (rtems_build_name ('S', 'R', 'V', 'A'),
+ 100,
+ 10000,
+ RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &tid);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Can't create task: %s\n", rtems_status_text (sc));
+ rtems_task_suspend (RTEMS_SELF);
+ }
+ sc = rtems_task_start (tid, subtask, arg);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Can't start task: %s\n", rtems_status_text (sc));
+ rtems_task_suspend (RTEMS_SELF);
+ }
+}
+
+rtems_task Init (rtems_task_argument ignored)
+{
+ int i;
+ rtems_id semrec, semnorec;
+ rtems_status_code sc;
+ rtems_interval then, now;
+
+ sc = rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticksPerSecond);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Can't get ticks per second: %s\n", rtems_status_text (sc));
+ exit (1);
+ }
+ sc = rtems_semaphore_create (rtems_build_name ('S', 'M', 'r', 'c'),
+ 1,
+ RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY |RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
+ 0,
+ &semrec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't create recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ exit (1);
+ }
+ sc = rtems_semaphore_create (rtems_build_name ('S', 'M', 'n', 'c'),
+ 1,
+ RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_NO_NESTING_ALLOWED|RTEMS_INHERIT_PRIORITY |RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
+ 0,
+ &semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't create non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ exit (1);
+ }
+
+ sc = rtems_semaphore_obtain (semrec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't obtain recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semrec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't reobtain recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't obtain non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc == RTEMS_SUCCESSFUL) {
+ printf ("%d: Reobtain non-recursive-lock semaphore -- and should not have.\n", __LINE__);
+ }
+
+ sc = rtems_semaphore_release (semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't release non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_release (semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't rerelease non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't obtain non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc == RTEMS_SUCCESSFUL) {
+ printf ("%d: Reobtain non-recursive-lock semaphore -- and should not have.\n", __LINE__);
+ }
+ else if (sc != RTEMS_UNSATISFIED) {
+ printf ("%d: Reobtain non-recursive-lock semaphore failed, but error is %d (%s), not RTEMS_UNSATISFIED.\n", __LINE__, sc, rtems_status_text (sc));
+ }
+
+ sc = rtems_semaphore_release (semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't release non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_release (semnorec);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't rerelease non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_NO_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("%d: Can't obtain non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ }
+ /*
+ * Since this task is holding this, there is no reason to block.
+ * It is obviously an error to reobtain it.
+ */
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_WAIT, 5);
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ if (sc == RTEMS_SUCCESSFUL) {
+ printf ("%d: Reobtain non-recursive-lock semaphore -- and should not have.\n", __LINE__);
+ }
+ else if (sc != RTEMS_UNSATISFIED) {
+ printf ("%d: Reobtain non-recursive-lock semaphore failed, but error is %d (%s), not RTEMS_UNSATISFIED.\n", __LINE__, sc, rtems_status_text (sc));
+ }
+ if ((then - now) < 4)
+ printf ("%d: Reobtain non-recursive-lock semaphore failed without timeout.\n", __LINE__);
+
+ startTask (semnorec);
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
+ for (i = 0 ; i < 5 ; i++) {
+ int diff;
+
+ sc = rtems_semaphore_obtain (semnorec, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
+ diff = now - then;
+ then = now;
+ if (sc != RTEMS_SUCCESSFUL)
+ printf ("%d: Failed to obtain non-recursive-lock semaphore: %s\n", __LINE__, rtems_status_text (sc));
+ else if (diff < (2 * ticksPerSecond + 1))
+ printf ("%d: Obtained obtain non-recursive-lock semaphore too quickly -- %d ticks\n", __LINE__, diff);
+ }
+
+ exit (0);
+}
diff --git a/testsuites/sptests/sp29/sp29.doc b/testsuites/sptests/sp29/sp29.doc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testsuites/sptests/sp29/sp29.doc
diff --git a/testsuites/sptests/sp29/sp29.scn b/testsuites/sptests/sp29/sp29.scn
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testsuites/sptests/sp29/sp29.scn