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 /** Mutex */
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_initialize.h"
29 #include "tx_thread.h"
30 #include "tx_timer.h"
31 #include "tx_mutex.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _txe_mutex_create PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* William E. Lamie, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function checks for errors in the create mutex function */
47 /* call. */
48 /* */
49 /* INPUT */
50 /* */
51 /* mutex_ptr Pointer to mutex control block */
52 /* name_ptr Pointer to mutex name */
53 /* inherit Initial mutex count */
54 /* mutex_control_block_size Size of mutex control block */
55 /* */
56 /* OUTPUT */
57 /* */
58 /* TX_MUTEX_ERROR Invalid mutex pointer */
59 /* TX_CALLER_ERROR Invalid caller of this function */
60 /* TX_INHERIT_ERROR Invalid inherit option */
61 /* status Actual completion status */
62 /* */
63 /* CALLS */
64 /* */
65 /* _tx_mutex_create Actual create mutex function */
66 /* _tx_thread_system_preempt_check Check for preemption */
67 /* */
68 /* CALLED BY */
69 /* */
70 /* Application Code */
71 /* */
72 /* RELEASE HISTORY */
73 /* */
74 /* DATE NAME DESCRIPTION */
75 /* */
76 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
77 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
78 /* resulting in version 6.1 */
79 /* */
80 /**************************************************************************/
_txe_mutex_create(TX_MUTEX * mutex_ptr,CHAR * name_ptr,UINT inherit,UINT mutex_control_block_size)81 UINT _txe_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size)
82 {
83
84 TX_INTERRUPT_SAVE_AREA
85
86 UINT status;
87 ULONG i;
88 TX_MUTEX *next_mutex;
89 #ifndef TX_TIMER_PROCESS_IN_ISR
90 TX_THREAD *thread_ptr;
91 #endif
92
93
94 /* Default status to success. */
95 status = TX_SUCCESS;
96
97 /* Check for an invalid mutex pointer. */
98 if (mutex_ptr == TX_NULL)
99 {
100
101 /* Mutex pointer is invalid, return appropriate error code. */
102 status = TX_MUTEX_ERROR;
103 }
104
105 /* Now check to make sure the control block is the correct size. */
106 else if (mutex_control_block_size != (sizeof(TX_MUTEX)))
107 {
108
109 /* Mutex pointer is invalid, return appropriate error code. */
110 status = TX_MUTEX_ERROR;
111 }
112 else
113 {
114
115 /* Disable interrupts. */
116 TX_DISABLE
117
118 /* Increment the preempt disable flag. */
119 _tx_thread_preempt_disable++;
120
121 /* Restore interrupts. */
122 TX_RESTORE
123
124 /* Next see if it is already in the created list. */
125 next_mutex = _tx_mutex_created_ptr;
126 for (i = ((ULONG) 0); i < _tx_mutex_created_count; i++)
127 {
128
129 /* Determine if this mutex matches the mutex in the list. */
130 if (mutex_ptr == next_mutex)
131 {
132
133 break;
134 }
135 else
136 {
137
138 /* Move to the next mutex. */
139 next_mutex = next_mutex -> tx_mutex_created_next;
140 }
141 }
142
143 /* Disable interrupts. */
144 TX_DISABLE
145
146 /* Decrement the preempt disable flag. */
147 _tx_thread_preempt_disable--;
148
149 /* Restore interrupts. */
150 TX_RESTORE
151
152 /* Check for preemption. */
153 _tx_thread_system_preempt_check();
154
155 /* At this point, check to see if there is a duplicate mutex. */
156 if (mutex_ptr == next_mutex)
157 {
158
159 /* Mutex is already created, return appropriate error code. */
160 status = TX_MUTEX_ERROR;
161 }
162 else
163 {
164
165 /* Check for a valid inherit option. */
166 if (inherit != TX_INHERIT)
167 {
168
169 if (inherit != TX_NO_INHERIT)
170 {
171
172 /* Inherit option is illegal. */
173 status = TX_INHERIT_ERROR;
174 }
175 }
176 }
177 }
178
179 /* Determine if everything is okay. */
180 if (status == TX_SUCCESS)
181 {
182
183 #ifndef TX_TIMER_PROCESS_IN_ISR
184
185 /* Pickup thread pointer. */
186 TX_THREAD_GET_CURRENT(thread_ptr)
187
188 /* Check for invalid caller of this function. First check for a calling thread. */
189 if (thread_ptr == &_tx_timer_thread)
190 {
191
192 /* Invalid caller of this function, return appropriate error code. */
193 status = TX_CALLER_ERROR;
194 }
195 #endif
196
197 /* Check for interrupt call. */
198 if (TX_THREAD_GET_SYSTEM_STATE() != ((ULONG) 0))
199 {
200
201 /* Now, make sure the call is from an interrupt and not initialization. */
202 if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
203 {
204
205 /* Invalid caller of this function, return appropriate error code. */
206 status = TX_CALLER_ERROR;
207 }
208 }
209 }
210
211 /* Determine if everything is okay. */
212 if (status == TX_SUCCESS)
213 {
214
215 /* Call actual mutex create function. */
216 status = _tx_mutex_create(mutex_ptr, name_ptr, inherit);
217 }
218
219 /* Return completion status. */
220 return(status);
221 }
222
223