From 39bcf7417ea39806e4817a9ce72cfc20c060c4bf Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 25 May 2016 14:23:48 +0200 Subject: Fix semaphore post overflow status Close #2720. --- cpukit/posix/src/semaphoretranslatereturncode.c | 5 +--- cpukit/posix/src/sempost.c | 14 ++++++++-- cpukit/rtems/src/semrelease.c | 1 + cpukit/rtems/src/semtranslatereturncode.c | 2 +- cpukit/score/include/rtems/score/coresemimpl.h | 3 ++- cpukit/score/src/mpci.c | 2 +- testsuites/psxtests/psxsem01/init.c | 34 +++++++++++++++++++++++++ testsuites/sptests/spsem_err01/init.c | 29 +++++++++++++++++++++ testsuites/sptests/spsem_err01/spsem_err01.scn | 7 +++-- 9 files changed, 86 insertions(+), 11 deletions(-) diff --git a/cpukit/posix/src/semaphoretranslatereturncode.c b/cpukit/posix/src/semaphoretranslatereturncode.c index d7b99eaf67..04b293d349 100644 --- a/cpukit/posix/src/semaphoretranslatereturncode.c +++ b/cpukit/posix/src/semaphoretranslatereturncode.c @@ -27,8 +27,5 @@ const int _POSIX_Semaphore_Return_codes[CORE_SEMAPHORE_STATUS_LAST + 1] = { EAGAIN, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */ EINVAL, /* CORE_SEMAPHORE_WAS_DELETED */ ETIMEDOUT, /* CORE_SEMAPHORE_TIMEOUT */ - /* The next error can not occur since we set the maximum - * count to the largest value the count can hold. - */ - ENOSYS, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */ + EOVERFLOW /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */ }; diff --git a/cpukit/posix/src/sempost.c b/cpukit/posix/src/sempost.c index 86d2f5acf6..f4633dcf70 100644 --- a/cpukit/posix/src/sempost.c +++ b/cpukit/posix/src/sempost.c @@ -19,6 +19,7 @@ #endif #include +#include #include @@ -28,6 +29,7 @@ int sem_post( { POSIX_Semaphore_Control *the_semaphore; Thread_queue_Context queue_context; + CORE_semaphore_Status status; the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context ); @@ -35,9 +37,17 @@ int sem_post( rtems_set_errno_and_return_minus_one( EINVAL ); } - _CORE_semaphore_Surrender( + status = _CORE_semaphore_Surrender( &the_semaphore->Semaphore, + SEM_VALUE_MAX, &queue_context ); - return 0; + + if ( status == CORE_SEMAPHORE_STATUS_SUCCESSFUL ) { + return 0; + } + + rtems_set_errno_and_return_minus_one( + _POSIX_Semaphore_Translate_core_semaphore_return_code( status ) + ); } diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c index 197e4d81b0..aa80e8385f 100644 --- a/cpukit/rtems/src/semrelease.c +++ b/cpukit/rtems/src/semrelease.c @@ -68,6 +68,7 @@ rtems_status_code rtems_semaphore_release( rtems_id id ) } else { semaphore_status = _CORE_semaphore_Surrender( &the_semaphore->Core_control.semaphore, + UINT32_MAX, &queue_context ); return _Semaphore_Translate_core_semaphore_return_code( semaphore_status ); diff --git a/cpukit/rtems/src/semtranslatereturncode.c b/cpukit/rtems/src/semtranslatereturncode.c index 9aa94206be..ea7e8bcb6b 100644 --- a/cpukit/rtems/src/semtranslatereturncode.c +++ b/cpukit/rtems/src/semtranslatereturncode.c @@ -37,5 +37,5 @@ const rtems_status_code _Semaphore_Translate_core_semaphore_return_code_[] = { RTEMS_UNSATISFIED, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */ RTEMS_OBJECT_WAS_DELETED, /* CORE_SEMAPHORE_WAS_DELETED */ RTEMS_TIMEOUT, /* CORE_SEMAPHORE_TIMEOUT */ - RTEMS_INTERNAL_ERROR, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */ + RTEMS_UNSATISFIED /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */ }; diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h index 1660c1d089..5dad11bc46 100644 --- a/cpukit/score/include/rtems/score/coresemimpl.h +++ b/cpukit/score/include/rtems/score/coresemimpl.h @@ -149,6 +149,7 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy( */ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender( CORE_semaphore_Control *the_semaphore, + uint32_t maximum_count, Thread_queue_Context *queue_context ) { @@ -171,7 +172,7 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender( queue_context ); } else { - if ( the_semaphore->count < UINT32_MAX ) + if ( the_semaphore->count < maximum_count ) the_semaphore->count += 1; else status = CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED; diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c index 4022a800f1..3442bbd2c7 100644 --- a/cpukit/score/src/mpci.c +++ b/cpukit/score/src/mpci.c @@ -374,7 +374,7 @@ void _MPCI_Announce ( void ) Thread_queue_Context queue_context; _ISR_lock_ISR_disable( &queue_context.Lock_context ); - (void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, &queue_context ); + (void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, UINT32_MAX, &queue_context ); } void _MPCI_Internal_packets_Send_process_packet ( diff --git a/testsuites/psxtests/psxsem01/init.c b/testsuites/psxtests/psxsem01/init.c index 24f6d96465..1bec5c65a7 100644 --- a/testsuites/psxtests/psxsem01/init.c +++ b/testsuites/psxtests/psxsem01/init.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,38 @@ static void test_sem_wait_during_delete(void) rtems_test_assert( eno == 0 ); } +static void test_sem_post_overflow(void) +{ + sem_t sem; + int rv; + int val; + + rv = sem_init( &sem, 0, SEM_VALUE_MAX ); + rtems_test_assert( rv == 0 ); + + rv = sem_getvalue( &sem, &val ); + rtems_test_assert( rv == 0 ); + rtems_test_assert( val == (int) SEM_VALUE_MAX ); + + errno = 0; + rv = sem_post( &sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EOVERFLOW ); + + rv = sem_getvalue( &sem, &val ); + rtems_test_assert( rv == 0 ); + rtems_test_assert( val == (int) SEM_VALUE_MAX ); + + rv = sem_wait( &sem ); + rtems_test_assert( rv == 0 ); + + rv = sem_post( &sem ); + rtems_test_assert( rv == 0 ); + + rv = sem_destroy( &sem ); + rtems_test_assert( rv == 0 ); +} + void *POSIX_Init( void *argument ) @@ -345,6 +378,7 @@ void *POSIX_Init( rtems_test_assert( (status == -1) && (errno == ENOENT) ); test_sem_wait_during_delete(); + test_sem_post_overflow(); /* Try adding in unlinking before closing... (can we still open?) */ diff --git a/testsuites/sptests/spsem_err01/init.c b/testsuites/sptests/spsem_err01/init.c index 897581ac94..39a366b41a 100644 --- a/testsuites/sptests/spsem_err01/init.c +++ b/testsuites/sptests/spsem_err01/init.c @@ -30,6 +30,35 @@ rtems_task Init( Semaphore_name[ 2 ] = rtems_build_name( 'S', 'M', '2', ' ' ); Semaphore_name[ 3 ] = rtems_build_name( 'S', 'M', '3', ' ' ); + /* release overflow */ + status = rtems_semaphore_create( + Semaphore_name[ 1 ], + UINT32_MAX, + RTEMS_COUNTING_SEMAPHORE, + 0, + &Semaphore_id[ 1 ] + ); + fatal_directive_status( + status, + RTEMS_SUCCESSFUL, + "rtems_semaphore_create" + ); + puts( "TA1 - rtems_semaphore_create - RTEMS_SUCCESSFUL" ); + status = rtems_semaphore_release( Semaphore_id[ 1 ] ); + fatal_directive_status( + status, + RTEMS_UNSATISFIED, + "rtems_semaphore_release" + ); + puts( "TA1 - rtems_semaphore_release - RTEMS_UNSATISFIED" ); + status = rtems_semaphore_delete( Semaphore_id[ 1 ] ); + fatal_directive_status( + status, + RTEMS_SUCCESSFUL, + "rtems_semaphore_delete" + ); + puts( "TA1 - rtems_semaphore_delete - RTEMS_SUCCESSFUL" ); + /* invalid name */ status = rtems_semaphore_create( 0, diff --git a/testsuites/sptests/spsem_err01/spsem_err01.scn b/testsuites/sptests/spsem_err01/spsem_err01.scn index 00d363d15f..b6172196b0 100644 --- a/testsuites/sptests/spsem_err01/spsem_err01.scn +++ b/testsuites/sptests/spsem_err01/spsem_err01.scn @@ -1,4 +1,7 @@ -*** TEST SEMAPHORE ERROR 01 *** +*** BEGIN OF TEST SP SEMAPHORE ERROR 01 *** +TA1 - rtems_semaphore_create - RTEMS_SUCCESSFUL +TA1 - rtems_semaphore_release - RTEMS_UNSATISFIED +TA1 - rtems_semaphore_delete - RTEMS_SUCCESSFUL TA1 - rtems_semaphore_create - RTEMS_INVALID_NAME TA1 - rtems_semaphore_create - RTEMS_INVALID_ADDRESS TA1 - rtems_semaphore_create - 1 - RTEMS_SUCCESSFUL @@ -16,4 +19,4 @@ TA1 - rtems_semaphore_ident - global RTEMS_INVALID_NAME TA1 - rtems_semaphore_ident - local RTEMS_INVALID_NAME TA1 - rtems_semaphore_release - RTEMS_INVALID_ID TA1 - rtems_semaphore_flush - RTEMS_INVALID_ID -*** END TEST SEMAPHORE ERROR 01 *** +*** END OF TEST SP SEMAPHORE ERROR 01 *** -- cgit v1.2.3