[PATCH 8/8] rtems: Add rtems_message_queue_construct()

Gedare Bloom gedare at rtems.org
Thu Sep 24 16:47:34 UTC 2020


We'll need docs. The test case looks incomplete. Might want to
duplicate the current tests for constructed queues to exercise
default, priority; I guess the GLOBAL attribute is meaningless in an
sptest.

Everything else here looks fine beside what I commented on in the
earlier patches.

On Thu, Sep 24, 2020 at 6:13 AM Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
>
> In contrast to message queues created by rtems_message_queue_create(), the
> message queues constructed by this directive use a user-provided message buffer
> storage area.
>
> Add RTEMS_MESSAGE_QUEUE_BUFFER() to define a message buffer type for message
> buffer storage areas.
>
> Update #4007.
> ---
>  cpukit/Makefile.am                       |   2 +
>  cpukit/include/rtems/rtems/message.h     | 124 +++++++++++++++
>  cpukit/include/rtems/rtems/messageimpl.h |  17 ++
>  cpukit/include/rtems/score/coremsg.h     |  10 ++
>  cpukit/include/rtems/score/coremsgimpl.h |  67 +++++++-
>  cpukit/posix/src/mqueueopen.c            |   4 +-
>  cpukit/rtems/src/msgqconstruct.c         | 189 +++++++++++++++++++++++
>  cpukit/rtems/src/msgqcreate.c            | 178 +++++----------------
>  cpukit/score/src/coremsg.c               |  17 +-
>  cpukit/score/src/coremsgclose.c          |   7 +-
>  cpukit/score/src/coremsgwkspace.c        |  53 +++++++
>  spec/build/cpukit/librtemscpu.yml        |   2 +
>  testsuites/sptests/sp13/init.c           |  21 ++-
>  testsuites/sptests/sp13/system.h         |   2 +-
>  14 files changed, 532 insertions(+), 161 deletions(-)
>  create mode 100644 cpukit/rtems/src/msgqconstruct.c
>  create mode 100644 cpukit/score/src/coremsgwkspace.c
>
> diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
> index e2bed4b844..2c35354e66 100644
> --- a/cpukit/Makefile.am
> +++ b/cpukit/Makefile.am
> @@ -706,6 +706,7 @@ librtemscpu_a_SOURCES += rtems/src/intrcatch.c
>  librtemscpu_a_SOURCES += rtems/src/modes.c
>  librtemscpu_a_SOURCES += rtems/src/msg.c
>  librtemscpu_a_SOURCES += rtems/src/msgqbroadcast.c
> +librtemscpu_a_SOURCES += rtems/src/msgqconstruct.c
>  librtemscpu_a_SOURCES += rtems/src/msgqcreate.c
>  librtemscpu_a_SOURCES += rtems/src/msgqdelete.c
>  librtemscpu_a_SOURCES += rtems/src/msgqflush.c
> @@ -839,6 +840,7 @@ librtemscpu_a_SOURCES += score/src/coremsgflushwait.c
>  librtemscpu_a_SOURCES += score/src/coremsginsert.c
>  librtemscpu_a_SOURCES += score/src/coremsgseize.c
>  librtemscpu_a_SOURCES += score/src/coremsgsubmit.c
> +librtemscpu_a_SOURCES += score/src/coremsgwkspace.c
>  librtemscpu_a_SOURCES += score/src/coremutexseize.c
>  librtemscpu_a_SOURCES += score/src/percpu.c
>  librtemscpu_a_SOURCES += score/src/percpuasm.c
> diff --git a/cpukit/include/rtems/rtems/message.h b/cpukit/include/rtems/rtems/message.h
> index 675cd98acc..a576132d95 100644
> --- a/cpukit/include/rtems/rtems/message.h
> +++ b/cpukit/include/rtems/rtems/message.h
> @@ -21,6 +21,7 @@
>  #include <rtems/rtems/options.h>
>  #include <rtems/rtems/status.h>
>  #include <rtems/rtems/types.h>
> +#include <rtems/score/coremsgbuffer.h>
>
>  #ifdef __cplusplus
>  extern "C" {
> @@ -65,6 +66,129 @@ rtems_status_code rtems_message_queue_create(
>    rtems_id        *id
>  );
>
> +/**
> + * @brief Defines a structure which can be used as a message queue buffer for
> + *   messages of the specified maximum size.
> + *
> + * Use this macro to define the message buffers for
> + * rtems_message_queue_construct().
> + *
> + * @param _maximum_message_size is the maximum message size in bytes.
> + */
> +#define RTEMS_MESSAGE_QUEUE_BUFFER( _maximum_message_size ) \
> +  struct { \
> +    CORE_message_queue_Buffer _buffer; \
> +    char _message[ _maximum_message_size ]; \
> +  }
> +
> +/**
> + * @brief This structure defines the configuration of a message queue
> + *   constructed by rtems_message_queue_construct().
> + */
> +typedef struct {
> +  /**
> +   * @brief This member defines the name of the message queue.
> +   */
> +  rtems_name name;
> +
> +  /**
> +   * @brief This member defines the maximum number of pending messages
> +   *   supported by the message queue.
> +   */
> +  uint32_t maximum_pending_messages;
> +
> +  /**
> +   * @brief This member defines the maximum message size supported by the
> +   *   message queue.
> +   */
> +  size_t maximum_message_size;
> +
> +  /**
> +   * @brief This member shall point to the message buffer storage area begin.
> +   *
> +   * The message buffer storage area for the message queue shall be an array of
> +   * the type defined by RTEMS_MESSAGE_QUEUE_BUFFER() with a maximum message
> +   * size equal to the maximum message size of this configuration.
> +   */
> +  void *storage_area;
> +
> +  /**
> +   * @brief This member defines size of the message buffer storage area in
> +   *   bytes.
> +   */
> +  size_t storage_size;
> +
> +  /**
> +   * @brief This member defines the optional handler to free the message buffer
> +   *   storage area.
> +   *
> +   * It is called when the message queue is deleted.  It is called from task
> +   * context under protection of the object allocator lock.  It is allowed to
> +   * call free() in this handler.  If handler is NULL, then no action will be
> +   * performed.
> +   */
> +  void ( *storage_free )( void * );
> +
> +  /**
> +   * @brief This member defines the attributes of the message queue.
> +   */
> +  rtems_attribute attributes;
> +} rtems_message_queue_config;
> +
> +/**
> + * @brief Constructs a message queue according to the specified configuration.
> + *
> + * In contrast to message queues created by rtems_message_queue_create(), the
> + * message queues constructed by this directive use a user-provided message
> + * buffer storage area.
> + *
> + * This directive is intended for applications which do not want to use the
> + * RTEMS Workspace and instead statically allocate all operating system
> + * resources.  An application based solely on static allocation can avoid any
> + * runtime memory allocators.  This can simplify the application architecture
> + * as well as any analysis that may be required.
> + *
> + * The value for #CONFIGURE_MESSAGE_BUFFER_MEMORY should not include memory for
> + * message queues constructed by rtems_message_queueu_construct().
> + *
> + * @param config is the message queue configuration.
> + *
> + * @param[out] id is the pointer to an object identifier variable.  The
> + *   identifier of the constructed message queue object will be stored in this
> + *   variable, in case of a successful operation.
> + *
> + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
> + *
> + * @retval ::RTEMS_INVALID_ADDRESS The id parameter was NULL.
> + *
> + * @retval ::RTEMS_INVALID_NAME The message queue name in the configuration was
> + *   invalid.
> + *
> + * @retval ::RTEMS_INVALID_SIZE The maximum message size in the configuration
> + *   is too big and resulted in integer overflows in calculations carried out
> + *   to determine the size of the message buffer area.
> + *
> + * @retval ::RTEMS_INVALID_SIZE The maximum number of pending messages in the
> + *   configuration is too big and resulted in integer overflows in calculations
> + *   carried out to determine the size of the message buffer area.
> + *
> + * @retval ::RTEMS_TOO_MANY There was no inactive message queue object
> + *   available to construct a message queue.
> + *
> + * @retval ::RTEMS_TOO_MANY In multiprocessing configurations, there was no
> + *   inactive global object available to construct a global message queue.
> + *
> + * @retval ::RTEMS_UNSATISFIED The message queue storage area pointer of the
> + *   configuration was NULL.
> + *
> + * @retval ::RTEMS_UNSATISFIED The message queue storage area size of the
> + *   configuration was invalid.
> + */
> +rtems_status_code rtems_message_queue_construct(
> +  const rtems_message_queue_config *config,
> +  rtems_id                         *id
> +);
> +
>  /**
>   * @brief RTEMS Message Queue Name to Id
>   *
> diff --git a/cpukit/include/rtems/rtems/messageimpl.h b/cpukit/include/rtems/rtems/messageimpl.h
> index e317244025..c90ac97da9 100644
> --- a/cpukit/include/rtems/rtems/messageimpl.h
> +++ b/cpukit/include/rtems/rtems/messageimpl.h
> @@ -101,6 +101,23 @@ RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Allocate( void )
>      _Objects_Allocate( &_Message_queue_Information );
>  }
>
> +/**
> + * @brief Creates a message queue.
> + *
> + * @param config is the message queue configuration.
> + *
> + * @param[out] id contains the object identifier if the operation was
> + *   successful.
> + *
> + * @param allocate_buffers is the message buffer storage area allocation
> + *   handler.
> + */
> +rtems_status_code _Message_queue_Create(
> +  const rtems_message_queue_config    *config,
> +  rtems_id                            *id,
> +  CORE_message_queue_Allocate_buffers  allocate_buffers
> +);
> +
>  /**@}*/
>
>  #ifdef __cplusplus
> diff --git a/cpukit/include/rtems/score/coremsg.h b/cpukit/include/rtems/score/coremsg.h
> index 220c9839a5..51c638bcc3 100644
> --- a/cpukit/include/rtems/score/coremsg.h
> +++ b/cpukit/include/rtems/score/coremsg.h
> @@ -124,6 +124,16 @@ struct CORE_message_queue_Control {
>     *  as part of destroying it.
>     */
>    CORE_message_queue_Buffer         *message_buffers;
> +
> +  /**
> +   * @brief This member contains the optional message buffer storage area free
> +   * handler.
> +   *
> +   * It may be NULL.  In this case no action is performed to free the message
> +   * buffer storage area.
> +   */
> +  void                            ( *free_message_buffers )( void * );
> +
>    #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
>      /** This is the routine invoked when the message queue transitions
>       *  from zero (0) messages pending to one (1) message pending.
> diff --git a/cpukit/include/rtems/score/coremsgimpl.h b/cpukit/include/rtems/score/coremsgimpl.h
> index cb84bfb207..0bf5fa52d0 100644
> --- a/cpukit/include/rtems/score/coremsgimpl.h
> +++ b/cpukit/include/rtems/score/coremsgimpl.h
> @@ -68,6 +68,54 @@ extern "C" {
>   */
>  typedef int CORE_message_queue_Submit_types;
>
> +/**
> + * @brief This handler shall allocate the message buffer storage area for a
> + *   message queue.
> + *
> + * The handler shall set the CORE_message_queue_Control::free_message_buffers
> + * member.
> + *
> + * @param[out] the_message_queue is the message queue control.
> + *
> + * @param size is the message buffer storage area size to allocate.
> + *
> + * @param arg is the handler argument.
> + *
> + * @retval NULL The allocation failed.
> + *
> + * @return Otherwise the pointer to the allocated message buffer storage area
> + *   begin shall be returned.
> + */
> +typedef void *( *CORE_message_queue_Allocate_buffers )(
> +  CORE_message_queue_Control *the_message_queue,
> +  size_t                      size,
> +  const void                 *arg
> +);
> +
> +/**
> + * @brief This handler allocates the message buffer storage area for a message
> + *   queue from the RTEMS Workspace.
> + *
> + * The handler sets the CORE_message_queue_Control::free_message_buffers
> + * to _Workspace_Free().
> + *
> + * @param[out] the_message_queue is the message queue control.
> + *
> + * @param size is the message buffer storage area size to allocate.
> + *
> + * @param arg is the unused handler argument.
> + *
> + * @retval NULL The allocation failed.
> + *
> + * @return Otherwise the pointer to the allocated message buffer storage area
> + *   begin is returned.
> + */
> +void *_CORE_message_queue_Workspace_allocate(
> +  CORE_message_queue_Control *the_message_queue,
> +  size_t                      size,
> +  const void                 *arg
> +);
> +
>  /**
>   * @brief Initializes a message queue.
>   *
> @@ -81,19 +129,26 @@ typedef int CORE_message_queue_Submit_types;
>   * @param maximum_message_size is the size of the largest message that may be
>   *   sent to this message queue instance.
>   *
> + * @param allocate_buffers is the message buffer storage area allocation
> + *   handler.
> + *
> + * @param arg is the message buffer storage area allocation handler argument.
> + *
>   * @retval STATUS_SUCCESSFUL The message queue was initialized.
>   *
>   * @retval STATUS_MESSAGE_QUEUE_INVALID_SIZE Calculations with the maximum
>   *   pending messages or maximum message size produced an integer overflow.
>   *
> - * @retval STATUS_MESSAGE_QUEUE_NO_MEMORY There was not enough memory to
> - *   allocate the message buffers.
> + * @retval STATUS_MESSAGE_QUEUE_NO_MEMORY The message buffer storage area
> + *   allocation failed.
>   */
>  Status_Control _CORE_message_queue_Initialize(
> -  CORE_message_queue_Control     *the_message_queue,
> -  CORE_message_queue_Disciplines  discipline,
> -  uint32_t                        maximum_pending_messages,
> -  size_t                          maximum_message_size
> +  CORE_message_queue_Control          *the_message_queue,
> +  CORE_message_queue_Disciplines       discipline,
> +  uint32_t                             maximum_pending_messages,
> +  size_t                               maximum_message_size,
> +  CORE_message_queue_Allocate_buffers  allocate_buffers,
> +  const void                          *arg
>  );
>
>  /**
> diff --git a/cpukit/posix/src/mqueueopen.c b/cpukit/posix/src/mqueueopen.c
> index af8abebea8..af50dc2754 100644
> --- a/cpukit/posix/src/mqueueopen.c
> +++ b/cpukit/posix/src/mqueueopen.c
> @@ -102,7 +102,9 @@ static mqd_t _POSIX_Message_queue_Create(
>      &the_mq->Message_queue,
>      CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
>      attr->mq_maxmsg,
> -    attr->mq_msgsize
> +    attr->mq_msgsize,
> +    _CORE_message_queue_Workspace_allocate,
> +    NULL
>    );
>
>    if ( status != STATUS_SUCCESSFUL ) {
> diff --git a/cpukit/rtems/src/msgqconstruct.c b/cpukit/rtems/src/msgqconstruct.c
> new file mode 100644
> index 0000000000..61d0472e7c
> --- /dev/null
> +++ b/cpukit/rtems/src/msgqconstruct.c
> @@ -0,0 +1,189 @@
> +/**
> + *  @file
> + *
> + *  @brief RTEMS Create Message Queue
> + *  @ingroup ClassicMessageQueue
> + */
> +
> +/*
> + *  COPYRIGHT (c) 1989-2014.
> + *  On-Line Applications Research Corporation (OAR).
> + *
> + *  The license and distribution terms for this file may be
> + *  found in the file LICENSE in this distribution or at
> + *  http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <rtems/rtems/messageimpl.h>
> +#include <rtems/rtems/attrimpl.h>
> +#include <rtems/rtems/support.h>
> +#include <rtems/score/coremsgimpl.h>
> +#include <rtems/sysinit.h>
> +
> +static void *_Message_queue_Get_buffers(
> +  CORE_message_queue_Control *the_message_queue,
> +  size_t                      size,
> +  const void                 *arg
> +)
> +{
> +  const rtems_message_queue_config *config;
> +
> +  config = arg;
> +
> +  if ( config->storage_size != size ) {
> +    return NULL;
> +  }
> +
> +  the_message_queue->free_message_buffers = config->storage_free;
> +  return config->storage_area;
> +}
> +
> +rtems_status_code rtems_message_queue_construct(
> +  const rtems_message_queue_config *config,
> +  rtems_id                         *id
> +)
> +{
> +  return _Message_queue_Create( config, id, _Message_queue_Get_buffers );
> +}
> +
> +rtems_status_code _Message_queue_Create(
> +  const rtems_message_queue_config    *config,
> +  rtems_id                            *id,
> +  CORE_message_queue_Allocate_buffers  allocate_buffers
> +)
> +{
> +  Message_queue_Control          *the_message_queue;
> +  CORE_message_queue_Disciplines  discipline;
> +  Status_Control                  status;
> +#if defined(RTEMS_MULTIPROCESSING)
> +  bool                            is_global;
> +#endif
> +
> +  if ( id == NULL ) {
> +    return RTEMS_INVALID_ADDRESS;
> +  }
> +
> +  if ( !rtems_is_name_valid( config->name ) ) {
> +    return RTEMS_INVALID_NAME;
> +  }
> +
> +  if ( config->maximum_pending_messages == 0 ) {
> +    return RTEMS_INVALID_NUMBER;
> +  }
> +
> +  if ( config->maximum_message_size == 0 ) {
> +    return RTEMS_INVALID_SIZE;
> +  }
> +
> +#if defined(RTEMS_MULTIPROCESSING)
> +  if ( _System_state_Is_multiprocessing ) {
> +    is_global = _Attributes_Is_global( config->attributes );
> +  } else {
> +    is_global = false;
> +  }
> +
> +#if 1
> +  /*
> +   * I am not 100% sure this should be an error.
> +   * It seems reasonable to create a que with a large max size,
> +   * and then just send smaller msgs from remote (or all) nodes.
> +   */
> +  if ( is_global ) {
> +    size_t max_packet_payload_size = _MPCI_table->maximum_packet_size
> +      - MESSAGE_QUEUE_MP_PACKET_SIZE;
> +
> +    if ( config->maximum_message_size > max_packet_payload_size ) {
> +      return RTEMS_INVALID_SIZE;
> +    }
> +  }
> +#endif
> +#endif
> +
> +  the_message_queue = _Message_queue_Allocate();
> +
> +  if ( !the_message_queue ) {
> +    _Objects_Allocator_unlock();
> +    return RTEMS_TOO_MANY;
> +  }
> +
> +#if defined(RTEMS_MULTIPROCESSING)
> +  if (
> +    is_global
> +      && !_Objects_MP_Allocate_and_open(
> +            &_Message_queue_Information,
> +            config->name,
> +            the_message_queue->Object.id,
> +            false
> +          )
> +  ) {
> +    _Message_queue_Free( the_message_queue );
> +    _Objects_Allocator_unlock();
> +    return RTEMS_TOO_MANY;
> +  }
> +
> +  the_message_queue->is_global = is_global;
> +#endif
> +
> +  if ( _Attributes_Is_priority( config->attributes ) ) {
> +    discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
> +  } else {
> +    discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
> +  }
> +
> +  status = _CORE_message_queue_Initialize(
> +    &the_message_queue->message_queue,
> +    discipline,
> +    config->maximum_pending_messages,
> +    config->maximum_message_size,
> +    allocate_buffers,
> +    config
> +  );
> +
> +  if ( status != STATUS_SUCCESSFUL ) {
> +#if defined(RTEMS_MULTIPROCESSING)
> +    if ( is_global )
> +        _Objects_MP_Close(
> +          &_Message_queue_Information, the_message_queue->Object.id);
> +#endif
> +
> +    _Message_queue_Free( the_message_queue );
> +    _Objects_Allocator_unlock();
> +    return STATUS_GET_CLASSIC( status );
> +  }
> +
> +  _Objects_Open(
> +    &_Message_queue_Information,
> +    &the_message_queue->Object,
> +    (Objects_Name) config->name
> +  );
> +
> +  *id = the_message_queue->Object.id;
> +
> +#if defined(RTEMS_MULTIPROCESSING)
> +  if ( is_global )
> +    _Message_queue_MP_Send_process_packet(
> +      MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
> +      the_message_queue->Object.id,
> +      config->name,
> +      0
> +    );
> +#endif
> +
> +  _Objects_Allocator_unlock();
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +static void _Message_queue_Manager_initialization( void )
> +{
> +  _Objects_Initialize_information( &_Message_queue_Information);
> +}
> +
> +RTEMS_SYSINIT_ITEM(
> +  _Message_queue_Manager_initialization,
> +  RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE,
> +  RTEMS_SYSINIT_ORDER_MIDDLE
> +);
> diff --git a/cpukit/rtems/src/msgqcreate.c b/cpukit/rtems/src/msgqcreate.c
> index 20787f00a6..7469f10509 100644
> --- a/cpukit/rtems/src/msgqcreate.c
> +++ b/cpukit/rtems/src/msgqcreate.c
> @@ -1,17 +1,37 @@
> +/* SPDX-License-Identifier: BSD-2-Clause */
> +
>  /**
> - *  @file
> + * @file
> + *
> + * @ingroup ClassicMessageQueueImpl
>   *
> - *  @brief RTEMS Create Message Queue
> - *  @ingroup ClassicMessageQueue
> + * @brief This source file contains the implementation of
> + *   rtems_message_queue_create().
>   */
>
>  /*
> - *  COPYRIGHT (c) 1989-2014.
> - *  On-Line Applications Research Corporation (OAR).
> + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
>   *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> + * POSSIBILITY OF SUCH DAMAGE.
>   */
>
>  #ifdef HAVE_CONFIG_H
> @@ -19,17 +39,9 @@
>  #endif
>
>  #include <rtems/rtems/messageimpl.h>
> -#include <rtems/rtems/status.h>
> -#include <rtems/rtems/attrimpl.h>
> -#include <rtems/rtems/options.h>
> -#include <rtems/rtems/support.h>
> -#include <rtems/score/sysstate.h>
> -#include <rtems/score/chain.h>
> -#include <rtems/score/isr.h>
>  #include <rtems/score/coremsgimpl.h>
> -#include <rtems/score/thread.h>
> -#include <rtems/score/wkspace.h>
> -#include <rtems/sysinit.h>
> +
> +#include <string.h>
>
>  rtems_status_code rtems_message_queue_create(
>    rtems_name       name,
> @@ -39,123 +51,17 @@ rtems_status_code rtems_message_queue_create(
>    rtems_id        *id
>  )
>  {
> -  Message_queue_Control          *the_message_queue;
> -  CORE_message_queue_Disciplines  discipline;
> -  Status_Control                  status;
> -#if defined(RTEMS_MULTIPROCESSING)
> -  bool                            is_global;
> -#endif
> -
> -  if ( !rtems_is_name_valid( name ) )
> -    return RTEMS_INVALID_NAME;
> -
> -  if ( !id )
> -    return RTEMS_INVALID_ADDRESS;
> -
> -#if defined(RTEMS_MULTIPROCESSING)
> -  if ( _System_state_Is_multiprocessing ) {
> -    is_global = _Attributes_Is_global( attribute_set );
> -  } else {
> -    is_global = false;
> -  }
> -#endif
> -
> -  if ( count == 0 )
> -      return RTEMS_INVALID_NUMBER;
> -
> -  if ( max_message_size == 0 )
> -      return RTEMS_INVALID_SIZE;
> -
> -#if defined(RTEMS_MULTIPROCESSING)
> -#if 1
> -  /*
> -   * I am not 100% sure this should be an error.
> -   * It seems reasonable to create a que with a large max size,
> -   * and then just send smaller msgs from remote (or all) nodes.
> -   */
> -  if ( is_global ) {
> -    size_t max_packet_payload_size = _MPCI_table->maximum_packet_size
> -      - MESSAGE_QUEUE_MP_PACKET_SIZE;
> -
> -    if ( max_message_size > max_packet_payload_size ) {
> -      return RTEMS_INVALID_SIZE;
> -    }
> -  }
> -#endif
> -#endif
> -
> -  the_message_queue = _Message_queue_Allocate();
> -
> -  if ( !the_message_queue ) {
> -    _Objects_Allocator_unlock();
> -    return RTEMS_TOO_MANY;
> -  }
> -
> -#if defined(RTEMS_MULTIPROCESSING)
> -  if ( is_global &&
> -    !( _Objects_MP_Allocate_and_open( &_Message_queue_Information,
> -                              name, the_message_queue->Object.id, false ) ) ) {
> -    _Message_queue_Free( the_message_queue );
> -    _Objects_Allocator_unlock();
> -    return RTEMS_TOO_MANY;
> -  }
> -
> -  the_message_queue->is_global = is_global;
> -#endif
> -
> -  if (_Attributes_Is_priority( attribute_set ) )
> -    discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
> -  else
> -    discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
> -
> -  status = _CORE_message_queue_Initialize(
> -    &the_message_queue->message_queue,
> -    discipline,
> -    count,
> -    max_message_size
> -  );
> -
> -  if ( status != STATUS_SUCCESSFUL ) {
> -#if defined(RTEMS_MULTIPROCESSING)
> -    if ( is_global )
> -        _Objects_MP_Close(
> -          &_Message_queue_Information, the_message_queue->Object.id);
> -#endif
> -
> -    _Message_queue_Free( the_message_queue );
> -    _Objects_Allocator_unlock();
> -    return STATUS_GET_CLASSIC( status );
> -  }
> -
> -  _Objects_Open(
> -    &_Message_queue_Information,
> -    &the_message_queue->Object,
> -    (Objects_Name) name
> +  rtems_message_queue_config config;
> +
> +  memset( &config, 0, sizeof( config ) );
> +  config.name = name;
> +  config.maximum_pending_messages = count;
> +  config.maximum_message_size = max_message_size;
> +  config.attributes = attribute_set;
> +
> +  return _Message_queue_Create(
> +    &config,
> +    id,
> +    _CORE_message_queue_Workspace_allocate
>    );
> -
> -  *id = the_message_queue->Object.id;
> -
> -#if defined(RTEMS_MULTIPROCESSING)
> -  if ( is_global )
> -    _Message_queue_MP_Send_process_packet(
> -      MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
> -      the_message_queue->Object.id,
> -      name,
> -      0
> -    );
> -#endif
> -
> -  _Objects_Allocator_unlock();
> -  return RTEMS_SUCCESSFUL;
>  }
> -
> -static void _Message_queue_Manager_initialization( void )
> -{
> -  _Objects_Initialize_information( &_Message_queue_Information);
> -}
> -
> -RTEMS_SYSINIT_ITEM(
> -  _Message_queue_Manager_initialization,
> -  RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE,
> -  RTEMS_SYSINIT_ORDER_MIDDLE
> -);
> diff --git a/cpukit/score/src/coremsg.c b/cpukit/score/src/coremsg.c
> index 7fc0cbd286..ce8ac70860 100644
> --- a/cpukit/score/src/coremsg.c
> +++ b/cpukit/score/src/coremsg.c
> @@ -20,7 +20,6 @@
>
>  #include <rtems/score/coremsgimpl.h>
>  #include <rtems/score/assert.h>
> -#include <rtems/score/wkspace.h>
>
>  #define MESSAGE_SIZE_LIMIT \
>    ( SIZE_MAX - sizeof( uintptr_t ) - 1 - sizeof( CORE_message_queue_Buffer ) )
> @@ -32,10 +31,12 @@ RTEMS_STATIC_ASSERT(
>  );
>
>  Status_Control _CORE_message_queue_Initialize(
> -  CORE_message_queue_Control     *the_message_queue,
> -  CORE_message_queue_Disciplines  discipline,
> -  uint32_t                        maximum_pending_messages,
> -  size_t                          maximum_message_size
> +  CORE_message_queue_Control          *the_message_queue,
> +  CORE_message_queue_Disciplines       discipline,
> +  uint32_t                             maximum_pending_messages,
> +  size_t                               maximum_message_size,
> +  CORE_message_queue_Allocate_buffers  allocate_buffers,
> +  const void                          *arg
>  )
>  {
>    size_t buffer_size;
> @@ -56,8 +57,10 @@ Status_Control _CORE_message_queue_Initialize(
>      return STATUS_MESSAGE_QUEUE_INVALID_SIZE;
>    }
>
> -  the_message_queue->message_buffers = _Workspace_Allocate(
> -    (size_t) maximum_pending_messages * buffer_size
> +  the_message_queue->message_buffers = ( *allocate_buffers )(
> +    the_message_queue,
> +    (size_t) maximum_pending_messages * buffer_size,
> +    arg
>    );
>
>    if ( the_message_queue->message_buffers == NULL ) {
> diff --git a/cpukit/score/src/coremsgclose.c b/cpukit/score/src/coremsgclose.c
> index 18b49b096c..98032dd3ad 100644
> --- a/cpukit/score/src/coremsgclose.c
> +++ b/cpukit/score/src/coremsgclose.c
> @@ -19,7 +19,6 @@
>  #endif
>
>  #include <rtems/score/coremsgimpl.h>
> -#include <rtems/score/wkspace.h>
>
>  static Thread_Control *_CORE_message_queue_Was_deleted(
>    Thread_Control       *the_thread,
> @@ -50,7 +49,11 @@ void _CORE_message_queue_Close(
>      queue_context
>    );
>
> -  (void) _Workspace_Free( the_message_queue->message_buffers );
> +  if ( the_message_queue->free_message_buffers != NULL ) {
> +    ( *the_message_queue->free_message_buffers )(
> +      the_message_queue->message_buffers
> +    );
> +  }
>
>    _Thread_queue_Destroy( &the_message_queue->Wait_queue );
>  }
> diff --git a/cpukit/score/src/coremsgwkspace.c b/cpukit/score/src/coremsgwkspace.c
> new file mode 100644
> index 0000000000..8441701813
> --- /dev/null
> +++ b/cpukit/score/src/coremsgwkspace.c
> @@ -0,0 +1,53 @@
> +/* SPDX-License-Identifier: BSD-2-Clause */
> +
> +/**
> + * @file
> + *
> + * @ingroup RTEMSScoreMessageQueue
> + *
> + * @brief This source file contains the implementation of
> + *   _CORE_message_queue_Workspace_allocate().
> + */
> +
> +/*
> + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <rtems/score/coremsgimpl.h>
> +#include <rtems/score/wkspace.h>
> +
> +void *_CORE_message_queue_Workspace_allocate(
> +  CORE_message_queue_Control *the_message_queue,
> +  size_t                      size,
> +  const void                 *arg
> +)
> +{
> +  (void) arg;
> +  the_message_queue->free_message_buffers = _Workspace_Free;
> +  return _Workspace_Allocate( size );
> +}
> diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml
> index 2baf8ef01c..21dc239b1b 100644
> --- a/spec/build/cpukit/librtemscpu.yml
> +++ b/spec/build/cpukit/librtemscpu.yml
> @@ -1198,6 +1198,7 @@ source:
>  - cpukit/rtems/src/modes.c
>  - cpukit/rtems/src/msg.c
>  - cpukit/rtems/src/msgqbroadcast.c
> +- cpukit/rtems/src/msgqconstruct.c
>  - cpukit/rtems/src/msgqcreate.c
>  - cpukit/rtems/src/msgqdelete.c
>  - cpukit/rtems/src/msgqflush.c
> @@ -1376,6 +1377,7 @@ source:
>  - cpukit/score/src/coremsginsert.c
>  - cpukit/score/src/coremsgseize.c
>  - cpukit/score/src/coremsgsubmit.c
> +- cpukit/score/src/coremsgwkspace.c
>  - cpukit/score/src/coremutexseize.c
>  - cpukit/score/src/corerwlock.c
>  - cpukit/score/src/corerwlockobtainread.c
> diff --git a/testsuites/sptests/sp13/init.c b/testsuites/sptests/sp13/init.c
> index a23d369001..f8ffd55426 100644
> --- a/testsuites/sptests/sp13/init.c
> +++ b/testsuites/sptests/sp13/init.c
> @@ -28,6 +28,17 @@
>
>  const char rtems_test_name[] = "SP 13";
>
> +static RTEMS_MESSAGE_QUEUE_BUFFER( MESSAGE_SIZE ) Queue_3_buffers[ 100 ];
> +
> +static const rtems_message_queue_config Queue_3_config = {
> +  .name = rtems_build_name( 'Q', '3', ' ', ' ' ),
> +  .maximum_pending_messages = RTEMS_ARRAY_SIZE( Queue_3_buffers ),
> +  .maximum_message_size = MESSAGE_SIZE,
> +  .storage_area = Queue_3_buffers,
> +  .storage_size = sizeof( Queue_3_buffers ),
> +  .attributes = RTEMS_GLOBAL
> +};
> +
>  rtems_task Init(
>    rtems_task_argument argument
>  )
> @@ -101,14 +112,8 @@ rtems_task Init(
>    );
>    directive_failed( status, "rtems_message_queue_create of Q2" );
>
> -  status = rtems_message_queue_create(
> -    Queue_name[ 3 ],
> -    100,
> -    MESSAGE_SIZE,
> -    RTEMS_GLOBAL,
> -    &Queue_id[ 3 ]
> -  );
> -  directive_failed( status, "rtems_message_queue_create of Q3" );
> +  status = rtems_message_queue_construct( &Queue_3_config, &Queue_id[ 3 ] );
> +  directive_failed( status, "rtems_message_queue_construct of Q3" );
>
>    rtems_task_exit();
>  }
> diff --git a/testsuites/sptests/sp13/system.h b/testsuites/sptests/sp13/system.h
> index 7a495963f6..1abfc96b1d 100644
> --- a/testsuites/sptests/sp13/system.h
> +++ b/testsuites/sptests/sp13/system.h
> @@ -91,7 +91,7 @@ TEST_EXTERN rtems_name Queue_name[ 4 ];      /* array of queue names */
>  #define CONFIGURE_MESSAGE_BUFFER_MEMORY \
>     /* Q1 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 100, MESSAGE_SIZE ) + \
>     /* Q2 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 10, MESSAGE_SIZE ) + \
> -   /* Q3 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 100, MESSAGE_SIZE ) + \
> +   /* Q3 is statically allocated */ \
>     /* Q1 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 100, 20 ) + \
>     /* Q1 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 2,  1030 )
>
> --
> 2.26.2
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel


More information about the devel mailing list