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 /** Event Flags */
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_event_flags.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _tx_event_flags_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 event flag group. All threads */
47 /* suspended on the group are resumed with the TX_DELETED status */
48 /* code. */
49 /* */
50 /* INPUT */
51 /* */
52 /* group_ptr Pointer to group 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_event_flags_delete(TX_EVENT_FLAGS_GROUP * group_ptr)77 UINT _tx_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr)
78 {
79
80 TX_INTERRUPT_SAVE_AREA
81
82 TX_THREAD *thread_ptr;
83 TX_THREAD *next_thread;
84 UINT suspended_count;
85 TX_EVENT_FLAGS_GROUP *next_group;
86 TX_EVENT_FLAGS_GROUP *previous_group;
87
88
89 /* Disable interrupts to remove the group from the created list. */
90 TX_DISABLE
91
92 /* If trace is enabled, insert this event into the trace buffer. */
93 TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_DELETE, group_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
94
95 /* Optional event flags group delete extended processing. */
96 TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
97
98 /* If trace is enabled, unregister this object. */
99 TX_TRACE_OBJECT_UNREGISTER(group_ptr)
100
101 /* Log this kernel call. */
102 TX_EL_EVENT_FLAGS_DELETE_INSERT
103
104 /* Clear the event flag group ID to make it invalid. */
105 group_ptr -> tx_event_flags_group_id = TX_CLEAR_ID;
106
107 /* Decrement the number of created event flag groups. */
108 _tx_event_flags_created_count--;
109
110 /* See if this group is the only one on the list. */
111 if (_tx_event_flags_created_count == TX_EMPTY)
112 {
113
114 /* Only created event flag group, just set the created list to NULL. */
115 _tx_event_flags_created_ptr = TX_NULL;
116 }
117 else
118 {
119
120 /* Link-up the neighbors. */
121 next_group = group_ptr -> tx_event_flags_group_created_next;
122 previous_group = group_ptr -> tx_event_flags_group_created_previous;
123 next_group -> tx_event_flags_group_created_previous = previous_group;
124 previous_group -> tx_event_flags_group_created_next = next_group;
125
126 /* See if we have to update the created list head pointer. */
127 if (_tx_event_flags_created_ptr == group_ptr)
128 {
129
130 /* Yes, move the head pointer to the next link. */
131 _tx_event_flags_created_ptr = next_group;
132 }
133 }
134
135 /* Temporarily disable preemption. */
136 _tx_thread_preempt_disable++;
137
138 /* Pickup the suspension information. */
139 thread_ptr = group_ptr -> tx_event_flags_group_suspension_list;
140 group_ptr -> tx_event_flags_group_suspension_list = TX_NULL;
141 suspended_count = group_ptr -> tx_event_flags_group_suspended_count;
142 group_ptr -> tx_event_flags_group_suspended_count = TX_NO_SUSPENSIONS;
143
144 /* Restore interrupts. */
145 TX_RESTORE
146
147 /* Walk through the event flag suspension list to resume any and all threads
148 suspended on this group. */
149 while (suspended_count != TX_NO_SUSPENSIONS)
150 {
151
152 /* Decrement the number of suspended threads. */
153 suspended_count--;
154
155 /* Lockout interrupts. */
156 TX_DISABLE
157
158 /* Clear the cleanup pointer, this prevents the timeout from doing
159 anything. */
160 thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
161
162 /* Set the return status in the thread to TX_DELETED. */
163 thread_ptr -> tx_thread_suspend_status = TX_DELETED;
164
165 /* Move the thread pointer ahead. */
166 next_thread = thread_ptr -> tx_thread_suspended_next;
167
168 #ifdef TX_NOT_INTERRUPTABLE
169
170 /* Resume the thread! */
171 _tx_thread_system_ni_resume(thread_ptr);
172
173 /* Restore interrupts. */
174 TX_RESTORE
175 #else
176
177 /* Temporarily disable preemption again. */
178 _tx_thread_preempt_disable++;
179
180 /* Restore interrupts. */
181 TX_RESTORE
182
183 /* Resume the thread. */
184 _tx_thread_system_resume(thread_ptr);
185 #endif
186
187 /* Move to next thread. */
188 thread_ptr = next_thread;
189 }
190
191 /* Execute Port-Specific completion processing. If needed, it is typically defined in tx_port.h. */
192 TX_EVENT_FLAGS_GROUP_DELETE_PORT_COMPLETION(group_ptr)
193
194 /* Disable interrupts. */
195 TX_DISABLE
196
197 /* Release previous preempt disable. */
198 _tx_thread_preempt_disable--;
199
200 /* Restore interrupts. */
201 TX_RESTORE
202
203 /* Check for preemption. */
204 _tx_thread_system_preempt_check();
205
206 /* Return TX_SUCCESS. */
207 return(TX_SUCCESS);
208 }
209
210