source: rtems/cpukit/rtems/src/msgqcreate.c @ 8ef3818

4.104.114.84.95
Last change on this file since 8ef3818 was 53fb837a, checked in by Joel Sherrill <joel.sherrill@…>, on 01/13/00 at 19:25:15

POSIX message queues now include complete functionality including
blocking sends when the queue is full. The SuperCore? was enhanced
to support blocking on send. The existing POSIX API was debugged
and numerous test cases were added to psxmsgq01 by Jennifer Averett.
SuperCore? enhancements and resulting modifications to other APIs
were done by Joel.

There is one significant point of interpretation for the POSIX API.
What happens to threads already blocked on a message queue when the
mode of that same message queue is changed from blocking to non-blocking?
We decided to unblock all waiting tasks with an EAGAIN error just
as if a non-blocking version of the same operation had returned
unsatisfied. This case is not discussed in the POSIX standard and
other implementations may have chosen differently.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 *  Message Queue Manager
3 *
4 *
5 *  COPYRIGHT (c) 1989-1999.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15#include <rtems/system.h>
16#include <rtems/score/sysstate.h>
17#include <rtems/score/chain.h>
18#include <rtems/score/isr.h>
19#include <rtems/score/coremsg.h>
20#include <rtems/score/object.h>
21#include <rtems/score/states.h>
22#include <rtems/score/thread.h>
23#include <rtems/score/wkspace.h>
24#if defined(RTEMS_MULTIPROCESSING)
25#include <rtems/score/mpci.h>
26#endif
27#include <rtems/rtems/status.h>
28#include <rtems/rtems/attr.h>
29#include <rtems/rtems/message.h>
30#include <rtems/rtems/options.h>
31#include <rtems/rtems/support.h>
32
33/*PAGE
34 *
35 *  rtems_message_queue_create
36 *
37 *  This directive creates a message queue by allocating and initializing
38 *  a message queue data structure.
39 *
40 *  Input parameters:
41 *    name             - user defined queue name
42 *    count            - maximum message and reserved buffer count
43 *    max_message_size - maximum size of each message
44 *    attribute_set    - process method
45 *    id               - pointer to queue
46 *
47 *  Output parameters:
48 *    id                - queue id
49 *    RTEMS_SUCCESSFUL  - if successful
50 *    error code        - if unsuccessful
51 */
52
53rtems_status_code rtems_message_queue_create(
54  rtems_name          name,
55  unsigned32          count,
56  unsigned32          max_message_size,
57  rtems_attribute     attribute_set,
58  Objects_Id         *id
59)
60{
61  register Message_queue_Control *the_message_queue;
62  CORE_message_queue_Attributes   the_msgq_attributes;
63  void                           *handler;
64#if defined(RTEMS_MULTIPROCESSING)
65  boolean                         is_global;
66#endif
67
68  if ( !rtems_is_name_valid( name ) )
69    return RTEMS_INVALID_NAME;
70
71#if defined(RTEMS_MULTIPROCESSING)
72  if ( (is_global = _Attributes_Is_global( attribute_set ) ) &&
73       !_System_state_Is_multiprocessing )
74    return RTEMS_MP_NOT_CONFIGURED;
75#endif
76
77  if ( count == 0 )
78      return RTEMS_INVALID_NUMBER;
79
80  if ( max_message_size == 0 )
81      return RTEMS_INVALID_SIZE;
82
83#if defined(RTEMS_MULTIPROCESSING)
84#if 1
85  /*
86   * I am not 100% sure this should be an error.
87   * It seems reasonable to create a que with a large max size,
88   * and then just send smaller msgs from remote (or all) nodes.
89   */
90 
91  if ( is_global && (_MPCI_table->maximum_packet_size < max_message_size) )
92    return RTEMS_INVALID_SIZE;
93#endif
94#endif
95       
96  _Thread_Disable_dispatch();              /* protects object pointer */
97
98  the_message_queue = _Message_queue_Allocate( count, max_message_size );
99
100  if ( !the_message_queue ) {
101    _Thread_Enable_dispatch();
102    return RTEMS_TOO_MANY;
103  }
104
105#if defined(RTEMS_MULTIPROCESSING)
106  if ( is_global &&
107    !( _Objects_MP_Allocate_and_open( &_Message_queue_Information,
108                              name, the_message_queue->Object.id, FALSE ) ) ) {
109    _Message_queue_Free( the_message_queue );
110    _Thread_Enable_dispatch();
111    return RTEMS_TOO_MANY;
112  }
113#endif
114
115  the_message_queue->attribute_set = attribute_set;
116
117  if (_Attributes_Is_priority( attribute_set ) )
118    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
119  else
120    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
121
122  handler = NULL;
123#if defined(RTEMS_MULTIPROCESSING)
124  handler = _Message_queue_MP_Send_extract_proxy;
125#endif
126
127  if ( ! _CORE_message_queue_Initialize(
128           &the_message_queue->message_queue,
129           OBJECTS_RTEMS_MESSAGE_QUEUES,
130           &the_msgq_attributes,
131           count,
132           max_message_size,
133           handler ) ) {
134#if defined(RTEMS_MULTIPROCESSING)
135    if ( is_global )
136        _Objects_MP_Close(
137          &_Message_queue_Information, the_message_queue->Object.id);
138#endif
139
140    _Message_queue_Free( the_message_queue );
141    _Thread_Enable_dispatch();
142    return RTEMS_TOO_MANY;
143  }
144
145  _Objects_Open(
146    &_Message_queue_Information,
147    &the_message_queue->Object,
148    &name
149  );
150
151  *id = the_message_queue->Object.id;
152
153#if defined(RTEMS_MULTIPROCESSING)
154  if ( is_global )
155    _Message_queue_MP_Send_process_packet(
156      MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
157      the_message_queue->Object.id,
158      name,
159      0
160    );
161#endif
162
163  _Thread_Enable_dispatch();
164  return RTEMS_SUCCESSFUL;
165}
Note: See TracBrowser for help on using the repository browser.