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