ReactOS 0.4.16-dev-306-g647d351
utmutex.c
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Module Name: utmutex - local mutex support
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2022, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include "acpi.h"
45#include "accommon.h"
46
47#define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME ("utmutex")
49
50/* Local prototypes */
51
52static ACPI_STATUS
54 ACPI_MUTEX_HANDLE MutexId);
55
56static void
58 ACPI_MUTEX_HANDLE MutexId);
59
60
61/*******************************************************************************
62 *
63 * FUNCTION: AcpiUtMutexInitialize
64 *
65 * PARAMETERS: None.
66 *
67 * RETURN: Status
68 *
69 * DESCRIPTION: Create the system mutex objects. This includes mutexes,
70 * spin locks, and reader/writer locks.
71 *
72 ******************************************************************************/
73
76 void)
77{
78 UINT32 i;
80
81
82 ACPI_FUNCTION_TRACE (UtMutexInitialize);
83
84
85 /* Create each of the predefined mutex objects */
86
87 for (i = 0; i < ACPI_NUM_MUTEX; i++)
88 {
90 if (ACPI_FAILURE (Status))
91 {
93 }
94 }
95
96 /* Create the spinlocks for use at interrupt level or for speed */
97
98 Status = AcpiOsCreateLock (&AcpiGbl_GpeLock);
99 if (ACPI_FAILURE (Status))
100 {
102 }
103
104 Status = AcpiOsCreateLock (&AcpiGbl_HardwareLock);
105 if (ACPI_FAILURE (Status))
106 {
108 }
109
110 Status = AcpiOsCreateLock (&AcpiGbl_ReferenceCountLock);
111 if (ACPI_FAILURE (Status))
112 {
114 }
115
116 /* Mutex for _OSI support */
117
118 Status = AcpiOsCreateMutex (&AcpiGbl_OsiMutex);
119 if (ACPI_FAILURE (Status))
120 {
122 }
123
124 /* Create the reader/writer lock for namespace access */
125
126 Status = AcpiUtCreateRwLock (&AcpiGbl_NamespaceRwLock);
127 if (ACPI_FAILURE (Status))
128 {
130 }
131
133}
134
135
136/*******************************************************************************
137 *
138 * FUNCTION: AcpiUtMutexTerminate
139 *
140 * PARAMETERS: None.
141 *
142 * RETURN: None.
143 *
144 * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
145 * spin locks, and reader/writer locks.
146 *
147 ******************************************************************************/
148
149void
151 void)
152{
153 UINT32 i;
154
155
156 ACPI_FUNCTION_TRACE (UtMutexTerminate);
157
158
159 /* Delete each predefined mutex object */
160
161 for (i = 0; i < ACPI_NUM_MUTEX; i++)
162 {
164 }
165
166 AcpiOsDeleteMutex (AcpiGbl_OsiMutex);
167
168 /* Delete the spinlocks */
169
170 AcpiOsDeleteLock (AcpiGbl_GpeLock);
171 AcpiOsDeleteLock (AcpiGbl_HardwareLock);
172 AcpiOsDeleteLock (AcpiGbl_ReferenceCountLock);
173
174 /* Delete the reader/writer lock */
175
176 AcpiUtDeleteRwLock (&AcpiGbl_NamespaceRwLock);
178}
179
180
181/*******************************************************************************
182 *
183 * FUNCTION: AcpiUtCreateMutex
184 *
185 * PARAMETERS: MutexID - ID of the mutex to be created
186 *
187 * RETURN: Status
188 *
189 * DESCRIPTION: Create a mutex object.
190 *
191 ******************************************************************************/
192
193static ACPI_STATUS
195 ACPI_MUTEX_HANDLE MutexId)
196{
198
199
200 ACPI_FUNCTION_TRACE_U32 (UtCreateMutex, MutexId);
201
202
203 if (!AcpiGbl_MutexInfo[MutexId].Mutex)
204 {
205 Status = AcpiOsCreateMutex (&AcpiGbl_MutexInfo[MutexId].Mutex);
206 AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
207 AcpiGbl_MutexInfo[MutexId].UseCount = 0;
208 }
209
211}
212
213
214/*******************************************************************************
215 *
216 * FUNCTION: AcpiUtDeleteMutex
217 *
218 * PARAMETERS: MutexID - ID of the mutex to be deleted
219 *
220 * RETURN: Status
221 *
222 * DESCRIPTION: Delete a mutex object.
223 *
224 ******************************************************************************/
225
226static void
228 ACPI_MUTEX_HANDLE MutexId)
229{
230
231 ACPI_FUNCTION_TRACE_U32 (UtDeleteMutex, MutexId);
232
233
234 AcpiOsDeleteMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
235
236 AcpiGbl_MutexInfo[MutexId].Mutex = NULL;
237 AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
238
240}
241
242
243/*******************************************************************************
244 *
245 * FUNCTION: AcpiUtAcquireMutex
246 *
247 * PARAMETERS: MutexID - ID of the mutex to be acquired
248 *
249 * RETURN: Status
250 *
251 * DESCRIPTION: Acquire a mutex object.
252 *
253 ******************************************************************************/
254
257 ACPI_MUTEX_HANDLE MutexId)
258{
260 ACPI_THREAD_ID ThisThreadId;
261
262
263 ACPI_FUNCTION_NAME (UtAcquireMutex);
264
265
266 if (MutexId > ACPI_MAX_MUTEX)
267 {
268 return (AE_BAD_PARAMETER);
269 }
270
271 ThisThreadId = AcpiOsGetThreadId ();
272
273#ifdef ACPI_MUTEX_DEBUG
274 {
275 UINT32 i;
276 /*
277 * Mutex debug code, for internal debugging only.
278 *
279 * Deadlock prevention. Check if this thread owns any mutexes of value
280 * greater than or equal to this one. If so, the thread has violated
281 * the mutex ordering rule. This indicates a coding error somewhere in
282 * the ACPI subsystem code.
283 */
284 for (i = MutexId; i < ACPI_NUM_MUTEX; i++)
285 {
286 if (AcpiGbl_MutexInfo[i].ThreadId == ThisThreadId)
287 {
288 if (i == MutexId)
289 {
291 "Mutex [%s] already acquired by this thread [%u]",
292 AcpiUtGetMutexName (MutexId),
293 (UINT32) ThisThreadId));
294
295 return (AE_ALREADY_ACQUIRED);
296 }
297
299 "Invalid acquire order: Thread %u owns [%s], wants [%s]",
300 (UINT32) ThisThreadId, AcpiUtGetMutexName (i),
301 AcpiUtGetMutexName (MutexId)));
302
303 return (AE_ACQUIRE_DEADLOCK);
304 }
305 }
306 }
307#endif
308
310 "Thread %u attempting to acquire Mutex [%s]\n",
311 (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId)));
312
314 AcpiGbl_MutexInfo[MutexId].Mutex, ACPI_WAIT_FOREVER);
315 if (ACPI_SUCCESS (Status))
316 {
318 "Thread %u acquired Mutex [%s]\n",
319 (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId)));
320
321 AcpiGbl_MutexInfo[MutexId].UseCount++;
322 AcpiGbl_MutexInfo[MutexId].ThreadId = ThisThreadId;
323 }
324 else
325 {
327 "Thread %u could not acquire Mutex [%s] (0x%X)",
328 (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId), MutexId));
329 }
330
331 return (Status);
332}
333
334
335/*******************************************************************************
336 *
337 * FUNCTION: AcpiUtReleaseMutex
338 *
339 * PARAMETERS: MutexID - ID of the mutex to be released
340 *
341 * RETURN: Status
342 *
343 * DESCRIPTION: Release a mutex object.
344 *
345 ******************************************************************************/
346
349 ACPI_MUTEX_HANDLE MutexId)
350{
351 ACPI_FUNCTION_NAME (UtReleaseMutex);
352
353
354 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
356
357 if (MutexId > ACPI_MAX_MUTEX)
358 {
359 return (AE_BAD_PARAMETER);
360 }
361
362 /*
363 * Mutex must be acquired in order to release it!
364 */
365 if (AcpiGbl_MutexInfo[MutexId].ThreadId == ACPI_MUTEX_NOT_ACQUIRED)
366 {
368 "Mutex [%s] (0x%X) is not acquired, cannot release",
369 AcpiUtGetMutexName (MutexId), MutexId));
370
371 return (AE_NOT_ACQUIRED);
372 }
373
374#ifdef ACPI_MUTEX_DEBUG
375 {
376 UINT32 i;
377 /*
378 * Mutex debug code, for internal debugging only.
379 *
380 * Deadlock prevention. Check if this thread owns any mutexes of value
381 * greater than this one. If so, the thread has violated the mutex
382 * ordering rule. This indicates a coding error somewhere in
383 * the ACPI subsystem code.
384 */
385 for (i = MutexId; i < ACPI_NUM_MUTEX; i++)
386 {
387 if (AcpiGbl_MutexInfo[i].ThreadId == AcpiOsGetThreadId ())
388 {
389 if (i == MutexId)
390 {
391 continue;
392 }
393
395 "Invalid release order: owns [%s], releasing [%s]",
397
398 return (AE_RELEASE_DEADLOCK);
399 }
400 }
401 }
402#endif
403
404 /* Mark unlocked FIRST */
405
406 AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
407
408 AcpiOsReleaseMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
409 return (AE_OK);
410}
unsigned int UINT32
#define AE_ALREADY_ACQUIRED
Definition: acexcep.h:129
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_ACQUIRE_DEADLOCK
Definition: acexcep.h:126
#define AE_RELEASE_DEADLOCK
Definition: acexcep.h:127
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define AE_NOT_ACQUIRED
Definition: acexcep.h:128
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define AE_OK
Definition: acexcep.h:97
#define ACPI_MAX_MUTEX
Definition: aclocal.h:91
UINT32 ACPI_MUTEX_HANDLE
Definition: aclocal.h:52
#define ACPI_MUTEX_NOT_ACQUIRED
Definition: aclocal.h:119
#define ACPI_NUM_MUTEX
Definition: aclocal.h:92
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define ACPI_FUNCTION_TRACE_U32(a, b)
Definition: acoutput.h:482
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
#define return_VOID
Definition: acoutput.h:495
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
#define ACPI_DB_MUTEX
Definition: acoutput.h:182
ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
Definition: osl.c:463
ACPI_THREAD_ID AcpiOsGetThreadId(void)
Definition: osl.c:217
void AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
Definition: osl.c:485
#define AcpiOsDeleteMutex(Handle)
Definition: actypes.h:275
#define AcpiOsAcquireMutex(Handle, Time)
Definition: actypes.h:276
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define AcpiOsReleaseMutex(Handle)
Definition: actypes.h:277
#define ACPI_WAIT_FOREVER
Definition: actypes.h:501
#define ACPI_THREAD_ID
Definition: actypes.h:144
#define AcpiOsCreateMutex(OutHandle)
Definition: actypes.h:274
ACPI_STATUS AcpiUtCreateRwLock(ACPI_RW_LOCK *Lock)
Definition: utlock.c:66
void AcpiUtDeleteRwLock(ACPI_RW_LOCK *Lock)
Definition: utlock.c:85
const char * AcpiUtGetMutexName(UINT32 MutexId)
Definition: utdecode.c:479
Definition: Mutex.h:16
#define NULL
Definition: types.h:112
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void AcpiUtDeleteMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:227
ACPI_STATUS AcpiUtAcquireMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:256
ACPI_STATUS AcpiUtMutexInitialize(void)
Definition: utmutex.c:75
ACPI_STATUS AcpiUtReleaseMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:348
static ACPI_STATUS AcpiUtCreateMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:194
void AcpiUtMutexTerminate(void)
Definition: utmutex.c:150