| 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: coremsgflushsupp.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_Flush_support
|
| 35 |
|
|
*
|
| 36 |
|
|
* This message handler routine removes all messages from a message queue
|
| 37 |
|
|
* and returns them to the inactive message pool. The number of messages
|
| 38 |
|
|
* flushed from the queue is returned
|
| 39 |
|
|
*
|
| 40 |
|
|
* Input parameters:
|
| 41 |
|
|
* the_message_queue - pointer to message queue
|
| 42 |
|
|
*
|
| 43 |
|
|
* Output parameters:
|
| 44 |
|
|
* returns - number of messages placed on inactive chain
|
| 45 |
|
|
*
|
| 46 |
|
|
* INTERRUPT LATENCY:
|
| 47 |
|
|
* only case
|
| 48 |
|
|
*/
|
| 49 |
|
|
|
| 50 |
|
|
unsigned32 _CORE_message_queue_Flush_support(
|
| 51 |
|
|
CORE_message_queue_Control *the_message_queue
|
| 52 |
|
|
)
|
| 53 |
|
|
{
|
| 54 |
|
|
ISR_Level level;
|
| 55 |
|
|
Chain_Node *inactive_first;
|
| 56 |
|
|
Chain_Node *message_queue_first;
|
| 57 |
|
|
Chain_Node *message_queue_last;
|
| 58 |
|
|
unsigned32 count;
|
| 59 |
|
|
|
| 60 |
|
|
/*
|
| 61 |
|
|
* Currently, RTEMS supports no API that has both flush and blocking
|
| 62 |
|
|
* sends. Thus, this routine assumes that there are no senders
|
| 63 |
|
|
* blocked waiting to send messages. In the event, that an API is
|
| 64 |
|
|
* added that can flush a message queue when threads are blocked
|
| 65 |
|
|
* waiting to send, there are two basic behaviors envisioned:
|
| 66 |
|
|
*
|
| 67 |
|
|
* (1) The thread queue of pending senders is a logical extension
|
| 68 |
|
|
* of the pending message queue. In this case, it should be
|
| 69 |
|
|
* flushed using the _Thread_queue_Flush() service with a status
|
| 70 |
|
|
* such as CORE_MESSAGE_QUEUE_SENDER_FLUSHED (which currently does
|
| 71 |
|
|
* not exist). This can be implemented without changing the "big-O"
|
| 72 |
|
|
* of the message flushing part of the routine.
|
| 73 |
|
|
*
|
| 74 |
|
|
* (2) Only the actual messages queued should be purged. In this case,
|
| 75 |
|
|
* the blocked sender threads must be allowed to send their messages.
|
| 76 |
|
|
* In this case, the implementation will be forced to individually
|
| 77 |
|
|
* dequeue the senders and queue their messages. This will force
|
| 78 |
|
|
* this routine to have "big O(n)" where n is the number of blocked
|
| 79 |
|
|
* senders. If there are more messages pending than senders blocked,
|
| 80 |
|
|
* then the existing flush code can be used to dispose of the remaining
|
| 81 |
|
|
* pending messages.
|
| 82 |
|
|
*
|
| 83 |
|
|
* For now, though, we are very happy to have a small routine with
|
| 84 |
|
|
* fixed execution time that only deals with pending messages.
|
| 85 |
|
|
*/
|
| 86 |
|
|
|
| 87 |
|
|
_ISR_Disable( level );
|
| 88 |
|
|
inactive_first = the_message_queue->Inactive_messages.first;
|
| 89 |
|
|
message_queue_first = the_message_queue->Pending_messages.first;
|
| 90 |
|
|
message_queue_last = the_message_queue->Pending_messages.last;
|
| 91 |
|
|
|
| 92 |
|
|
the_message_queue->Inactive_messages.first = message_queue_first;
|
| 93 |
|
|
message_queue_last->next = inactive_first;
|
| 94 |
|
|
inactive_first->previous = message_queue_last;
|
| 95 |
|
|
message_queue_first->previous =
|
| 96 |
|
|
_Chain_Head( &the_message_queue->Inactive_messages );
|
| 97 |
|
|
|
| 98 |
|
|
_Chain_Initialize_empty( &the_message_queue->Pending_messages );
|
| 99 |
|
|
|
| 100 |
|
|
count = the_message_queue->number_of_pending_messages;
|
| 101 |
|
|
the_message_queue->number_of_pending_messages = 0;
|
| 102 |
|
|
_ISR_Enable( level );
|
| 103 |
|
|
return count;
|
| 104 |
|
|
}
|
| 105 |
|
|
|