source: rtems/cpukit/rtems/src/msgqconstruct.c @ c268766

Last change on this file since c268766 was c268766, checked in by Sebastian Huber <sebastian.huber@…>, on 05/10/21 at 07:39:35

rtems: Use _Objects_Free_nothing() for msg queues

Use _Objects_Free_nothing() for rtems_message_queue_construct() to avoid
unreachable code in _CORE_message_queue_Close() in case only
user-provided message buffers are used.

Update #4007.

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSImplClassicMessage
5 *
6 * @brief This source file contains the implementation of
7 *   rtems_message_queue_construct().
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2014.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <rtems/rtems/messageimpl.h>
24#include <rtems/rtems/attrimpl.h>
25#include <rtems/rtems/statusimpl.h>
26#include <rtems/rtems/support.h>
27#include <rtems/score/coremsgimpl.h>
28#include <rtems/sysinit.h>
29
30static void *_Message_queue_Get_buffers(
31  CORE_message_queue_Control *the_message_queue,
32  size_t                      size,
33  const void                 *arg
34)
35{
36  const rtems_message_queue_config *config;
37
38  config = arg;
39
40  if ( config->storage_size != size ) {
41    return NULL;
42  }
43
44  if ( config->storage_free != NULL ) {
45    the_message_queue->free_message_buffers = config->storage_free;
46  } else {
47    the_message_queue->free_message_buffers = _Objects_Free_nothing;
48  }
49
50  return config->storage_area;
51}
52
53rtems_status_code rtems_message_queue_construct(
54  const rtems_message_queue_config *config,
55  rtems_id                         *id
56)
57{
58  if ( config == NULL ) {
59    return RTEMS_INVALID_ADDRESS;
60  }
61
62  return _Message_queue_Create( config, id, _Message_queue_Get_buffers );
63}
64
65rtems_status_code _Message_queue_Create(
66  const rtems_message_queue_config    *config,
67  rtems_id                            *id,
68  CORE_message_queue_Allocate_buffers  allocate_buffers
69)
70{
71  Message_queue_Control          *the_message_queue;
72  CORE_message_queue_Disciplines  discipline;
73  Status_Control                  status;
74#if defined(RTEMS_MULTIPROCESSING)
75  bool                            is_global;
76#endif
77
78  if ( !rtems_is_name_valid( config->name ) ) {
79    return RTEMS_INVALID_NAME;
80  }
81
82  if ( id == NULL ) {
83    return RTEMS_INVALID_ADDRESS;
84  }
85
86  if ( config->maximum_pending_messages == 0 ) {
87    return RTEMS_INVALID_NUMBER;
88  }
89
90  if ( config->maximum_message_size == 0 ) {
91    return RTEMS_INVALID_SIZE;
92  }
93
94#if defined(RTEMS_MULTIPROCESSING)
95  if ( _System_state_Is_multiprocessing ) {
96    is_global = _Attributes_Is_global( config->attributes );
97  } else {
98    is_global = false;
99  }
100
101#if 1
102  /*
103   * I am not 100% sure this should be an error.
104   * It seems reasonable to create a que with a large max size,
105   * and then just send smaller msgs from remote (or all) nodes.
106   */
107  if ( is_global ) {
108    size_t max_packet_payload_size = _MPCI_table->maximum_packet_size
109      - MESSAGE_QUEUE_MP_PACKET_SIZE;
110
111    if ( config->maximum_message_size > max_packet_payload_size ) {
112      return RTEMS_INVALID_SIZE;
113    }
114  }
115#endif
116#endif
117
118  the_message_queue = _Message_queue_Allocate();
119
120  if ( !the_message_queue ) {
121    _Objects_Allocator_unlock();
122    return RTEMS_TOO_MANY;
123  }
124
125#if defined(RTEMS_MULTIPROCESSING)
126  if (
127    is_global
128      && !_Objects_MP_Allocate_and_open(
129            &_Message_queue_Information,
130            config->name,
131            the_message_queue->Object.id,
132            false
133          )
134  ) {
135    _Message_queue_Free( the_message_queue );
136    _Objects_Allocator_unlock();
137    return RTEMS_TOO_MANY;
138  }
139
140  the_message_queue->is_global = is_global;
141#endif
142
143  if ( _Attributes_Is_priority( config->attributes ) ) {
144    discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
145  } else {
146    discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
147  }
148
149  status = _CORE_message_queue_Initialize(
150    &the_message_queue->message_queue,
151    discipline,
152    config->maximum_pending_messages,
153    config->maximum_message_size,
154    allocate_buffers,
155    config
156  );
157
158  if ( status != STATUS_SUCCESSFUL ) {
159#if defined(RTEMS_MULTIPROCESSING)
160    if ( is_global )
161        _Objects_MP_Close(
162          &_Message_queue_Information, the_message_queue->Object.id);
163#endif
164
165    _Message_queue_Free( the_message_queue );
166    _Objects_Allocator_unlock();
167    return _Status_Get( status );
168  }
169
170  *id = _Objects_Open_u32(
171    &_Message_queue_Information,
172    &the_message_queue->Object,
173    config->name
174  );
175
176#if defined(RTEMS_MULTIPROCESSING)
177  if ( is_global )
178    _Message_queue_MP_Send_process_packet(
179      MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
180      the_message_queue->Object.id,
181      config->name,
182      0
183    );
184#endif
185
186  _Objects_Allocator_unlock();
187  return RTEMS_SUCCESSFUL;
188}
189
190static void _Message_queue_Manager_initialization( void )
191{
192  _Objects_Initialize_information( &_Message_queue_Information);
193}
194
195RTEMS_SYSINIT_ITEM(
196  _Message_queue_Manager_initialization,
197  RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE,
198  RTEMS_SYSINIT_ORDER_MIDDLE
199);
Note: See TracBrowser for help on using the repository browser.