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.
This commit is contained in:
Joel Sherrill
1999-12-13 15:29:20 +00:00
parent e906798937
commit 7d91d722ba
25 changed files with 547 additions and 36 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 ????? */

View File

@@ -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:

View File

@@ -90,6 +90,7 @@ void _CORE_mutex_Seize(
);
}
}
executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
return;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -66,6 +66,7 @@ sp25/Makefile
sp26/Makefile
sp27/Makefile
sp28/Makefile
sp29/Makefile
spsize/Makefile
)

View File

@@ -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

View File

@@ -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);
}

View File

View File

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 ????? */

View File

@@ -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:

View File

@@ -90,6 +90,7 @@ void _CORE_mutex_Seize(
);
}
}
executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
return;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

View File