From 4a4f41ed642cd5d9f4056b12d86bbf80e8da983a Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 23 Sep 2020 16:47:58 +0200 Subject: rtems: Add rtems_message_queue_construct() 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/rtems/src/msgqconstruct.c | 189 +++++++++++++++++++++++++++++++++++++++ cpukit/rtems/src/msgqcreate.c | 178 +++++++++--------------------------- 2 files changed, 231 insertions(+), 136 deletions(-) create mode 100644 cpukit/rtems/src/msgqconstruct.c (limited to 'cpukit/rtems') 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 +#include +#include +#include +#include + +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 -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include + +#include 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 -); -- cgit v1.2.3