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.hu...@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@rtems.org > http://lists.rtems.org/mailman/listinfo/devel _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel