ReactOS  0.4.13-dev-257-gfabbd7c
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 - 2019, 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 MERCHANTIBILITY 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 
52 static ACPI_STATUS
54  ACPI_MUTEX_HANDLE MutexId);
55 
56 static 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 
149 void
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);
177  return_VOID;
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 
193 static 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 
226 static 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 
239  return_VOID;
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",
355  (UINT32) AcpiOsGetThreadId (), AcpiUtGetMutexName (MutexId)));
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]",
396  AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId)));
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 }
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
#define ACPI_NUM_MUTEX
Definition: aclocal.h:92
const char * AcpiUtGetMutexName(UINT32 MutexId)
Definition: utdecode.c:478
#define ACPI_MUTEX_NOT_ACQUIRED
Definition: aclocal.h:119
#define AE_NOT_ACQUIRED
Definition: acexcep.h:128
void AcpiUtMutexTerminate(void)
Definition: utmutex.c:150
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
ACPI_THREAD_ID AcpiOsGetThreadId(void)
Definition: osl.c:217
UINT32 ACPI_MUTEX_HANDLE
Definition: aclocal.h:52
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
ACPI_STATUS AcpiUtMutexInitialize(void)
Definition: utmutex.c:75
#define ACPI_MAX_MUTEX
Definition: aclocal.h:91
ACPI_STATUS AcpiOsAcquireMutex(ACPI_MUTEX Handle, UINT16 Timeout)
Definition: osl.c:306
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
Definition: osl.c:463
#define ACPI_FUNCTION_TRACE_U32(a, b)
Definition: acoutput.h:482
Definition: Mutex.h:15
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
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
unsigned int UINT32
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define AE_INFO
Definition: acoutput.h:230
smooth NULL
Definition: ftsmooth.c:416
#define AE_ACQUIRE_DEADLOCK
Definition: acexcep.h:126
static void AcpiUtDeleteMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:227
static ACPI_STATUS AcpiUtCreateMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:194
void AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
Definition: osl.c:485
#define AE_RELEASE_DEADLOCK
Definition: acexcep.h:127
#define ACPI_WAIT_FOREVER
Definition: actypes.h:501
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
ACPI_STATUS AcpiUtCreateRwLock(ACPI_RW_LOCK *Lock)
Definition: utlock.c:66
#define return_VOID
Definition: acoutput.h:495
void AcpiUtDeleteRwLock(ACPI_RW_LOCK *Lock)
Definition: utlock.c:85
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
ACPI_STATUS AcpiOsCreateMutex(ACPI_MUTEX *OutHandle)
Definition: osl.c:271
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
ACPI_STATUS AcpiUtAcquireMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:256
void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
Definition: osl.c:333
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
void AcpiOsDeleteMutex(ACPI_MUTEX Handle)
Definition: osl.c:293
#define AE_OK
Definition: acexcep.h:97
#define ACPI_THREAD_ID
Definition: actypes.h:144
#define AE_ALREADY_ACQUIRED
Definition: acexcep.h:129
#define ACPI_DB_MUTEX
Definition: acoutput.h:182
ACPI_STATUS AcpiUtReleaseMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:348