Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:26

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreMessageQueue
0007  *
0008  * @brief This source file contains the implementation of
0009  *   _CORE_message_queue_Flush().
0010  */
0011 
0012 /*
0013  *  COPYRIGHT (c) 1989-1999.
0014  *  On-Line Applications Research Corporation (OAR).
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041 
0042 #include <rtems/score/coremsgimpl.h>
0043 
0044 uint32_t   _CORE_message_queue_Flush(
0045   CORE_message_queue_Control *the_message_queue,
0046   Thread_queue_Context       *queue_context
0047 )
0048 {
0049   Chain_Node *inactive_head;
0050   Chain_Node *inactive_first;
0051   Chain_Node *message_queue_first;
0052   Chain_Node *message_queue_last;
0053   uint32_t    count;
0054 
0055   /*
0056    *  Currently, RTEMS supports no API that has both flush and blocking
0057    *  sends.  Thus, this routine assumes that there are no senders
0058    *  blocked waiting to send messages.  In the event, that an API is
0059    *  added that can flush a message queue when threads are blocked
0060    *  waiting to send, there are two basic behaviors envisioned:
0061    *
0062    *  (1) The thread queue of pending senders is a logical extension
0063    *  of the pending message queue.  In this case, it should be
0064    *  flushed using the _Thread_queue_Flush_critical() service with a status
0065    *  such as CORE_MESSAGE_QUEUE_SENDER_FLUSHED (which currently does
0066    *  not exist).  This can be implemented without changing the "big-O"
0067    *  of the message flushing part of the routine.
0068    *
0069    *  (2) Only the actual messages queued should be purged.  In this case,
0070    *  the blocked sender threads must be allowed to send their messages.
0071    *  In this case, the implementation will be forced to individually
0072    *  dequeue the senders and queue their messages.  This will force
0073    *  this routine to have "big O(n)" where n is the number of blocked
0074    *  senders.  If there are more messages pending than senders blocked,
0075    *  then the existing flush code can be used to dispose of the remaining
0076    *  pending messages.
0077    *
0078    *  For now, though, we are very happy to have a small routine with
0079    *  fixed execution time that only deals with pending messages.
0080    */
0081 
0082   _CORE_message_queue_Acquire_critical( the_message_queue, queue_context );
0083 
0084   count = the_message_queue->number_of_pending_messages;
0085   if ( count != 0 ) {
0086     the_message_queue->number_of_pending_messages = 0;
0087 
0088     inactive_head = _Chain_Head( &the_message_queue->Inactive_messages );
0089     inactive_first = inactive_head->next;
0090     message_queue_first = _Chain_First( &the_message_queue->Pending_messages );
0091     message_queue_last = _Chain_Last( &the_message_queue->Pending_messages );
0092 
0093     inactive_head->next = message_queue_first;
0094     message_queue_last->next = inactive_first;
0095     inactive_first->previous = message_queue_last;
0096     message_queue_first->previous = inactive_head;
0097 
0098     _Chain_Initialize_empty( &the_message_queue->Pending_messages );
0099   }
0100 
0101   _CORE_message_queue_Release( the_message_queue, queue_context );
0102   return count;
0103 }