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 /** Mutex */
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_mutex.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _tx_mutex_delete PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* William E. Lamie, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function deletes the specified mutex. All threads */
47 /* suspended on the mutex are resumed with the TX_DELETED status */
48 /* code. */
49 /* */
50 /* INPUT */
51 /* */
52 /* mutex_ptr Pointer to mutex control block */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* TX_SUCCESS Successful completion status */
57 /* */
58 /* CALLS */
59 /* */
60 /* _tx_mutex_put Release an owned mutex */
61 /* _tx_thread_system_preempt_check Check for preemption */
62 /* _tx_thread_system_resume Resume thread service */
63 /* _tx_thread_system_ni_resume Non-interruptable resume thread */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* Application Code */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
74 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
75 /* resulting in version 6.1 */
76 /* */
77 /**************************************************************************/
_tx_mutex_delete(TX_MUTEX * mutex_ptr)78 UINT _tx_mutex_delete(TX_MUTEX *mutex_ptr)
79 {
80
81 TX_INTERRUPT_SAVE_AREA
82
83 TX_THREAD *thread_ptr;
84 TX_THREAD *next_thread;
85 TX_THREAD *owner_thread;
86 UINT suspended_count;
87 TX_MUTEX *next_mutex;
88 TX_MUTEX *previous_mutex;
89 #ifdef TX_MISRA_ENABLE
90 UINT status;
91 #endif
92
93 /* Disable interrupts to remove the mutex from the created list. */
94 TX_DISABLE
95
96 /* If trace is enabled, insert this event into the trace buffer. */
97 TX_TRACE_IN_LINE_INSERT(TX_TRACE_MUTEX_DELETE, mutex_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_MUTEX_EVENTS)
98
99 /* Optional mutex delete extended processing. */
100 TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
101
102 /* If trace is enabled, unregister this object. */
103 TX_TRACE_OBJECT_UNREGISTER(mutex_ptr)
104
105 /* Log this kernel call. */
106 TX_EL_MUTEX_DELETE_INSERT
107
108 /* Clear the mutex ID to make it invalid. */
109 mutex_ptr -> tx_mutex_id = TX_CLEAR_ID;
110
111 /* Decrement the created count. */
112 _tx_mutex_created_count--;
113
114 /* See if the mutex is the only one on the list. */
115 if (_tx_mutex_created_count == TX_EMPTY)
116 {
117
118 /* Only created mutex, just set the created list to NULL. */
119 _tx_mutex_created_ptr = TX_NULL;
120 }
121 else
122 {
123
124 /* Link-up the neighbors. */
125 next_mutex = mutex_ptr -> tx_mutex_created_next;
126 previous_mutex = mutex_ptr -> tx_mutex_created_previous;
127 next_mutex -> tx_mutex_created_previous = previous_mutex;
128 previous_mutex -> tx_mutex_created_next = next_mutex;
129
130 /* See if we have to update the created list head pointer. */
131 if (_tx_mutex_created_ptr == mutex_ptr)
132 {
133
134 /* Yes, move the head pointer to the next link. */
135 _tx_mutex_created_ptr = next_mutex;
136 }
137 }
138
139 /* Temporarily disable preemption. */
140 _tx_thread_preempt_disable++;
141
142 /* Pickup the suspension information. */
143 thread_ptr = mutex_ptr -> tx_mutex_suspension_list;
144 mutex_ptr -> tx_mutex_suspension_list = TX_NULL;
145 suspended_count = mutex_ptr -> tx_mutex_suspended_count;
146 mutex_ptr -> tx_mutex_suspended_count = TX_NO_SUSPENSIONS;
147
148
149 /* Determine if the mutex is currently on a thread's ownership list. */
150
151 /* Setup pointer to owner of mutex. */
152 owner_thread = mutex_ptr -> tx_mutex_owner;
153
154 /* Determine if there is a valid thread pointer. */
155 if (owner_thread != TX_NULL)
156 {
157
158 /* Yes, remove this mutex from the owned list. */
159
160 /* Set the ownership count to 1. */
161 mutex_ptr -> tx_mutex_ownership_count = ((UINT) 1);
162
163 /* Restore interrupts. */
164 TX_RESTORE
165
166 #ifdef TX_MISRA_ENABLE
167 /* Release the mutex. */
168 do
169 {
170 status = _tx_mutex_put(mutex_ptr);
171 } while (status != TX_SUCCESS);
172 #else
173 _tx_mutex_put(mutex_ptr);
174 #endif
175
176 /* Disable interrupts. */
177 TX_DISABLE
178 }
179
180 /* Restore interrupts. */
181 TX_RESTORE
182
183 /* Walk through the mutex list to resume any and all threads suspended
184 on this mutex. */
185 while (suspended_count != ((ULONG) 0))
186 {
187
188 /* Decrement the suspension count. */
189 suspended_count--;
190
191 /* Lockout interrupts. */
192 TX_DISABLE
193
194 /* Clear the cleanup pointer, this prevents the timeout from doing
195 anything. */
196 thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
197
198 /* Set the return status in the thread to TX_DELETED. */
199 thread_ptr -> tx_thread_suspend_status = TX_DELETED;
200
201 /* Move the thread pointer ahead. */
202 next_thread = thread_ptr -> tx_thread_suspended_next;
203
204 #ifdef TX_NOT_INTERRUPTABLE
205
206 /* Resume the thread! */
207 _tx_thread_system_ni_resume(thread_ptr);
208
209 /* Restore interrupts. */
210 TX_RESTORE
211 #else
212
213 /* Temporarily disable preemption again. */
214 _tx_thread_preempt_disable++;
215
216 /* Restore interrupts. */
217 TX_RESTORE
218
219 /* Resume the thread. */
220 _tx_thread_system_resume(thread_ptr);
221 #endif
222
223 /* Move to next thread. */
224 thread_ptr = next_thread;
225 }
226
227 /* Execute Port-Specific completion processing. If needed, it is typically defined in tx_port.h. */
228 TX_MUTEX_DELETE_PORT_COMPLETION(mutex_ptr)
229
230 /* Disable interrupts. */
231 TX_DISABLE
232
233 /* Release previous preempt disable. */
234 _tx_thread_preempt_disable--;
235
236 /* Restore interrupts. */
237 TX_RESTORE
238
239 /* Check for preemption. */
240 _tx_thread_system_preempt_check();
241
242 /* Return TX_SUCCESS. */
243 return(TX_SUCCESS);
244 }
245
246