ReactOS  0.4.15-dev-1054-gd029a62
exmutex.c File Reference
#include "acpi.h"
#include "accommon.h"
#include "acinterp.h"
#include "acevents.h"
Include dependency graph for exmutex.c:

Go to the source code of this file.

Macros

#define _COMPONENT   ACPI_EXECUTER
 

Functions

static void AcpiExLinkMutex (ACPI_OPERAND_OBJECT *ObjDesc, ACPI_THREAD_STATE *Thread)
 
void AcpiExUnlinkMutex (ACPI_OPERAND_OBJECT *ObjDesc)
 
ACPI_STATUS AcpiExAcquireMutexObject (UINT16 Timeout, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_THREAD_ID ThreadId)
 
ACPI_STATUS AcpiExAcquireMutex (ACPI_OPERAND_OBJECT *TimeDesc, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_WALK_STATE *WalkState)
 
ACPI_STATUS AcpiExReleaseMutexObject (ACPI_OPERAND_OBJECT *ObjDesc)
 
ACPI_STATUS AcpiExReleaseMutex (ACPI_OPERAND_OBJECT *ObjDesc, ACPI_WALK_STATE *WalkState)
 
void AcpiExReleaseAllMutexes (ACPI_THREAD_STATE *Thread)
 

Macro Definition Documentation

◆ _COMPONENT

#define _COMPONENT   ACPI_EXECUTER

Definition at line 49 of file exmutex.c.

Function Documentation

◆ AcpiExAcquireMutex()

ACPI_STATUS AcpiExAcquireMutex ( ACPI_OPERAND_OBJECT TimeDesc,
ACPI_OPERAND_OBJECT ObjDesc,
ACPI_WALK_STATE WalkState 
)

Definition at line 248 of file exmutex.c.

252 {
254 
255 
256  ACPI_FUNCTION_TRACE_PTR (ExAcquireMutex, ObjDesc);
257 
258 
259  if (!ObjDesc)
260  {
262  }
263 
264  /* Must have a valid thread state struct */
265 
266  if (!WalkState->Thread)
267  {
269  "Cannot acquire Mutex [%4.4s], null thread info",
270  AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
272  }
273 
274  /*
275  * Current sync level must be less than or equal to the sync level
276  * of the mutex. This mechanism provides some deadlock prevention.
277  */
278  if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
279  {
281  "Cannot acquire Mutex [%4.4s], "
282  "current SyncLevel is too large (%u)",
283  AcpiUtGetNodeName (ObjDesc->Mutex.Node),
284  WalkState->Thread->CurrentSyncLevel));
286  }
287 
289  "Acquiring: Mutex SyncLevel %u, Thread SyncLevel %u, "
290  "Depth %u TID %p\n",
291  ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel,
292  ObjDesc->Mutex.AcquisitionDepth, WalkState->Thread));
293 
295  ObjDesc, WalkState->Thread->ThreadId);
296 
297  if (ACPI_SUCCESS (Status) && ObjDesc->Mutex.AcquisitionDepth == 1)
298  {
299  /* Save Thread object, original/current sync levels */
300 
301  ObjDesc->Mutex.OwnerThread = WalkState->Thread;
302  ObjDesc->Mutex.OriginalSyncLevel =
303  WalkState->Thread->CurrentSyncLevel;
304  WalkState->Thread->CurrentSyncLevel =
305  ObjDesc->Mutex.SyncLevel;
306 
307  /* Link the mutex to the current thread for force-unlock at method exit */
308 
309  AcpiExLinkMutex (ObjDesc, WalkState->Thread);
310  }
311 
313  "Acquired: Mutex SyncLevel %u, Thread SyncLevel %u, Depth %u\n",
314  ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel,
315  ObjDesc->Mutex.AcquisitionDepth));
316 
318 }
ACPI_THREAD_STATE * Thread
Definition: acstruct.h:127
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define AE_AML_INTERNAL
Definition: acexcep.h:194
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:524
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_OBJECT_COMMON_HEADER UINT8 SyncLevel
Definition: acobject.h:186
UINT8 OriginalSyncLevel
Definition: acobject.h:194
UINT16 AcquisitionDepth
Definition: acobject.h:187
#define AE_AML_MUTEX_ORDER
Definition: acexcep.h:200
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
ACPI_STATUS AcpiExAcquireMutexObject(UINT16 Timeout, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_THREAD_ID ThreadId)
Definition: exmutex.c:176
ACPI_STATE_COMMON UINT8 CurrentSyncLevel
Definition: aclocal.h:764
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
static void AcpiExLinkMutex(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_THREAD_STATE *Thread)
Definition: exmutex.c:125
Status
Definition: gdiplustypes.h:24
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:518
#define ACPI_DB_EXEC
Definition: acoutput.h:165
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
unsigned short UINT16
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:306
ACPI_THREAD_ID ThreadId
Definition: aclocal.h:767
ACPI_NAMESPACE_NODE * Node
Definition: acobject.h:193
struct acpi_thread_state * OwnerThread
Definition: acobject.h:190

Referenced by AcpiExOpcode_2A_0T_1R().

◆ AcpiExAcquireMutexObject()

ACPI_STATUS AcpiExAcquireMutexObject ( UINT16  Timeout,
ACPI_OPERAND_OBJECT ObjDesc,
ACPI_THREAD_ID  ThreadId 
)

Definition at line 176 of file exmutex.c.

180 {
182 
183 
184  ACPI_FUNCTION_TRACE_PTR (ExAcquireMutexObject, ObjDesc);
185 
186 
187  if (!ObjDesc)
188  {
190  }
191 
192  /* Support for multiple acquires by the owning thread */
193 
194  if (ObjDesc->Mutex.ThreadId == ThreadId)
195  {
196  /*
197  * The mutex is already owned by this thread, just increment the
198  * acquisition depth
199  */
200  ObjDesc->Mutex.AcquisitionDepth++;
202  }
203 
204  /* Acquire the mutex, wait if necessary. Special case for Global Lock */
205 
206  if (ObjDesc == AcpiGbl_GlobalLockMutex)
207  {
209  }
210  else
211  {
213  }
214 
215  if (ACPI_FAILURE (Status))
216  {
217  /* Includes failure from a timeout on TimeDesc */
218 
220  }
221 
222  /* Acquired the mutex: update mutex object */
223 
224  ObjDesc->Mutex.ThreadId = ThreadId;
225  ObjDesc->Mutex.AcquisitionDepth = 1;
226  ObjDesc->Mutex.OriginalSyncLevel = 0;
227  ObjDesc->Mutex.OwnerThread = NULL; /* Used only for AML Acquire() */
228 
230 }
ACPI_STATUS AcpiEvAcquireGlobalLock(UINT16 Timeout)
Definition: evglock.c:230
ACPI_MUTEX OsMutex
Definition: acobject.h:188
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:524
UINT32 ACPI_STATUS
Definition: actypes.h:460
UINT8 OriginalSyncLevel
Definition: acobject.h:194
UINT16 AcquisitionDepth
Definition: acobject.h:187
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_STATUS AcpiExSystemWaitMutex(ACPI_MUTEX Mutex, UINT16 Timeout)
Definition: exsystem.c:120
smooth NULL
Definition: ftsmooth.c:416
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
ACPI_THREAD_ID ThreadId
Definition: acobject.h:189
Status
Definition: gdiplustypes.h:24
static ULONG Timeout
Definition: ping.c:61
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define AE_OK
Definition: acexcep.h:97
struct acpi_thread_state * OwnerThread
Definition: acobject.h:190

Referenced by AcpiAcquireGlobalLock(), AcpiExAcquireGlobalLock(), and AcpiExAcquireMutex().

◆ AcpiExLinkMutex()

static void AcpiExLinkMutex ( ACPI_OPERAND_OBJECT ObjDesc,
ACPI_THREAD_STATE Thread 
)
static

Definition at line 125 of file exmutex.c.

128 {
129  ACPI_OPERAND_OBJECT *ListHead;
130 
131 
132  ListHead = Thread->AcquiredMutexList;
133 
134  /* This object will be the first object in the list */
135 
136  ObjDesc->Mutex.Prev = NULL;
137  ObjDesc->Mutex.Next = ListHead;
138 
139  /* Update old first object to point back to this object */
140 
141  if (ListHead)
142  {
143  ListHead->Mutex.Prev = ObjDesc;
144  }
145 
146  /* Update list head */
147 
148  Thread->AcquiredMutexList = ObjDesc;
149 }
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:524
union acpi_operand_object * Next
Definition: acobject.h:192
union acpi_operand_object * Prev
Definition: acobject.h:191
smooth NULL
Definition: ftsmooth.c:416
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653

Referenced by AcpiExAcquireMutex().

◆ AcpiExReleaseAllMutexes()

void AcpiExReleaseAllMutexes ( ACPI_THREAD_STATE Thread)

Definition at line 536 of file exmutex.c.

538 {
539  ACPI_OPERAND_OBJECT *Next = Thread->AcquiredMutexList;
540  ACPI_OPERAND_OBJECT *ObjDesc;
541 
542 
543  ACPI_FUNCTION_TRACE (ExReleaseAllMutexes);
544 
545 
546  /* Traverse the list of owned mutexes, releasing each one */
547 
548  while (Next)
549  {
550  ObjDesc = Next;
552  "Mutex [%4.4s] force-release, SyncLevel %u Depth %u\n",
553  ObjDesc->Mutex.Node->Name.Ascii, ObjDesc->Mutex.SyncLevel,
554  ObjDesc->Mutex.AcquisitionDepth));
555 
556  /* Release the mutex, special case for Global Lock */
557 
558  if (ObjDesc == AcpiGbl_GlobalLockMutex)
559  {
560  /* Ignore errors */
561 
563  }
564  else
565  {
566  AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
567  }
568 
569  /* Update Thread SyncLevel (Last mutex is the important one) */
570 
571  Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
572 
573  /* Mark mutex unowned */
574 
575  Next = ObjDesc->Mutex.Next;
576 
577  ObjDesc->Mutex.Prev = NULL;
578  ObjDesc->Mutex.Next = NULL;
579  ObjDesc->Mutex.AcquisitionDepth = 0;
580  ObjDesc->Mutex.OwnerThread = NULL;
581  ObjDesc->Mutex.ThreadId = 0;
582  }
583 
584  return_VOID;
585 }
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
ACPI_MUTEX OsMutex
Definition: acobject.h:188
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:524
union acpi_operand_object * Next
Definition: acobject.h:192
char Ascii[4]
Definition: actbl.h:394
union acpi_operand_object * Prev
Definition: acobject.h:191
ACPI_OBJECT_COMMON_HEADER UINT8 SyncLevel
Definition: acobject.h:186
UINT8 OriginalSyncLevel
Definition: acobject.h:194
UINT16 AcquisitionDepth
Definition: acobject.h:187
smooth NULL
Definition: ftsmooth.c:416
ACPI_NAME_UNION Name
Definition: aclocal.h:191
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define return_VOID
Definition: acoutput.h:495
ACPI_THREAD_ID ThreadId
Definition: acobject.h:189
#define ACPI_DB_EXEC
Definition: acoutput.h:165
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
ACPI_STATUS AcpiEvReleaseGlobalLock(void)
Definition: evglock.c:333
void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
Definition: osl.c:333
ACPI_NAMESPACE_NODE * Node
Definition: acobject.h:193
struct acpi_thread_state * OwnerThread
Definition: acobject.h:190

Referenced by AcpiPsParseAml().

◆ AcpiExReleaseMutex()

ACPI_STATUS AcpiExReleaseMutex ( ACPI_OPERAND_OBJECT ObjDesc,
ACPI_WALK_STATE WalkState 
)

Definition at line 408 of file exmutex.c.

411 {
412  UINT8 PreviousSyncLevel;
413  ACPI_THREAD_STATE *OwnerThread;
415 
416 
417  ACPI_FUNCTION_TRACE (ExReleaseMutex);
418 
419 
420  if (!ObjDesc)
421  {
423  }
424 
425  OwnerThread = ObjDesc->Mutex.OwnerThread;
426 
427  /* The mutex must have been previously acquired in order to release it */
428 
429  if (!OwnerThread)
430  {
432  "Cannot release Mutex [%4.4s], not acquired",
433  AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
435  }
436 
437  /* Must have a valid thread ID */
438 
439  if (!WalkState->Thread)
440  {
442  "Cannot release Mutex [%4.4s], null thread info",
443  AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
445  }
446 
447  /*
448  * The Mutex is owned, but this thread must be the owner.
449  * Special case for Global Lock, any thread can release
450  */
451  if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
452  (ObjDesc != AcpiGbl_GlobalLockMutex))
453  {
455  "Thread %u cannot release Mutex [%4.4s] acquired by thread %u",
456  (UINT32) WalkState->Thread->ThreadId,
457  AcpiUtGetNodeName (ObjDesc->Mutex.Node),
458  (UINT32) OwnerThread->ThreadId));
460  }
461 
462  /*
463  * The sync level of the mutex must be equal to the current sync level. In
464  * other words, the current level means that at least one mutex at that
465  * level is currently being held. Attempting to release a mutex of a
466  * different level can only mean that the mutex ordering rule is being
467  * violated. This behavior is clarified in ACPI 4.0 specification.
468  */
469  if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
470  {
472  "Cannot release Mutex [%4.4s], SyncLevel mismatch: "
473  "mutex %u current %u",
474  AcpiUtGetNodeName (ObjDesc->Mutex.Node),
475  ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));
477  }
478 
479  /*
480  * Get the previous SyncLevel from the head of the acquired mutex list.
481  * This handles the case where several mutexes at the same level have been
482  * acquired, but are not released in reverse order.
483  */
484  PreviousSyncLevel =
486 
488  "Releasing: Object SyncLevel %u, Thread SyncLevel %u, "
489  "Prev SyncLevel %u, Depth %u TID %p\n",
490  ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel,
491  PreviousSyncLevel, ObjDesc->Mutex.AcquisitionDepth,
492  WalkState->Thread));
493 
494  Status = AcpiExReleaseMutexObject (ObjDesc);
495  if (ACPI_FAILURE (Status))
496  {
498  }
499 
500  if (ObjDesc->Mutex.AcquisitionDepth == 0)
501  {
502  /* Restore the previous SyncLevel */
503 
504  OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
505  }
506 
508  "Released: Object SyncLevel %u, Thread SyncLevel, %u, "
509  "Prev SyncLevel %u, Depth %u\n",
510  ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel,
511  PreviousSyncLevel, ObjDesc->Mutex.AcquisitionDepth));
512 
514 }
ACPI_THREAD_STATE * Thread
Definition: acstruct.h:127
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define AE_AML_MUTEX_NOT_ACQUIRED
Definition: acexcep.h:201
#define AE_AML_INTERNAL
Definition: acexcep.h:194
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:524
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_OBJECT_COMMON_HEADER UINT8 SyncLevel
Definition: acobject.h:186
ACPI_STATUS AcpiExReleaseMutexObject(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: exmutex.c:344
UINT8 OriginalSyncLevel
Definition: acobject.h:194
UINT16 AcquisitionDepth
Definition: acobject.h:187
#define AE_AML_MUTEX_ORDER
Definition: acexcep.h:200
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
unsigned int UINT32
#define AE_INFO
Definition: acoutput.h:230
ACPI_STATE_COMMON UINT8 CurrentSyncLevel
Definition: aclocal.h:764
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
Status
Definition: gdiplustypes.h:24
union acpi_operand_object * AcquiredMutexList
Definition: aclocal.h:766
#define ACPI_DB_EXEC
Definition: acoutput.h:165
#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
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:306
#define AE_AML_NOT_OWNER
Definition: acexcep.h:199
ACPI_THREAD_ID ThreadId
Definition: aclocal.h:767
unsigned char UINT8
#define AE_OK
Definition: acexcep.h:97
ACPI_NAMESPACE_NODE * Node
Definition: acobject.h:193
struct acpi_thread_state * OwnerThread
Definition: acobject.h:190

Referenced by AcpiExOpcode_1A_0T_0R().

◆ AcpiExReleaseMutexObject()

ACPI_STATUS AcpiExReleaseMutexObject ( ACPI_OPERAND_OBJECT ObjDesc)

Definition at line 344 of file exmutex.c.

346 {
348 
349 
350  ACPI_FUNCTION_TRACE (ExReleaseMutexObject);
351 
352 
353  if (ObjDesc->Mutex.AcquisitionDepth == 0)
354  {
356  }
357 
358  /* Match multiple Acquires with multiple Releases */
359 
360  ObjDesc->Mutex.AcquisitionDepth--;
361  if (ObjDesc->Mutex.AcquisitionDepth != 0)
362  {
363  /* Just decrement the depth and return */
364 
366  }
367 
368  if (ObjDesc->Mutex.OwnerThread)
369  {
370  /* Unlink the mutex from the owner's list */
371 
372  AcpiExUnlinkMutex (ObjDesc);
373  ObjDesc->Mutex.OwnerThread = NULL;
374  }
375 
376  /* Release the mutex, special case for Global Lock */
377 
378  if (ObjDesc == AcpiGbl_GlobalLockMutex)
379  {
381  }
382  else
383  {
384  AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
385  }
386 
387  /* Clear mutex info */
388 
389  ObjDesc->Mutex.ThreadId = 0;
391 }
#define AE_NOT_ACQUIRED
Definition: acexcep.h:128
ACPI_MUTEX OsMutex
Definition: acobject.h:188
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:524
UINT32 ACPI_STATUS
Definition: actypes.h:460
UINT16 AcquisitionDepth
Definition: acobject.h:187
void AcpiExUnlinkMutex(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: exmutex.c:73
smooth NULL
Definition: ftsmooth.c:416
ACPI_THREAD_ID ThreadId
Definition: acobject.h:189
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 AcpiEvReleaseGlobalLock(void)
Definition: evglock.c:333
void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
Definition: osl.c:333
#define AE_OK
Definition: acexcep.h:97
struct acpi_thread_state * OwnerThread
Definition: acobject.h:190

Referenced by AcpiExReleaseGlobalLock(), AcpiExReleaseMutex(), and AcpiReleaseGlobalLock().

◆ AcpiExUnlinkMutex()

void AcpiExUnlinkMutex ( ACPI_OPERAND_OBJECT ObjDesc)

Definition at line 73 of file exmutex.c.

75 {
77 
78 
79  if (!Thread)
80  {
81  return;
82  }
83 
84  /* Doubly linked list */
85 
86  if (ObjDesc->Mutex.Next)
87  {
88  (ObjDesc->Mutex.Next)->Mutex.Prev = ObjDesc->Mutex.Prev;
89  }
90 
91  if (ObjDesc->Mutex.Prev)
92  {
93  (ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
94 
95  /*
96  * Migrate the previous sync level associated with this mutex to
97  * the previous mutex on the list so that it may be preserved.
98  * This handles the case where several mutexes have been acquired
99  * at the same level, but are not released in opposite order.
100  */
101  (ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
102  ObjDesc->Mutex.OriginalSyncLevel;
103  }
104  else
105  {
106  Thread->AcquiredMutexList = ObjDesc->Mutex.Next;
107  }
108 }
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:524
union acpi_operand_object * Next
Definition: acobject.h:192
union acpi_operand_object * Prev
Definition: acobject.h:191
Definition: Mutex.h:15
UINT8 OriginalSyncLevel
Definition: acobject.h:194
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
struct acpi_thread_state * OwnerThread
Definition: acobject.h:190

Referenced by AcpiExReleaseMutexObject(), and AcpiUtDeleteInternalObj().