1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** ThreadX Component                                                     */
17 /**                                                                       */
18 /**   Queue                                                               */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define TX_SOURCE_CODE
24 
25 
26 /* Include necessary system files.  */
27 
28 #include "tx_api.h"
29 #include "tx_trace.h"
30 #include "tx_thread.h"
31 #include "tx_queue.h"
32 
33 
34 /**************************************************************************/
35 /*                                                                        */
36 /*  FUNCTION                                               RELEASE        */
37 /*                                                                        */
38 /*    _tx_queue_flush                                     PORTABLE C      */
39 /*                                                           6.1          */
40 /*  AUTHOR                                                                */
41 /*                                                                        */
42 /*    William E. Lamie, Microsoft Corporation                             */
43 /*                                                                        */
44 /*  DESCRIPTION                                                           */
45 /*                                                                        */
46 /*    This function resets the specified queue, if there are any messages */
47 /*    in it.  Messages waiting to be placed on the queue are also thrown  */
48 /*    out.                                                                */
49 /*                                                                        */
50 /*  INPUT                                                                 */
51 /*                                                                        */
52 /*    queue_ptr                         Pointer to queue control block    */
53 /*                                                                        */
54 /*  OUTPUT                                                                */
55 /*                                                                        */
56 /*    TX_SUCCESS                        Successful completion status      */
57 /*                                                                        */
58 /*  CALLS                                                                 */
59 /*                                                                        */
60 /*    _tx_thread_system_preempt_check   Check for preemption              */
61 /*    _tx_thread_system_resume          Resume thread service             */
62 /*    _tx_thread_system_ni_resume       Non-interruptable resume thread   */
63 /*                                                                        */
64 /*  CALLED BY                                                             */
65 /*                                                                        */
66 /*    Application Code                                                    */
67 /*                                                                        */
68 /*  RELEASE HISTORY                                                       */
69 /*                                                                        */
70 /*    DATE              NAME                      DESCRIPTION             */
71 /*                                                                        */
72 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
73 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
74 /*                                            resulting in version 6.1    */
75 /*                                                                        */
76 /**************************************************************************/
_tx_queue_flush(TX_QUEUE * queue_ptr)77 UINT  _tx_queue_flush(TX_QUEUE *queue_ptr)
78 {
79 
80 TX_INTERRUPT_SAVE_AREA
81 
82 TX_THREAD       *suspension_list;
83 UINT            suspended_count;
84 TX_THREAD       *thread_ptr;
85 
86 
87     /* Initialize the suspended count and list.  */
88     suspended_count =  TX_NO_SUSPENSIONS;
89     suspension_list =  TX_NULL;
90 
91     /* Disable interrupts to reset various queue parameters.  */
92     TX_DISABLE
93 
94     /* If trace is enabled, insert this event into the trace buffer.  */
95     TX_TRACE_IN_LINE_INSERT(TX_TRACE_QUEUE_FLUSH, queue_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_QUEUE_EVENTS)
96 
97     /* Log this kernel call.  */
98     TX_EL_QUEUE_FLUSH_INSERT
99 
100     /* Determine if there is something on the queue.  */
101     if (queue_ptr -> tx_queue_enqueued != TX_NO_MESSAGES)
102     {
103 
104         /* Yes, there is something in the queue.  */
105 
106         /* Reset the queue parameters to erase all of the queued messages.  */
107         queue_ptr -> tx_queue_enqueued =           TX_NO_MESSAGES;
108         queue_ptr -> tx_queue_available_storage =  queue_ptr -> tx_queue_capacity;
109         queue_ptr -> tx_queue_read =               queue_ptr -> tx_queue_start;
110         queue_ptr -> tx_queue_write =              queue_ptr -> tx_queue_start;
111 
112         /* Now determine if there are any threads suspended on a full queue.  */
113         if (queue_ptr -> tx_queue_suspended_count != TX_NO_SUSPENSIONS)
114         {
115 
116             /* Yes, there are threads suspended on this queue, they must be
117                resumed!  */
118 
119             /* Copy the information into temporary variables.  */
120             suspension_list =  queue_ptr -> tx_queue_suspension_list;
121             suspended_count =  queue_ptr -> tx_queue_suspended_count;
122 
123             /* Clear the queue variables.  */
124             queue_ptr -> tx_queue_suspension_list =  TX_NULL;
125             queue_ptr -> tx_queue_suspended_count =  TX_NO_SUSPENSIONS;
126 
127             /* Temporarily disable preemption.  */
128             _tx_thread_preempt_disable++;
129         }
130     }
131 
132     /* Restore interrupts.  */
133     TX_RESTORE
134 
135     /* Walk through the queue list to resume any and all threads suspended
136        on this queue.  */
137     if (suspended_count != TX_NO_SUSPENSIONS)
138     {
139 
140         /* Pickup the thread to resume.  */
141         thread_ptr =  suspension_list;
142         while (suspended_count != ((ULONG) 0))
143         {
144 
145             /* Decrement the suspension count.  */
146             suspended_count--;
147 
148             /* Check for a NULL thread pointer.  */
149             if (thread_ptr == TX_NULL)
150             {
151 
152                 /* Get out of the loop.  */
153                 break;
154             }
155 
156             /* Resume the next suspended thread.  */
157 
158             /* Lockout interrupts.  */
159             TX_DISABLE
160 
161             /* Clear the cleanup pointer, this prevents the timeout from doing
162                anything.  */
163             thread_ptr -> tx_thread_suspend_cleanup =  TX_NULL;
164 
165             /* Set the return status in the thread to TX_SUCCESS.  */
166             thread_ptr -> tx_thread_suspend_status =  TX_SUCCESS;
167 
168             /* Move the thread pointer ahead.  */
169             thread_ptr =  thread_ptr -> tx_thread_suspended_next;
170 
171 #ifdef TX_NOT_INTERRUPTABLE
172 
173             /* Resume the thread!  */
174             _tx_thread_system_ni_resume(thread_ptr -> tx_thread_suspended_previous);
175 
176             /* Restore interrupts.  */
177             TX_RESTORE
178 #else
179 
180             /* Temporarily disable preemption again.  */
181             _tx_thread_preempt_disable++;
182 
183             /* Restore interrupts.  */
184             TX_RESTORE
185 
186             /* Resume the thread.  */
187             _tx_thread_system_resume(thread_ptr -> tx_thread_suspended_previous);
188 #endif
189         }
190 
191         /* Disable interrupts.  */
192         TX_DISABLE
193 
194         /* Restore previous preempt posture.  */
195         _tx_thread_preempt_disable--;
196 
197         /* Restore interrupts.  */
198         TX_RESTORE
199 
200         /* Check for preemption.  */
201         _tx_thread_system_preempt_check();
202     }
203 
204     /* Return TX_SUCCESS.  */
205     return(TX_SUCCESS);
206 }
207 
208