[PATCH 5/8] score: Simplify CORE_message_queue_Buffer

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Sep 24 12:12:52 UTC 2020


Merge CORE_message_queue_Buffer structure into
CORE_message_queue_Buffer_control.

Use a zero-length array for the actual message buffer.  This reduces the
structure size on all targets.

Update #4007.
---
 cpukit/include/rtems/confdefs/wkspace.h  |  2 +-
 cpukit/include/rtems/rtems/msgmp.h       |  7 ++--
 cpukit/include/rtems/score/coremsg.h     | 53 +++++++++++-------------
 cpukit/include/rtems/score/coremsgimpl.h | 16 +++----
 cpukit/rtems/src/msgmp.c                 | 20 ++++-----
 cpukit/score/src/coremsg.c               | 13 ++++--
 cpukit/score/src/coremsginsert.c         | 20 ++++-----
 cpukit/score/src/coremsgseize.c          | 10 ++---
 cpukit/score/src/coremsgsubmit.c         |  4 +-
 testsuites/sptests/spmsgq_err01/init.c   |  3 +-
 10 files changed, 72 insertions(+), 76 deletions(-)

diff --git a/cpukit/include/rtems/confdefs/wkspace.h b/cpukit/include/rtems/confdefs/wkspace.h
index 3b464899dc..89d7c21b2a 100644
--- a/cpukit/include/rtems/confdefs/wkspace.h
+++ b/cpukit/include/rtems/confdefs/wkspace.h
@@ -71,7 +71,7 @@
 #define CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( _messages, _size ) \
   _Configure_From_workspace( \
     ( _messages ) * ( _Configure_Align_up( _size, sizeof( uintptr_t ) ) \
-        + sizeof( CORE_message_queue_Buffer_control ) ) )
+        + sizeof( CORE_message_queue_Buffer ) ) )
 
 #ifndef CONFIGURE_MESSAGE_BUFFER_MEMORY
   #define CONFIGURE_MESSAGE_BUFFER_MEMORY 0
diff --git a/cpukit/include/rtems/rtems/msgmp.h b/cpukit/include/rtems/rtems/msgmp.h
index 6b08c86971..8638e9748e 100644
--- a/cpukit/include/rtems/rtems/msgmp.h
+++ b/cpukit/include/rtems/rtems/msgmp.h
@@ -71,13 +71,12 @@ typedef struct {
   rtems_option                       option_set;
   Objects_Id                         proxy_id;
   uint32_t                           count;
-  size_t                             size;
-  uint32_t                           pad0;
-  CORE_message_queue_Buffer          Buffer;
+  uint32_t                           size;
+  uint32_t                           buffer[ RTEMS_ZERO_LENGTH_ARRAY ];
 }   Message_queue_MP_Packet;
 
 #define MESSAGE_QUEUE_MP_PACKET_SIZE \
-  offsetof(Message_queue_MP_Packet, Buffer.buffer)
+  offsetof(Message_queue_MP_Packet, buffer)
 
 RTEMS_INLINE_ROUTINE bool _Message_queue_MP_Is_remote( Objects_Id id )
 {
diff --git a/cpukit/include/rtems/score/coremsg.h b/cpukit/include/rtems/score/coremsg.h
index cabf08b0ca..2131fa0765 100644
--- a/cpukit/include/rtems/score/coremsg.h
+++ b/cpukit/include/rtems/score/coremsg.h
@@ -68,37 +68,34 @@ extern "C" {
 typedef struct CORE_message_queue_Control CORE_message_queue_Control;
 
 /**
- *  @brief Data types needed to manipulate the contents of message buffers.
- *
- *  The following defines the data types needed to manipulate
- *  the contents of message buffers.
- *
- *  @note  The buffer field is normally longer than a single uint32_t
- *         but since messages are variable length we just make a ptr to 1.
+ * @brief The structure is used to organize message buffers of a message queue.
  */
 typedef struct {
-  /** This field is the size of this message. */
-  size_t      size;
-  /** This field contains the actual message. */
-  uint32_t    buffer[1];
-} CORE_message_queue_Buffer;
+  /**
+   * @brief This member is used to enqueue the buffer in the pending or free
+   *   buffer queue of a message queue.
+   */
+  Chain_Node Node;
 
-/**
- *  @brief The organization of a message buffer.
- *
- *  The following records define the organization of a message
- *  buffer.
- */
-typedef struct {
-  /** This element allows this structure to be placed on chains. */
-  Chain_Node                 Node;
-  #if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
-    /** This field is the priority of this message. */
-    int                        priority;
-  #endif
-  /** This field points to the contents of the message. */
-  CORE_message_queue_Buffer  Contents;
-}   CORE_message_queue_Buffer_control;
+  /** @brief This member defines the size of this message. */
+  size_t size;
+
+#if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
+  /** @brief This member defines the priority of this message. */
+  int priority;
+#endif
+
+  /**
+   * @brief This member contains the actual message.
+   *
+   * This is a zero-length array since the maximum message size is defined by
+   * the user.  Use a size_t array to make sure that the member offset is at
+   * the structure end.  This enables a more efficient memcpy() on 64-bit
+   * targets and makes it easier to inspect the message buffers with a
+   * debugger.
+   */
+  size_t buffer[ RTEMS_ZERO_LENGTH_ARRAY ];
+} CORE_message_queue_Buffer;
 
 /**
  *  @brief The possible blocking disciplines for a message queue.
diff --git a/cpukit/include/rtems/score/coremsgimpl.h b/cpukit/include/rtems/score/coremsgimpl.h
index 9403fb95fc..cb84bfb207 100644
--- a/cpukit/include/rtems/score/coremsgimpl.h
+++ b/cpukit/include/rtems/score/coremsgimpl.h
@@ -276,7 +276,7 @@ Status_Control _CORE_message_queue_Seize(
  */
 void _CORE_message_queue_Insert_message(
   CORE_message_queue_Control        *the_message_queue,
-  CORE_message_queue_Buffer_control *the_message,
+  CORE_message_queue_Buffer         *the_message,
   const void                        *content_source,
   size_t                             content_size,
   CORE_message_queue_Submit_types    submit_type
@@ -426,12 +426,12 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Copy_buffer (
  * @retval pointer The allocated message buffer.
  * @retval NULL The inactive message buffer chain is empty.
  */
-RTEMS_INLINE_ROUTINE CORE_message_queue_Buffer_control *
+RTEMS_INLINE_ROUTINE CORE_message_queue_Buffer *
 _CORE_message_queue_Allocate_message_buffer (
     CORE_message_queue_Control *the_message_queue
 )
 {
-   return (CORE_message_queue_Buffer_control *)
+   return (CORE_message_queue_Buffer *)
      _Chain_Get_unprotected( &the_message_queue->Inactive_messages );
 }
 
@@ -445,8 +445,8 @@ _CORE_message_queue_Allocate_message_buffer (
  * @param[out] the_message The message to be freed.
  */
 RTEMS_INLINE_ROUTINE void _CORE_message_queue_Free_message_buffer (
-  CORE_message_queue_Control        *the_message_queue,
-  CORE_message_queue_Buffer_control *the_message
+  CORE_message_queue_Control *the_message_queue,
+  CORE_message_queue_Buffer  *the_message
 )
 {
   _Chain_Append_unprotected( &the_message_queue->Inactive_messages, &the_message->Node );
@@ -466,7 +466,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Free_message_buffer (
  *       disabled if no API requires it.
  */
 RTEMS_INLINE_ROUTINE int _CORE_message_queue_Get_message_priority (
-  const CORE_message_queue_Buffer_control *the_message
+  const CORE_message_queue_Buffer *the_message
 )
 {
   #if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
@@ -488,11 +488,11 @@ RTEMS_INLINE_ROUTINE int _CORE_message_queue_Get_message_priority (
  * @retval NULL The message queue is empty.
  */
 RTEMS_INLINE_ROUTINE
-  CORE_message_queue_Buffer_control *_CORE_message_queue_Get_pending_message (
+  CORE_message_queue_Buffer *_CORE_message_queue_Get_pending_message (
   CORE_message_queue_Control *the_message_queue
 )
 {
-  return (CORE_message_queue_Buffer_control *)
+  return (CORE_message_queue_Buffer *)
     _Chain_Get_unprotected( &the_message_queue->Pending_messages );
 }
 
diff --git a/cpukit/rtems/src/msgmp.c b/cpukit/rtems/src/msgmp.c
index f49c254fbd..ae7c9802e2 100644
--- a/cpukit/rtems/src/msgmp.c
+++ b/cpukit/rtems/src/msgmp.c
@@ -151,10 +151,10 @@ static rtems_status_code _Message_queue_MP_Send_request_packet (
        */
 
       if (buffer) {
-          the_packet->Buffer.size = *size_p;
+          the_packet->size = *size_p;
           _CORE_message_queue_Copy_buffer(
             buffer,
-            the_packet->Buffer.buffer,
+            the_packet->buffer,
             *size_p
           );
       }
@@ -407,7 +407,7 @@ static void _Message_queue_MP_Process_packet (
 
       the_packet->Prefix.return_code = rtems_message_queue_receive(
         the_packet->Prefix.id,
-        the_packet->Buffer.buffer,
+        the_packet->buffer,
         &the_packet->size,
         the_packet->option_set,
         the_packet->Prefix.timeout
@@ -430,7 +430,7 @@ static void _Message_queue_MP_Process_packet (
            the_packet->size;
 
         _CORE_message_queue_Copy_buffer(
-          the_packet->Buffer.buffer,
+          the_packet->buffer,
           the_thread->Wait.return_argument_second.mutable_object,
           the_packet->size
         );
@@ -443,8 +443,8 @@ static void _Message_queue_MP_Process_packet (
 
       the_packet->Prefix.return_code = rtems_message_queue_send(
         the_packet->Prefix.id,
-        the_packet->Buffer.buffer,
-        the_packet->Buffer.size
+        the_packet->buffer,
+        the_packet->size
       );
 
       _Message_queue_MP_Send_response_packet(
@@ -466,8 +466,8 @@ static void _Message_queue_MP_Process_packet (
 
       the_packet->Prefix.return_code = rtems_message_queue_urgent(
         the_packet->Prefix.id,
-        the_packet->Buffer.buffer,
-        the_packet->Buffer.size
+        the_packet->buffer,
+        the_packet->size
       );
 
       _Message_queue_MP_Send_response_packet(
@@ -481,8 +481,8 @@ static void _Message_queue_MP_Process_packet (
 
       the_packet->Prefix.return_code = rtems_message_queue_broadcast(
         the_packet->Prefix.id,
-        the_packet->Buffer.buffer,
-        the_packet->Buffer.size,
+        the_packet->buffer,
+        the_packet->size,
         &the_packet->count
       );
 
diff --git a/cpukit/score/src/coremsg.c b/cpukit/score/src/coremsg.c
index 450470396c..7fc0cbd286 100644
--- a/cpukit/score/src/coremsg.c
+++ b/cpukit/score/src/coremsg.c
@@ -23,8 +23,13 @@
 #include <rtems/score/wkspace.h>
 
 #define MESSAGE_SIZE_LIMIT \
-  ( SIZE_MAX - sizeof( uintptr_t ) - 1 \
-    - sizeof( CORE_message_queue_Buffer_control ) )
+  ( SIZE_MAX - sizeof( uintptr_t ) - 1 - sizeof( CORE_message_queue_Buffer ) )
+
+RTEMS_STATIC_ASSERT(
+  offsetof( CORE_message_queue_Buffer, buffer )
+    == sizeof( CORE_message_queue_Buffer ),
+  CORE_MESSAGE_QUEUE_BUFFER_OFFSET
+);
 
 Status_Control _CORE_message_queue_Initialize(
   CORE_message_queue_Control     *the_message_queue,
@@ -43,8 +48,8 @@ Status_Control _CORE_message_queue_Initialize(
   buffer_size = RTEMS_ALIGN_UP( maximum_message_size, sizeof( uintptr_t ) );
   _Assert( buffer_size >= maximum_message_size );
 
-  buffer_size += sizeof( CORE_message_queue_Buffer_control );
-  _Assert( buffer_size >= sizeof( CORE_message_queue_Buffer_control ) );
+  buffer_size += sizeof( CORE_message_queue_Buffer );
+  _Assert( buffer_size >= sizeof( CORE_message_queue_Buffer ) );
 
   /* Make sure the memory allocation size computation does not overflow */
   if ( maximum_pending_messages > SIZE_MAX / buffer_size ) {
diff --git a/cpukit/score/src/coremsginsert.c b/cpukit/score/src/coremsginsert.c
index 850e1cd457..1a2abc3c96 100644
--- a/cpukit/score/src/coremsginsert.c
+++ b/cpukit/score/src/coremsginsert.c
@@ -27,11 +27,11 @@ static bool _CORE_message_queue_Order(
   const Chain_Node *right
 )
 {
-   const int                               *left_priority;
-   const CORE_message_queue_Buffer_control *right_message;
+   const int                       *left_priority;
+   const CORE_message_queue_Buffer *right_message;
 
    left_priority = (const int *) left;
-   right_message = (const CORE_message_queue_Buffer_control *) right;
+   right_message = (const CORE_message_queue_Buffer *) right;
 
    return *left_priority <
      _CORE_message_queue_Get_message_priority( right_message );
@@ -39,20 +39,20 @@ static bool _CORE_message_queue_Order(
 #endif
 
 void _CORE_message_queue_Insert_message(
-  CORE_message_queue_Control        *the_message_queue,
-  CORE_message_queue_Buffer_control *the_message,
-  const void                        *content_source,
-  size_t                             content_size,
-  CORE_message_queue_Submit_types    submit_type
+  CORE_message_queue_Control      *the_message_queue,
+  CORE_message_queue_Buffer       *the_message,
+  const void                      *content_source,
+  size_t                           content_size,
+  CORE_message_queue_Submit_types  submit_type
 )
 {
   Chain_Control *pending_messages;
 
-  the_message->Contents.size = content_size;
+  the_message->size = content_size;
 
   _CORE_message_queue_Copy_buffer(
     content_source,
-    the_message->Contents.buffer,
+    the_message->buffer,
     content_size
   );
 
diff --git a/cpukit/score/src/coremsgseize.c b/cpukit/score/src/coremsgseize.c
index bb78e28530..b2b9dbabdb 100644
--- a/cpukit/score/src/coremsgseize.c
+++ b/cpukit/score/src/coremsgseize.c
@@ -33,20 +33,16 @@ Status_Control _CORE_message_queue_Seize(
   Thread_queue_Context       *queue_context
 )
 {
-  CORE_message_queue_Buffer_control *the_message;
+  CORE_message_queue_Buffer *the_message;
 
   the_message = _CORE_message_queue_Get_pending_message( the_message_queue );
   if ( the_message != NULL ) {
     the_message_queue->number_of_pending_messages -= 1;
 
-    *size_p = the_message->Contents.size;
+    *size_p = the_message->size;
     executing->Wait.count =
       _CORE_message_queue_Get_message_priority( the_message );
-    _CORE_message_queue_Copy_buffer(
-      the_message->Contents.buffer,
-      buffer,
-      *size_p
-    );
+    _CORE_message_queue_Copy_buffer( the_message->buffer, buffer, *size_p );
 
     #if !defined(RTEMS_SCORE_COREMSG_ENABLE_BLOCKING_SEND)
       /*
diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c
index dd01f4aa7a..77fe30c0dd 100644
--- a/cpukit/score/src/coremsgsubmit.c
+++ b/cpukit/score/src/coremsgsubmit.c
@@ -36,8 +36,8 @@ Status_Control _CORE_message_queue_Submit(
   Thread_queue_Context             *queue_context
 )
 {
-  CORE_message_queue_Buffer_control *the_message;
-  Thread_Control                    *the_thread;
+  CORE_message_queue_Buffer *the_message;
+  Thread_Control            *the_thread;
 
   if ( size > the_message_queue->maximum_message_size ) {
     _CORE_message_queue_Release( the_message_queue, queue_context );
diff --git a/testsuites/sptests/spmsgq_err01/init.c b/testsuites/sptests/spmsgq_err01/init.c
index 854377038e..720ddd6fb7 100644
--- a/testsuites/sptests/spmsgq_err01/init.c
+++ b/testsuites/sptests/spmsgq_err01/init.c
@@ -101,8 +101,7 @@ rtems_task Init(
   /* not enough memory for messages */
   status = rtems_message_queue_create(
     Queue_name[ 1 ],
-    SIZE_MAX
-      / ( sizeof( uintptr_t ) + sizeof( CORE_message_queue_Buffer_control ) ),
+    SIZE_MAX / ( sizeof( uintptr_t ) + sizeof( CORE_message_queue_Buffer ) ),
     1,
     RTEMS_DEFAULT_ATTRIBUTES,
     &Queue_id[ 1 ]
-- 
2.26.2



More information about the devel mailing list