[rtems commit] score: Fix blocking _CORE_message_queue_Submit()

Sebastian Huber sebh at rtems.org
Tue May 24 13:37:46 UTC 2016


Module:    rtems
Branch:    master
Commit:    4b623d655bb4f4853a6ce385ae17e505dddbe7ce
Changeset: http://git.rtems.org/rtems/commit/?id=4b623d655bb4f4853a6ce385ae17e505dddbe7ce

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue May 24 07:40:18 2016 +0200

score: Fix blocking _CORE_message_queue_Submit()

Close #2718.

---

 cpukit/posix/src/mqueuesendsupp.c              | 11 ----
 cpukit/posix/src/mqueuetranslatereturncode.c   |  3 +-
 cpukit/score/include/rtems/score/coremsgimpl.h |  4 +-
 cpukit/score/src/coremsgsubmit.c               |  3 +-
 testsuites/psxtests/psxmsgq01/init.c           | 77 ++++++++++++++++++++++++++
 testsuites/psxtests/psxmsgq01/psxmsgq01.scn    |  1 +
 6 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/cpukit/posix/src/mqueuesendsupp.c b/cpukit/posix/src/mqueuesendsupp.c
index 0d9974a..f13339f 100644
--- a/cpukit/posix/src/mqueuesendsupp.c
+++ b/cpukit/posix/src/mqueuesendsupp.c
@@ -105,17 +105,6 @@ int _POSIX_Message_queue_Send_support(
     &lock_context
   );
 
-  /*
-   *  If we had to block, then this is where the task returns
-   *  after it wakes up.  The returned status is correct for
-   *  non-blocking operations but if we blocked, then we need
-   *  to look at the status in our TCB.
-   */
-
-  if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT ) {
-    msg_status = executing->Wait.return_code;
-  }
-
   if ( msg_status != CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL ) {
     rtems_set_errno_and_return_minus_one(
       _POSIX_Message_queue_Translate_core_message_queue_return_code(
diff --git a/cpukit/posix/src/mqueuetranslatereturncode.c b/cpukit/posix/src/mqueuetranslatereturncode.c
index 30d1c57..901d5aa 100644
--- a/cpukit/posix/src/mqueuetranslatereturncode.c
+++ b/cpukit/posix/src/mqueuetranslatereturncode.c
@@ -46,8 +46,7 @@ static
   ENOMEM,                /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED */
   EAGAIN,                /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT */
   EBADF,                 /* CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED */
-  ETIMEDOUT,             /* CORE_MESSAGE_QUEUE_STATUS_TIMEOUT */
-  ENOSYS                 /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT */
+  ETIMEDOUT              /* CORE_MESSAGE_QUEUE_STATUS_TIMEOUT */
 };
 
 
diff --git a/cpukit/score/include/rtems/score/coremsgimpl.h b/cpukit/score/include/rtems/score/coremsgimpl.h
index 34f214d..395d44d 100644
--- a/cpukit/score/include/rtems/score/coremsgimpl.h
+++ b/cpukit/score/include/rtems/score/coremsgimpl.h
@@ -89,8 +89,6 @@ typedef enum {
    *  to receive a message because one did not become available.
    */
   CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
-  /** This value indicates that a blocking receive was unsuccessful. */
-  CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT
 }   CORE_message_queue_Status;
 
 /**
@@ -98,7 +96,7 @@ typedef enum {
  *
  *  This is the last status value.
  */
-#define CORE_MESSAGE_QUEUE_STATUS_LAST CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT
+#define CORE_MESSAGE_QUEUE_STATUS_LAST CORE_MESSAGE_QUEUE_STATUS_TIMEOUT
 
 /**
  *  @brief Initialize a message queue.
diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c
index 7e589e7..91fb332 100644
--- a/cpukit/score/src/coremsgsubmit.c
+++ b/cpukit/score/src/coremsgsubmit.c
@@ -133,6 +133,7 @@ CORE_message_queue_Status _CORE_message_queue_Do_submit(
      *  it as a variable.  Doing this emphasizes how dangerous it
      *  would be to use this variable prior to here.
      */
+    executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
     executing->Wait.return_argument_second.immutable_object = buffer;
     executing->Wait.option = (uint32_t) size;
     executing->Wait.count = submit_type;
@@ -146,6 +147,6 @@ CORE_message_queue_Status _CORE_message_queue_Do_submit(
       CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
       lock_context
     );
-    return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT;
+    return executing->Wait.return_code;
   #endif
 }
diff --git a/testsuites/psxtests/psxmsgq01/init.c b/testsuites/psxtests/psxmsgq01/init.c
index 0c34cd9..3243a40 100644
--- a/testsuites/psxtests/psxmsgq01/init.c
+++ b/testsuites/psxtests/psxmsgq01/init.c
@@ -1259,6 +1259,82 @@ void verify_mq_send(void)
   }
 }
 
+static void *receive_maxmsg_plus_one( void *arg )
+{
+  mqd_t                 mq;
+  const Test_Message_t *m;
+  int                   i;
+
+  mq = Test_q[ BLOCKING ].mq;
+  m = &Predefined_Msgs[ 0 ];
+
+  for ( i = 0; i < MAXMSG + 1; ++i ) {
+    Test_Message_t a;
+    unsigned       prio;
+    ssize_t        n;
+
+    n = mq_receive( mq, &a.msg[0], sizeof(a.msg), &prio);
+    rtems_test_assert( n == m->size );
+    rtems_test_assert( prio == m->priority );
+    rtems_test_assert( memcmp( &a.msg[0], &m->msg[0], (size_t) n ) == 0 );
+  }
+
+  return arg;
+}
+
+static void verify_blocking_mq_timedsend( void )
+{
+  mqd_t                 mq;
+  const Test_Message_t *m;
+  int                   status;
+  struct timespec       timeout;
+  pthread_t             thread;
+  void                 *exit_value;
+  rtems_status_code     sc;
+
+  Start_Test( "verify_blocking_mq_timedsend"  );
+
+  mq = Test_q[ BLOCKING ].mq;
+  m = &Predefined_Msgs[ 0 ];
+
+  /*
+   * Create and suspend the receive thread early so that we don't overwrite the
+   * ETIMEDOUT in executing->Wait.return_code.  This verifies the succesful
+   * mq_timedreceive() later.
+   */
+
+  status = pthread_create( &thread, NULL, receive_maxmsg_plus_one, &thread );
+  fatal_posix_service_status( status, 0, "pthread_create" );
+
+  sc = rtems_task_suspend( thread );
+  fatal_directive_status( sc, RTEMS_SUCCESSFUL, "rtems_task_suspend" );
+
+  do {
+    status = clock_gettime( CLOCK_REALTIME, &timeout );
+    fatal_posix_service_status( status, 0, "clock_gettime" );
+    ++timeout.tv_sec;
+
+    status = mq_timedsend( mq, m->msg, m->size , m->priority, &timeout );
+  } while ( status == 0 );
+
+  fatal_posix_service_status_errno( status, ETIMEDOUT, "mq_timedsend");
+
+  sc = rtems_task_resume( thread );
+  fatal_directive_status( sc, RTEMS_SUCCESSFUL, "rtems_task_restart" );
+
+  status = clock_gettime( CLOCK_REALTIME, &timeout );
+  fatal_posix_service_status( status, 0, "clock_gettime" );
+  ++timeout.tv_sec;
+
+  status = mq_timedsend( mq, m->msg, m->size , m->priority, &timeout );
+  fatal_posix_service_status( status, 0, "mq_timedsend" );
+
+  exit_value = NULL;
+  status = pthread_join( thread, &exit_value );
+  fatal_posix_service_status( status, 0, "pthread_join" );
+  rtems_test_assert( exit_value == &thread );
+}
+
 void *POSIX_Init(
   void *argument
 )
@@ -1267,6 +1343,7 @@ void *POSIX_Init(
 
   validate_mq_open_error_codes( );
   open_test_queues();
+  verify_blocking_mq_timedsend();
   validate_mq_unlink_error_codes();
   validate_mq_close_error_codes();
   verify_unlink_functionality();
diff --git a/testsuites/psxtests/psxmsgq01/psxmsgq01.scn b/testsuites/psxtests/psxmsgq01/psxmsgq01.scn
index 70da5f3..4705bcf 100644
--- a/testsuites/psxtests/psxmsgq01/psxmsgq01.scn
+++ b/testsuites/psxtests/psxmsgq01/psxmsgq01.scn
@@ -9,6 +9,7 @@ Init: mq_open - SUCCESSFUL
 Init: mq_open - system is out of resources (ENFILE)
 Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL
 Init: Open Test Queues
+_______________verify_blocking_mq_timedsend
 _______________mq_unlink errors
 Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)
 Init: mq_unlink - A Queue not opened  (ENOENT)




More information about the vc mailing list