[PATCH 06/20] score: Fix _CORE_semaphore_Flush()

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Apr 19 13:12:34 UTC 2016


Use proper CORE_semaphore_Status for _CORE_semaphore_Flush() and
_CORE_semaphore_Destroy() operations.

Close #2696.
---
 cpukit/posix/include/rtems/posix/semaphoreimpl.h |  1 -
 cpukit/posix/src/semaphorecreatesupp.c           | 12 +++---
 cpukit/posix/src/semaphoredeletesupp.c           |  2 +-
 cpukit/posix/src/semaphoretranslatereturncode.c  |  2 +-
 cpukit/rtems/src/semdelete.c                     |  6 +--
 cpukit/rtems/src/semflush.c                      |  1 -
 cpukit/score/include/rtems/score/coresemimpl.h   | 26 ++++++++----
 testsuites/psxtests/psxsem01/init.c              | 52 +++++++++++++++++++++++-
 8 files changed, 79 insertions(+), 23 deletions(-)

diff --git a/cpukit/posix/include/rtems/posix/semaphoreimpl.h b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
index 8608e6f..41bfdad 100644
--- a/cpukit/posix/include/rtems/posix/semaphoreimpl.h
+++ b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
@@ -58,7 +58,6 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free (
   POSIX_Semaphore_Control *the_semaphore
 )
 {
-  _CORE_semaphore_Destroy( &the_semaphore->Semaphore );
   _Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object );
 }
 
diff --git a/cpukit/posix/src/semaphorecreatesupp.c b/cpukit/posix/src/semaphorecreatesupp.c
index 9a24e0a..79db888 100644
--- a/cpukit/posix/src/semaphorecreatesupp.c
+++ b/cpukit/posix/src/semaphorecreatesupp.c
@@ -54,11 +54,6 @@ int _POSIX_Semaphore_Create_support(
   if (pshared != 0)
     rtems_set_errno_and_return_minus_one( ENOSYS );
 
-  the_semaphore = _POSIX_Semaphore_Allocate_unprotected();
-  if ( !the_semaphore ) {
-    rtems_set_errno_and_return_minus_one( ENOSPC );
-  }
-
   /*
    * Make a copy of the user's string for name just in case it was
    * dynamically constructed.
@@ -66,13 +61,18 @@ int _POSIX_Semaphore_Create_support(
   if ( name_arg != NULL ) {
     name = _Workspace_String_duplicate( name_arg, name_len );
     if ( !name ) {
-      _POSIX_Semaphore_Free( the_semaphore );
       rtems_set_errno_and_return_minus_one( ENOMEM );
     }
   } else {
     name = NULL;
   }
 
+  the_semaphore = _POSIX_Semaphore_Allocate_unprotected();
+  if ( !the_semaphore ) {
+    _Workspace_Free( name );
+    rtems_set_errno_and_return_minus_one( ENOSPC );
+  }
+
   the_semaphore->process_shared  = pshared;
 
   if ( name ) {
diff --git a/cpukit/posix/src/semaphoredeletesupp.c b/cpukit/posix/src/semaphoredeletesupp.c
index 650cdcd..43946746 100644
--- a/cpukit/posix/src/semaphoredeletesupp.c
+++ b/cpukit/posix/src/semaphoredeletesupp.c
@@ -36,7 +36,7 @@ void _POSIX_Semaphore_Delete(
 {
   if ( !the_semaphore->linked && !the_semaphore->open_count ) {
     _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
-    _CORE_semaphore_Flush( &the_semaphore->Semaphore, -1, NULL, 0 );
+    _CORE_semaphore_Destroy( &the_semaphore->Semaphore, NULL, 0 );
     _POSIX_Semaphore_Free( the_semaphore );
   }
 }
diff --git a/cpukit/posix/src/semaphoretranslatereturncode.c b/cpukit/posix/src/semaphoretranslatereturncode.c
index 37e7d07..d7b99ea 100644
--- a/cpukit/posix/src/semaphoretranslatereturncode.c
+++ b/cpukit/posix/src/semaphoretranslatereturncode.c
@@ -25,7 +25,7 @@
 const int _POSIX_Semaphore_Return_codes[CORE_SEMAPHORE_STATUS_LAST + 1] = {
   0,                   /* CORE_SEMAPHORE_STATUS_SUCCESSFUL */
   EAGAIN,              /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */
-  EAGAIN,              /* CORE_SEMAPHORE_WAS_DELETED */
+  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.
diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c
index 6a83d25..d3d6264 100644
--- a/cpukit/rtems/src/semdelete.c
+++ b/cpukit/rtems/src/semdelete.c
@@ -73,13 +73,11 @@ rtems_status_code rtems_semaphore_delete(
         );
         _CORE_mutex_Destroy( &the_semaphore->Core_control.mutex );
       } else {
-        _CORE_semaphore_Flush(
+        _CORE_semaphore_Destroy(
           &the_semaphore->Core_control.semaphore,
-          CORE_SEMAPHORE_WAS_DELETED,
           _Semaphore_MP_Send_object_was_deleted,
           id
-        );
-        _CORE_semaphore_Destroy( &the_semaphore->Core_control.semaphore );
+        )
       }
 
       _Objects_Close( &_Semaphore_Information, &the_semaphore->Object );
diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c
index ea06883..64386b0 100644
--- a/cpukit/rtems/src/semflush.c
+++ b/cpukit/rtems/src/semflush.c
@@ -60,7 +60,6 @@ rtems_status_code rtems_semaphore_flush(
       } else {
         _CORE_semaphore_Flush(
           &the_semaphore->Core_control.semaphore,
-          CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT,
           _Semaphore_MP_Send_object_was_deleted,
           id
         );
diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h
index 79d907c..d68c3d7 100644
--- a/cpukit/score/include/rtems/score/coresemimpl.h
+++ b/cpukit/score/include/rtems/score/coresemimpl.h
@@ -86,12 +86,22 @@ void _CORE_semaphore_Initialize(
   uint32_t                    initial_value
 );
 
-RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
-  CORE_semaphore_Control *the_semaphore
-)
-{
-  _Thread_queue_Destroy( &the_semaphore->Wait_queue );
-}
+#define _CORE_semaphore_Destroy( \
+  the_semaphore, \
+  mp_callout, \
+  mp_id \
+) \
+  do { \
+    _Thread_queue_Flush( \
+      &( the_semaphore )->Wait_queue, \
+      ( the_semaphore )->operations, \
+      CORE_SEMAPHORE_WAS_DELETED, \
+      mp_callout, \
+      mp_id, \
+      &_core_semaphore_flush_lock_context \
+    ); \
+    _Thread_queue_Destroy( &( the_semaphore )->Wait_queue ); \
+  } while ( 0 )
 
 RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Do_surrender(
   CORE_semaphore_Control  *the_semaphore,
@@ -180,14 +190,14 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Do_surrender(
 /* Must be a macro due to the multiprocessing dependent parameters */
 #define _CORE_semaphore_Flush( \
   the_semaphore, \
-  status, \
+  CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT, \
   mp_callout, \
   mp_id \
 ) \
   _Thread_queue_Flush( \
     &( the_semaphore )->Wait_queue, \
     ( the_semaphore )->operations, \
-    status, \
+    CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT, \
     mp_callout, \
     mp_id \
   )
diff --git a/testsuites/psxtests/psxsem01/init.c b/testsuites/psxtests/psxsem01/init.c
index c1752f3..24f6d96 100644
--- a/testsuites/psxtests/psxsem01/init.c
+++ b/testsuites/psxtests/psxsem01/init.c
@@ -27,6 +27,55 @@ void *POSIX_Init(void *argument);
 
 #define MAX_SEMS  10
 
+static void *sem_wait_task(void *arg)
+{
+  sem_t *sem;
+  int    rv;
+
+  sem = arg;
+
+  rv = sem_wait( sem );
+  rtems_test_assert( rv == 0 );
+
+  errno = 0;
+  rv = sem_wait( sem );
+  rtems_test_assert( rv == -1 );
+  rtems_test_assert( errno == EINVAL );
+
+  return NULL;
+}
+
+static void test_sem_wait_during_delete(void)
+{
+  sem_t     sem;
+  int       rv;
+  pthread_t th;
+  int       eno;
+  int       val;
+
+  rv = sem_init( &sem, 0, 1 );
+  rtems_test_assert( rv == 0 );
+
+  eno = pthread_create( &th, NULL, sem_wait_task, &sem );
+  rtems_test_assert( eno == 0 );
+
+  rv = sem_getvalue( &sem, &val );
+  rtems_test_assert( rv == 0 );
+  rtems_test_assert( val == 1 );
+
+  sched_yield();
+
+  rv = sem_getvalue( &sem, &val );
+  rtems_test_assert( rv == 0 );
+  rtems_test_assert( val == 0 );
+
+  rv = sem_destroy( &sem );
+  rtems_test_assert( rv == 0 );
+
+  eno = pthread_join( th, NULL );
+  rtems_test_assert( eno == 0 );
+}
+
 void *POSIX_Init(
   void *argument
 )
@@ -295,6 +344,7 @@ void *POSIX_Init(
   fatal_posix_service_status( errno, ENOENT, "sem_unlink errno ENOENT");
   rtems_test_assert( (status == -1) && (errno == ENOENT) );
 
+  test_sem_wait_during_delete();
 
   /* Try adding in unlinking before closing... (can we still open?) */
 
@@ -312,7 +362,7 @@ void *POSIX_Init(
 
 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
 
-#define CONFIGURE_MAXIMUM_POSIX_THREADS     1
+#define CONFIGURE_MAXIMUM_POSIX_THREADS     2
 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES  MAX_SEMS
 
 #define CONFIGURE_POSIX_INIT_THREAD_TABLE
-- 
1.8.4.5



More information about the devel mailing list