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 |
|
|
|