| 1 |
30 |
unneback |
/*
|
| 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: coremsgsubmit.c,v 1.2 2001-09-27 11:59:34 chris Exp $
|
| 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_Submit
|
| 35 |
|
|
*
|
| 36 |
|
|
* This routine implements the send and urgent message functions. It
|
| 37 |
|
|
* processes a message that is to be submitted to the designated
|
| 38 |
|
|
* message queue. The message will either be processed as a
|
| 39 |
|
|
* send message which it will be inserted at the rear of the queue
|
| 40 |
|
|
* or it will be processed as an urgent message which will be inserted
|
| 41 |
|
|
* at the front of the queue.
|
| 42 |
|
|
*
|
| 43 |
|
|
* Input parameters:
|
| 44 |
|
|
* the_message_queue - message is submitted to this message queue
|
| 45 |
|
|
* buffer - pointer to message buffer
|
| 46 |
|
|
* size - size in bytes of message to send
|
| 47 |
|
|
* id - id of message queue
|
| 48 |
|
|
* api_message_queue_mp_support - api specific mp support callout
|
| 49 |
|
|
* submit_type - send or urgent message
|
| 50 |
|
|
*
|
| 51 |
|
|
* Output parameters:
|
| 52 |
|
|
* CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
|
| 53 |
|
|
* error code - if unsuccessful
|
| 54 |
|
|
*/
|
| 55 |
|
|
|
| 56 |
|
|
void _CORE_message_queue_Submit(
|
| 57 |
|
|
CORE_message_queue_Control *the_message_queue,
|
| 58 |
|
|
void *buffer,
|
| 59 |
|
|
unsigned32 size,
|
| 60 |
|
|
Objects_Id id,
|
| 61 |
|
|
CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
|
| 62 |
|
|
CORE_message_queue_Submit_types submit_type,
|
| 63 |
|
|
boolean wait,
|
| 64 |
|
|
Watchdog_Interval timeout
|
| 65 |
|
|
)
|
| 66 |
|
|
{
|
| 67 |
|
|
ISR_Level level;
|
| 68 |
|
|
CORE_message_queue_Buffer_control *the_message;
|
| 69 |
|
|
Thread_Control *the_thread;
|
| 70 |
|
|
Thread_Control *executing;
|
| 71 |
|
|
|
| 72 |
|
|
_Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
| 73 |
|
|
|
| 74 |
|
|
if ( size > the_message_queue->maximum_message_size ) {
|
| 75 |
|
|
_Thread_Executing->Wait.return_code =
|
| 76 |
|
|
CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
|
| 77 |
|
|
return;
|
| 78 |
|
|
}
|
| 79 |
|
|
|
| 80 |
|
|
/*
|
| 81 |
|
|
* Is there a thread currently waiting on this message queue?
|
| 82 |
|
|
*/
|
| 83 |
|
|
|
| 84 |
|
|
if ( the_message_queue->number_of_pending_messages == 0 ) {
|
| 85 |
|
|
the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
|
| 86 |
|
|
if ( the_thread ) {
|
| 87 |
|
|
_CORE_message_queue_Copy_buffer(
|
| 88 |
|
|
buffer,
|
| 89 |
|
|
the_thread->Wait.return_argument,
|
| 90 |
|
|
size
|
| 91 |
|
|
);
|
| 92 |
|
|
*(unsigned32 *)the_thread->Wait.return_argument_1 = size;
|
| 93 |
|
|
the_thread->Wait.count = submit_type;
|
| 94 |
|
|
|
| 95 |
|
|
#if defined(RTEMS_MULTIPROCESSING)
|
| 96 |
|
|
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
|
| 97 |
|
|
(*api_message_queue_mp_support) ( the_thread, id );
|
| 98 |
|
|
#endif
|
| 99 |
|
|
return;
|
| 100 |
|
|
}
|
| 101 |
|
|
}
|
| 102 |
|
|
|
| 103 |
|
|
/*
|
| 104 |
|
|
* No one waiting on the message queue at this time, so attempt to
|
| 105 |
|
|
* queue the message up for a future receive.
|
| 106 |
|
|
*/
|
| 107 |
|
|
|
| 108 |
|
|
if ( the_message_queue->number_of_pending_messages <
|
| 109 |
|
|
the_message_queue->maximum_pending_messages ) {
|
| 110 |
|
|
|
| 111 |
|
|
the_message =
|
| 112 |
|
|
_CORE_message_queue_Allocate_message_buffer( the_message_queue );
|
| 113 |
|
|
|
| 114 |
|
|
/*
|
| 115 |
|
|
* NOTE: If the system is consistent, this error should never occur.
|
| 116 |
|
|
*/
|
| 117 |
|
|
if ( !the_message ) {
|
| 118 |
|
|
_Thread_Executing->Wait.return_code =
|
| 119 |
|
|
CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
|
| 120 |
|
|
return;
|
| 121 |
|
|
}
|
| 122 |
|
|
|
| 123 |
|
|
_CORE_message_queue_Copy_buffer(
|
| 124 |
|
|
buffer,
|
| 125 |
|
|
the_message->Contents.buffer,
|
| 126 |
|
|
size
|
| 127 |
|
|
);
|
| 128 |
|
|
the_message->Contents.size = size;
|
| 129 |
|
|
the_message->priority = submit_type;
|
| 130 |
|
|
|
| 131 |
|
|
_CORE_message_queue_Insert_message(
|
| 132 |
|
|
the_message_queue,
|
| 133 |
|
|
the_message,
|
| 134 |
|
|
submit_type
|
| 135 |
|
|
);
|
| 136 |
|
|
return;
|
| 137 |
|
|
}
|
| 138 |
|
|
|
| 139 |
|
|
/*
|
| 140 |
|
|
* No message buffers were available so we may need to return an
|
| 141 |
|
|
* overflow error or block the sender until the message is placed
|
| 142 |
|
|
* on the queue.
|
| 143 |
|
|
*/
|
| 144 |
|
|
|
| 145 |
|
|
if ( !wait ) {
|
| 146 |
|
|
_Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
|
| 147 |
|
|
return;
|
| 148 |
|
|
}
|
| 149 |
|
|
|
| 150 |
|
|
executing = _Thread_Executing;
|
| 151 |
|
|
|
| 152 |
|
|
_ISR_Disable( level );
|
| 153 |
|
|
_Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
|
| 154 |
|
|
executing->Wait.queue = &the_message_queue->Wait_queue;
|
| 155 |
|
|
executing->Wait.id = id;
|
| 156 |
|
|
executing->Wait.return_argument = (void *)buffer;
|
| 157 |
|
|
executing->Wait.return_argument_1 = (void *)size;
|
| 158 |
|
|
executing->Wait.count = submit_type;
|
| 159 |
|
|
_ISR_Enable( level );
|
| 160 |
|
|
|
| 161 |
|
|
_Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
|
| 162 |
|
|
}
|