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_delete PORTABLE C */
38 /* 6.1 */
39 /* AUTHOR */
40 /* */
41 /* William E. Lamie, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function deletes the specified queue. All threads suspended */
46 /* on the queue are resumed with the TX_DELETED status code. */
47 /* */
48 /* INPUT */
49 /* */
50 /* queue_ptr Pointer to queue control block */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* TX_SUCCESS Successful completion status */
55 /* */
56 /* CALLS */
57 /* */
58 /* _tx_thread_system_preempt_check Check for preemption */
59 /* _tx_thread_system_resume Resume thread service */
60 /* _tx_thread_system_ni_resume Non-interruptable resume thread */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* Application Code */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
71 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* */
74 /**************************************************************************/
_tx_queue_delete(TX_QUEUE * queue_ptr)75 UINT _tx_queue_delete(TX_QUEUE *queue_ptr)
76 {
77
78 TX_INTERRUPT_SAVE_AREA
79
80 TX_THREAD *thread_ptr;
81 TX_THREAD *next_thread;
82 UINT suspended_count;
83 TX_QUEUE *next_queue;
84 TX_QUEUE *previous_queue;
85
86
87 /* Disable interrupts to remove the queue from the created list. */
88 TX_DISABLE
89
90 /* If trace is enabled, insert this event into the trace buffer. */
91 TX_TRACE_IN_LINE_INSERT(TX_TRACE_QUEUE_DELETE, queue_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_QUEUE_EVENTS)
92
93 /* Optional queue delete extended processing. */
94 TX_QUEUE_DELETE_EXTENSION(queue_ptr)
95
96 /* If trace is enabled, unregister this object. */
97 TX_TRACE_OBJECT_UNREGISTER(queue_ptr)
98
99 /* Log this kernel call. */
100 TX_EL_QUEUE_DELETE_INSERT
101
102 /* Clear the queue ID to make it invalid. */
103 queue_ptr -> tx_queue_id = TX_CLEAR_ID;
104
105 /* Decrement the number of created queues. */
106 _tx_queue_created_count--;
107
108 /* See if the queue is the only one on the list. */
109 if (_tx_queue_created_count == TX_EMPTY)
110 {
111
112 /* Only created queue, just set the created list to NULL. */
113 _tx_queue_created_ptr = TX_NULL;
114 }
115 else
116 {
117
118 /* Link-up the neighbors. */
119 next_queue = queue_ptr -> tx_queue_created_next;
120 previous_queue = queue_ptr -> tx_queue_created_previous;
121 next_queue -> tx_queue_created_previous = previous_queue;
122 previous_queue -> tx_queue_created_next = next_queue;
123
124 /* See if we have to update the created list head pointer. */
125 if (_tx_queue_created_ptr == queue_ptr)
126 {
127
128 /* Yes, move the head pointer to the next link. */
129 _tx_queue_created_ptr = next_queue;
130 }
131 }
132
133 /* Temporarily disable preemption. */
134 _tx_thread_preempt_disable++;
135
136 /* Pickup the suspension information. */
137 thread_ptr = queue_ptr -> tx_queue_suspension_list;
138 queue_ptr -> tx_queue_suspension_list = TX_NULL;
139 suspended_count = queue_ptr -> tx_queue_suspended_count;
140 queue_ptr -> tx_queue_suspended_count = TX_NO_SUSPENSIONS;
141
142 /* Restore interrupts. */
143 TX_RESTORE
144
145 /* Walk through the queue list to resume any and all threads suspended
146 on this queue. */
147 while (suspended_count != TX_NO_SUSPENSIONS)
148 {
149
150 /* Decrement the suspension count. */
151 suspended_count--;
152
153 /* Lockout interrupts. */
154 TX_DISABLE
155
156 /* Clear the cleanup pointer, this prevents the timeout from doing
157 anything. */
158 thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
159
160 /* Set the return status in the thread to TX_DELETED. */
161 thread_ptr -> tx_thread_suspend_status = TX_DELETED;
162
163 /* Move the thread pointer ahead. */
164 next_thread = thread_ptr -> tx_thread_suspended_next;
165
166 #ifdef TX_NOT_INTERRUPTABLE
167
168 /* Resume the thread! */
169 _tx_thread_system_ni_resume(thread_ptr);
170
171 /* Restore interrupts. */
172 TX_RESTORE
173 #else
174
175 /* Temporarily disable preemption again. */
176 _tx_thread_preempt_disable++;
177
178 /* Restore interrupts. */
179 TX_RESTORE
180
181 /* Resume the thread. */
182 _tx_thread_system_resume(thread_ptr);
183 #endif
184
185 /* Move to next thread. */
186 thread_ptr = next_thread;
187 }
188
189 /* Execute Port-Specific completion processing. If needed, it is typically defined in tx_port.h. */
190 TX_QUEUE_DELETE_PORT_COMPLETION(queue_ptr)
191
192 /* Disable interrupts. */
193 TX_DISABLE
194
195 /* Release previous preempt disable. */
196 _tx_thread_preempt_disable--;
197
198 /* Restore interrupts. */
199 TX_RESTORE
200
201 /* Check for preemption. */
202 _tx_thread_system_preempt_check();
203
204 /* Return TX_SUCCESS. */
205 return(TX_SUCCESS);
206 }
207
208