Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:22

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSImplClassicMessage
0007  *
0008  * @brief This source file contains the implementation of
0009  *   rtems_message_queue_construct().
0010  */
0011 
0012 /*
0013  *  COPYRIGHT (c) 1989-2014.
0014  *  On-Line Applications Research Corporation (OAR).
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041 
0042 #include <rtems/rtems/messageimpl.h>
0043 #include <rtems/rtems/attrimpl.h>
0044 #include <rtems/rtems/statusimpl.h>
0045 #include <rtems/rtems/support.h>
0046 #include <rtems/score/coremsgimpl.h>
0047 #include <rtems/sysinit.h>
0048 
0049 static void *_Message_queue_Get_buffers(
0050   CORE_message_queue_Control *the_message_queue,
0051   size_t                      size,
0052   const void                 *arg
0053 )
0054 {
0055   const rtems_message_queue_config *config;
0056 
0057   config = arg;
0058 
0059   if ( config->storage_size != size ) {
0060     return NULL;
0061   }
0062 
0063   if ( config->storage_free != NULL ) {
0064     the_message_queue->free_message_buffers = config->storage_free;
0065   } else {
0066     the_message_queue->free_message_buffers = _Objects_Free_nothing;
0067   }
0068 
0069   return config->storage_area;
0070 }
0071 
0072 rtems_status_code rtems_message_queue_construct(
0073   const rtems_message_queue_config *config,
0074   rtems_id                         *id
0075 )
0076 {
0077   if ( config == NULL ) {
0078     return RTEMS_INVALID_ADDRESS;
0079   }
0080 
0081   return _Message_queue_Create( config, id, _Message_queue_Get_buffers );
0082 }
0083 
0084 rtems_status_code _Message_queue_Create(
0085   const rtems_message_queue_config    *config,
0086   rtems_id                            *id,
0087   CORE_message_queue_Allocate_buffers  allocate_buffers
0088 )
0089 {
0090   Message_queue_Control          *the_message_queue;
0091   CORE_message_queue_Disciplines  discipline;
0092   Status_Control                  status;
0093 #if defined(RTEMS_MULTIPROCESSING)
0094   bool                            is_global;
0095 #endif
0096 
0097   if ( !rtems_is_name_valid( config->name ) ) {
0098     return RTEMS_INVALID_NAME;
0099   }
0100 
0101   if ( id == NULL ) {
0102     return RTEMS_INVALID_ADDRESS;
0103   }
0104 
0105   if ( config->maximum_pending_messages == 0 ) {
0106     return RTEMS_INVALID_NUMBER;
0107   }
0108 
0109   if ( config->maximum_message_size == 0 ) {
0110     return RTEMS_INVALID_SIZE;
0111   }
0112 
0113 #if defined(RTEMS_MULTIPROCESSING)
0114   if ( _System_state_Is_multiprocessing ) {
0115     is_global = _Attributes_Is_global( config->attributes );
0116   } else {
0117     is_global = false;
0118   }
0119 
0120 #if 1
0121   /*
0122    * I am not 100% sure this should be an error.
0123    * It seems reasonable to create a que with a large max size,
0124    * and then just send smaller msgs from remote (or all) nodes.
0125    */
0126   if ( is_global ) {
0127     size_t max_packet_payload_size = _MPCI_table->maximum_packet_size
0128       - MESSAGE_QUEUE_MP_PACKET_SIZE;
0129 
0130     if ( config->maximum_message_size > max_packet_payload_size ) {
0131       return RTEMS_INVALID_SIZE;
0132     }
0133   }
0134 #endif
0135 #endif
0136 
0137   the_message_queue = _Message_queue_Allocate();
0138 
0139   if ( !the_message_queue ) {
0140     _Objects_Allocator_unlock();
0141     return RTEMS_TOO_MANY;
0142   }
0143 
0144 #if defined(RTEMS_MULTIPROCESSING)
0145   if (
0146     is_global
0147       && !_Objects_MP_Allocate_and_open(
0148             &_Message_queue_Information,
0149             config->name,
0150             the_message_queue->Object.id,
0151             false
0152           )
0153   ) {
0154     _Message_queue_Free( the_message_queue );
0155     _Objects_Allocator_unlock();
0156     return RTEMS_TOO_MANY;
0157   }
0158 
0159   the_message_queue->is_global = is_global;
0160 #endif
0161 
0162   if ( _Attributes_Is_priority( config->attributes ) ) {
0163     discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
0164   } else {
0165     discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
0166   }
0167 
0168   status = _CORE_message_queue_Initialize(
0169     &the_message_queue->message_queue,
0170     discipline,
0171     config->maximum_pending_messages,
0172     config->maximum_message_size,
0173     allocate_buffers,
0174     config
0175   );
0176 
0177   if ( status != STATUS_SUCCESSFUL ) {
0178 #if defined(RTEMS_MULTIPROCESSING)
0179     if ( is_global )
0180         _Objects_MP_Close(
0181           &_Message_queue_Information, the_message_queue->Object.id);
0182 #endif
0183 
0184     _Message_queue_Free( the_message_queue );
0185     _Objects_Allocator_unlock();
0186     return _Status_Get( status );
0187   }
0188 
0189   *id = _Objects_Open_u32(
0190     &_Message_queue_Information,
0191     &the_message_queue->Object,
0192     config->name
0193   );
0194 
0195 #if defined(RTEMS_MULTIPROCESSING)
0196   if ( is_global )
0197     _Message_queue_MP_Send_process_packet(
0198       MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
0199       the_message_queue->Object.id,
0200       config->name,
0201       0
0202     );
0203 #endif
0204 
0205   _Objects_Allocator_unlock();
0206   return RTEMS_SUCCESSFUL;
0207 }
0208 
0209 static void _Message_queue_Manager_initialization( void )
0210 {
0211   _Objects_Initialize_information( &_Message_queue_Information);
0212 }
0213 
0214 RTEMS_SYSINIT_ITEM(
0215   _Message_queue_Manager_initialization,
0216   RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE,
0217   RTEMS_SYSINIT_ORDER_MIDDLE
0218 );