From 7d91d722baf1f1ff275fd31500526bb2fd6df632 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 13 Dec 1999 15:29:20 +0000 Subject: 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. --- c/src/exec/rtems/include/rtems/rtems/attr.h | 6 +- c/src/exec/rtems/inline/rtems/rtems/attr.inl | 17 +++ c/src/exec/rtems/macros/rtems/rtems/attr.inl | 9 ++ c/src/exec/rtems/src/semcreate.c | 9 +- c/src/exec/rtems/src/semtranslatereturncode.c | 2 +- c/src/exec/score/src/coremutexseize.c | 1 + c/src/exec/score/src/coremutexsurrender.c | 31 +++-- c/src/tests/sptests/Makefile.am | 3 +- c/src/tests/sptests/configure.in | 1 + c/src/tests/sptests/sp29/Makefile.am | 36 ++++++ c/src/tests/sptests/sp29/init.c | 177 ++++++++++++++++++++++++++ c/src/tests/sptests/sp29/sp29.doc | 0 c/src/tests/sptests/sp29/sp29.scn | 0 13 files changed, 274 insertions(+), 18 deletions(-) create mode 100644 c/src/tests/sptests/sp29/Makefile.am create mode 100644 c/src/tests/sptests/sp29/init.c create mode 100644 c/src/tests/sptests/sp29/sp29.doc create mode 100644 c/src/tests/sptests/sp29/sp29.scn (limited to 'c') 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 @@ -156,6 +156,23 @@ RTEMS_INLINE_ROUTINE boolean _Attributes_Is_priority_ceiling( return ( attribute_set & RTEMS_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 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 @@ -88,6 +88,15 @@ #define _Attributes_Is_priority_ceiling( _attribute_set ) \ ( (_attribute_set) & RTEMS_PRIORITY_CEILING ) +/*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 + +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 + +#include +#include + +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 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 -- cgit v1.2.3