/** * @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. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include rtems_status_code rtems_message_queue_create( rtems_name name, uint32_t count, size_t max_message_size, rtems_attribute attribute_set, rtems_id *id ) { Message_queue_Control *the_message_queue; CORE_message_queue_Disciplines discipline; #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 ( (is_global = _Attributes_Is_global( attribute_set ) ) && !_System_state_Is_multiprocessing ) return RTEMS_MP_NOT_CONFIGURED; #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; } #endif the_message_queue->attribute_set = attribute_set; if (_Attributes_Is_priority( attribute_set ) ) discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY; else discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO; if ( ! _CORE_message_queue_Initialize( &the_message_queue->message_queue, discipline, count, max_message_size ) ) { #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 RTEMS_UNSATISFIED; } _Objects_Open( &_Message_queue_Information, &the_message_queue->Object, (Objects_Name) 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, name, 0 ); #endif _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } static void _Message_queue_Manager_initialization(void) { _Objects_Initialize_information( &_Message_queue_Information); /* * Register the MP Process Packet routine. */ #if defined(RTEMS_MULTIPROCESSING) _MPCI_Register_packet_processor( MP_PACKET_MESSAGE_QUEUE, _Message_queue_MP_Process_packet ); #endif } RTEMS_SYSINIT_ITEM( _Message_queue_Manager_initialization, RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE, RTEMS_SYSINIT_ORDER_MIDDLE );