source: rtems/c/src/exec/score/src/coremsgbroadcast.c @ e4c07444

4.104.114.84.95
Last change on this file since e4c07444 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: 3.5 KB
Line 
1/*
2 *  CORE Message Queue Handler
3 *
4 *  DESCRIPTION:
5 *
6 *  This package is the implementation of the CORE Message Queue Handler.
7 *  This core object provides task synchronization and communication functions
8 *  via messages passed to queue objects.
9 *
10 *  COPYRIGHT (c) 1989-1999.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.OARcorp.com/rtems/license.html.
16 *
17 *  $Id$
18 */
19
20#include <rtems/system.h>
21#include <rtems/score/chain.h>
22#include <rtems/score/isr.h>
23#include <rtems/score/object.h>
24#include <rtems/score/coremsg.h>
25#include <rtems/score/states.h>
26#include <rtems/score/thread.h>
27#include <rtems/score/wkspace.h>
28#if defined(RTEMS_MULTIPROCESSING)
29#include <rtems/score/mpci.h>
30#endif
31
32/*PAGE
33 *
34 *  _CORE_message_queue_Broadcast
35 *
36 *  This function sends a message for every thread waiting on the queue and
37 *  returns the number of threads made ready by the message.
38 *
39 *  Input parameters:
40 *    the_message_queue            - message is submitted to this message queue
41 *    buffer                       - pointer to message buffer
42 *    size                         - size in bytes of message to send
43 *    id                           - id of message queue
44 *    api_message_queue_mp_support - api specific mp support callout
45 *    count                        - area to store number of threads made ready
46 *
47 *  Output parameters:
48 *    count                         - number of threads made ready
49 *    CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
50 *    error code                    - if unsuccessful
51 */
52
53CORE_message_queue_Status _CORE_message_queue_Broadcast(
54  CORE_message_queue_Control                *the_message_queue,
55  void                                      *buffer,
56  unsigned32                                 size,
57  Objects_Id                                 id,
58  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
59  unsigned32                                *count
60)
61{
62  Thread_Control          *the_thread;
63  unsigned32               number_broadcasted;
64  Thread_Wait_information *waitp;
65  unsigned32               constrained_size;
66
67  /*
68   *  If there are pending messages, then there can't be threads
69   *  waiting for us to send them a message.
70   *
71   *  NOTE: This check is critical because threads can block on
72   *        send and receive and this ensures that we are broadcasting
73   *        the message to threads waiting to receive -- not to send.
74   */
75
76  if ( the_message_queue->number_of_pending_messages != 0 ) {
77    *count = 0;
78    return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
79  }
80
81  /*
82   *  There must be no pending messages if there is a thread waiting to
83   *  receive a message.
84   */
85
86  number_broadcasted = 0;
87  while ((the_thread = _Thread_queue_Dequeue(&the_message_queue->Wait_queue))) {
88    waitp = &the_thread->Wait;
89    number_broadcasted += 1;
90
91    constrained_size = size;
92    if ( size > the_message_queue->maximum_message_size )
93        constrained_size = the_message_queue->maximum_message_size;
94
95    _CORE_message_queue_Copy_buffer(
96      buffer,
97      waitp->return_argument,
98      constrained_size
99    );
100
101    *(unsigned32 *)the_thread->Wait.return_argument_1 = size;
102
103#if defined(RTEMS_MULTIPROCESSING)
104    if ( !_Objects_Is_local_id( the_thread->Object.id ) )
105      (*api_message_queue_mp_support) ( the_thread, id );
106#endif
107
108  }
109  *count = number_broadcasted;
110  return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
111}
112
Note: See TracBrowser for help on using the repository browser.