[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