[PATCH 1/3] Fix semaphore post overflow status

Sebastian Huber sebastian.huber at embedded-brains.de
Wed May 25 13:48:56 UTC 2016


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 d7b99ea..04b293d 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 86d2f5a..f4633dc 100644
--- a/cpukit/posix/src/sempost.c
+++ b/cpukit/posix/src/sempost.c
@@ -19,6 +19,7 @@
 #endif
 
 #include <semaphore.h>
+#include <limits.h>
 
 #include <rtems/posix/semaphoreimpl.h>
 
@@ -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 197e4d8..aa80e83 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 9aa9420..ea7e8bc 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 1660c1d..5dad11b 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 4022a80..3442bbd 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 24f6d96..1bec5c6 100644
--- a/testsuites/psxtests/psxsem01/init.c
+++ b/testsuites/psxtests/psxsem01/init.c
@@ -15,6 +15,7 @@
 #include <semaphore.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <time.h>
 #include <tmacros.h>
 #include <pmacros.h>
@@ -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 897581a..39a366b 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 00d363d..b617219 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 ***
-- 
1.8.4.5



More information about the devel mailing list