ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

exmutex.c
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003  *
00004  * Module Name: exmutex - ASL Mutex Acquire/Release functions
00005  *
00006  *****************************************************************************/
00007 
00008 /******************************************************************************
00009  *
00010  * 1. Copyright Notice
00011  *
00012  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00013  * All rights reserved.
00014  *
00015  * 2. License
00016  *
00017  * 2.1. This is your license from Intel Corp. under its intellectual property
00018  * rights.  You may have additional license terms from the party that provided
00019  * you this software, covering your right to use that party's intellectual
00020  * property rights.
00021  *
00022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00023  * copy of the source code appearing in this file ("Covered Code") an
00024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00025  * base code distributed originally by Intel ("Original Intel Code") to copy,
00026  * make derivatives, distribute, use and display any portion of the Covered
00027  * Code in any form, with the right to sublicense such rights; and
00028  *
00029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00030  * license (with the right to sublicense), under only those claims of Intel
00031  * patents that are infringed by the Original Intel Code, to make, use, sell,
00032  * offer to sell, and import the Covered Code and derivative works thereof
00033  * solely to the minimum extent necessary to exercise the above copyright
00034  * license, and in no event shall the patent license extend to any additions
00035  * to or modifications of the Original Intel Code.  No other license or right
00036  * is granted directly or by implication, estoppel or otherwise;
00037  *
00038  * The above copyright and patent license is granted only if the following
00039  * conditions are met:
00040  *
00041  * 3. Conditions
00042  *
00043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00044  * Redistribution of source code of any substantial portion of the Covered
00045  * Code or modification with rights to further distribute source must include
00046  * the above Copyright Notice, the above License, this list of Conditions,
00047  * and the following Disclaimer and Export Compliance provision.  In addition,
00048  * Licensee must cause all Covered Code to which Licensee contributes to
00049  * contain a file documenting the changes Licensee made to create that Covered
00050  * Code and the date of any change.  Licensee must include in that file the
00051  * documentation of any changes made by any predecessor Licensee.  Licensee
00052  * must include a prominent statement that the modification is derived,
00053  * directly or indirectly, from Original Intel Code.
00054  *
00055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00056  * Redistribution of source code of any substantial portion of the Covered
00057  * Code or modification without rights to further distribute source must
00058  * include the following Disclaimer and Export Compliance provision in the
00059  * documentation and/or other materials provided with distribution.  In
00060  * addition, Licensee may not authorize further sublicense of source of any
00061  * portion of the Covered Code, and must include terms to the effect that the
00062  * license from Licensee to its licensee is limited to the intellectual
00063  * property embodied in the software Licensee provides to its licensee, and
00064  * not to intellectual property embodied in modifications its licensee may
00065  * make.
00066  *
00067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00068  * substantial portion of the Covered Code or modification must reproduce the
00069  * above Copyright Notice, and the following Disclaimer and Export Compliance
00070  * provision in the documentation and/or other materials provided with the
00071  * distribution.
00072  *
00073  * 3.4. Intel retains all right, title, and interest in and to the Original
00074  * Intel Code.
00075  *
00076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00077  * Intel shall be used in advertising or otherwise to promote the sale, use or
00078  * other dealings in products derived from or relating to the Covered Code
00079  * without prior written authorization from Intel.
00080  *
00081  * 4. Disclaimer and Export Compliance
00082  *
00083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00084  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00086  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00089  * PARTICULAR PURPOSE.
00090  *
00091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00098  * LIMITED REMEDY.
00099  *
00100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00101  * software or system incorporating such software without first obtaining any
00102  * required license or other approval from the U. S. Department of Commerce or
00103  * any other agency or department of the United States Government.  In the
00104  * event Licensee exports any such software from the United States or
00105  * re-exports any such software from a foreign destination, Licensee shall
00106  * ensure that the distribution and export/re-export of the software is in
00107  * compliance with all laws, regulations, orders, or other restrictions of the
00108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00109  * any of its subsidiaries will export/re-export any technical data, process,
00110  * software, or service, directly or indirectly, to any country for which the
00111  * United States government or any agency thereof requires an export license,
00112  * other governmental approval, or letter of assurance, without first obtaining
00113  * such license, approval or letter.
00114  *
00115  *****************************************************************************/
00116 
00117 #define __EXMUTEX_C__
00118 
00119 #include "acpi.h"
00120 #include "accommon.h"
00121 #include "acinterp.h"
00122 #include "acevents.h"
00123 
00124 #define _COMPONENT          ACPI_EXECUTER
00125         ACPI_MODULE_NAME    ("exmutex")
00126 
00127 /* Local prototypes */
00128 
00129 static void
00130 AcpiExLinkMutex (
00131     ACPI_OPERAND_OBJECT     *ObjDesc,
00132     ACPI_THREAD_STATE       *Thread);
00133 
00134 
00135 /*******************************************************************************
00136  *
00137  * FUNCTION:    AcpiExUnlinkMutex
00138  *
00139  * PARAMETERS:  ObjDesc             - The mutex to be unlinked
00140  *
00141  * RETURN:      None
00142  *
00143  * DESCRIPTION: Remove a mutex from the "AcquiredMutex" list
00144  *
00145  ******************************************************************************/
00146 
00147 void
00148 AcpiExUnlinkMutex (
00149     ACPI_OPERAND_OBJECT     *ObjDesc)
00150 {
00151     ACPI_THREAD_STATE       *Thread = ObjDesc->Mutex.OwnerThread;
00152 
00153 
00154     if (!Thread)
00155     {
00156         return;
00157     }
00158 
00159     /* Doubly linked list */
00160 
00161     if (ObjDesc->Mutex.Next)
00162     {
00163         (ObjDesc->Mutex.Next)->Mutex.Prev = ObjDesc->Mutex.Prev;
00164     }
00165 
00166     if (ObjDesc->Mutex.Prev)
00167     {
00168         (ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
00169 
00170         /*
00171          * Migrate the previous sync level associated with this mutex to
00172          * the previous mutex on the list so that it may be preserved.
00173          * This handles the case where several mutexes have been acquired
00174          * at the same level, but are not released in opposite order.
00175          */
00176         (ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
00177             ObjDesc->Mutex.OriginalSyncLevel;
00178     }
00179     else
00180     {
00181         Thread->AcquiredMutexList = ObjDesc->Mutex.Next;
00182     }
00183 }
00184 
00185 
00186 /*******************************************************************************
00187  *
00188  * FUNCTION:    AcpiExLinkMutex
00189  *
00190  * PARAMETERS:  ObjDesc             - The mutex to be linked
00191  *              Thread              - Current executing thread object
00192  *
00193  * RETURN:      None
00194  *
00195  * DESCRIPTION: Add a mutex to the "AcquiredMutex" list for this walk
00196  *
00197  ******************************************************************************/
00198 
00199 static void
00200 AcpiExLinkMutex (
00201     ACPI_OPERAND_OBJECT     *ObjDesc,
00202     ACPI_THREAD_STATE       *Thread)
00203 {
00204     ACPI_OPERAND_OBJECT     *ListHead;
00205 
00206 
00207     ListHead = Thread->AcquiredMutexList;
00208 
00209     /* This object will be the first object in the list */
00210 
00211     ObjDesc->Mutex.Prev = NULL;
00212     ObjDesc->Mutex.Next = ListHead;
00213 
00214     /* Update old first object to point back to this object */
00215 
00216     if (ListHead)
00217     {
00218         ListHead->Mutex.Prev = ObjDesc;
00219     }
00220 
00221     /* Update list head */
00222 
00223     Thread->AcquiredMutexList = ObjDesc;
00224 }
00225 
00226 
00227 /*******************************************************************************
00228  *
00229  * FUNCTION:    AcpiExAcquireMutexObject
00230  *
00231  * PARAMETERS:  Timeout             - Timeout in milliseconds
00232  *              ObjDesc             - Mutex object
00233  *              ThreadId            - Current thread state
00234  *
00235  * RETURN:      Status
00236  *
00237  * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common
00238  *              path that supports multiple acquires by the same thread.
00239  *
00240  * MUTEX:       Interpreter must be locked
00241  *
00242  * NOTE: This interface is called from three places:
00243  * 1) From AcpiExAcquireMutex, via an AML Acquire() operator
00244  * 2) From AcpiExAcquireGlobalLock when an AML Field access requires the
00245  *    global lock
00246  * 3) From the external interface, AcpiAcquireGlobalLock
00247  *
00248  ******************************************************************************/
00249 
00250 ACPI_STATUS
00251 AcpiExAcquireMutexObject (
00252     UINT16                  Timeout,
00253     ACPI_OPERAND_OBJECT     *ObjDesc,
00254     ACPI_THREAD_ID          ThreadId)
00255 {
00256     ACPI_STATUS             Status;
00257 
00258 
00259     ACPI_FUNCTION_TRACE_PTR (ExAcquireMutexObject, ObjDesc);
00260 
00261 
00262     if (!ObjDesc)
00263     {
00264         return_ACPI_STATUS (AE_BAD_PARAMETER);
00265     }
00266 
00267     /* Support for multiple acquires by the owning thread */
00268 
00269     if (ObjDesc->Mutex.ThreadId == ThreadId)
00270     {
00271         /*
00272          * The mutex is already owned by this thread, just increment the
00273          * acquisition depth
00274          */
00275         ObjDesc->Mutex.AcquisitionDepth++;
00276         return_ACPI_STATUS (AE_OK);
00277     }
00278 
00279     /* Acquire the mutex, wait if necessary. Special case for Global Lock */
00280 
00281     if (ObjDesc == AcpiGbl_GlobalLockMutex)
00282     {
00283         Status = AcpiEvAcquireGlobalLock (Timeout);
00284     }
00285     else
00286     {
00287         Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex,
00288                     Timeout);
00289     }
00290 
00291     if (ACPI_FAILURE (Status))
00292     {
00293         /* Includes failure from a timeout on TimeDesc */
00294 
00295         return_ACPI_STATUS (Status);
00296     }
00297 
00298     /* Acquired the mutex: update mutex object */
00299 
00300     ObjDesc->Mutex.ThreadId = ThreadId;
00301     ObjDesc->Mutex.AcquisitionDepth = 1;
00302     ObjDesc->Mutex.OriginalSyncLevel = 0;
00303     ObjDesc->Mutex.OwnerThread = NULL;      /* Used only for AML Acquire() */
00304 
00305     return_ACPI_STATUS (AE_OK);
00306 }
00307 
00308 
00309 /*******************************************************************************
00310  *
00311  * FUNCTION:    AcpiExAcquireMutex
00312  *
00313  * PARAMETERS:  TimeDesc            - Timeout integer
00314  *              ObjDesc             - Mutex object
00315  *              WalkState           - Current method execution state
00316  *
00317  * RETURN:      Status
00318  *
00319  * DESCRIPTION: Acquire an AML mutex
00320  *
00321  ******************************************************************************/
00322 
00323 ACPI_STATUS
00324 AcpiExAcquireMutex (
00325     ACPI_OPERAND_OBJECT     *TimeDesc,
00326     ACPI_OPERAND_OBJECT     *ObjDesc,
00327     ACPI_WALK_STATE         *WalkState)
00328 {
00329     ACPI_STATUS             Status;
00330 
00331 
00332     ACPI_FUNCTION_TRACE_PTR (ExAcquireMutex, ObjDesc);
00333 
00334 
00335     if (!ObjDesc)
00336     {
00337         return_ACPI_STATUS (AE_BAD_PARAMETER);
00338     }
00339 
00340     /* Must have a valid thread state struct */
00341 
00342     if (!WalkState->Thread)
00343     {
00344         ACPI_ERROR ((AE_INFO,
00345             "Cannot acquire Mutex [%4.4s], null thread info",
00346             AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
00347         return_ACPI_STATUS (AE_AML_INTERNAL);
00348     }
00349 
00350     /*
00351      * Current sync level must be less than or equal to the sync level of the
00352      * mutex. This mechanism provides some deadlock prevention
00353      */
00354     if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
00355     {
00356         ACPI_ERROR ((AE_INFO,
00357             "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%u)",
00358             AcpiUtGetNodeName (ObjDesc->Mutex.Node),
00359             WalkState->Thread->CurrentSyncLevel));
00360         return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
00361     }
00362 
00363     Status = AcpiExAcquireMutexObject ((UINT16) TimeDesc->Integer.Value,
00364                 ObjDesc, WalkState->Thread->ThreadId);
00365     if (ACPI_SUCCESS (Status) && ObjDesc->Mutex.AcquisitionDepth == 1)
00366     {
00367         /* Save Thread object, original/current sync levels */
00368 
00369         ObjDesc->Mutex.OwnerThread = WalkState->Thread;
00370         ObjDesc->Mutex.OriginalSyncLevel = WalkState->Thread->CurrentSyncLevel;
00371         WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.SyncLevel;
00372 
00373         /* Link the mutex to the current thread for force-unlock at method exit */
00374 
00375         AcpiExLinkMutex (ObjDesc, WalkState->Thread);
00376     }
00377 
00378     return_ACPI_STATUS (Status);
00379 }
00380 
00381 
00382 /*******************************************************************************
00383  *
00384  * FUNCTION:    AcpiExReleaseMutexObject
00385  *
00386  * PARAMETERS:  ObjDesc             - The object descriptor for this op
00387  *
00388  * RETURN:      Status
00389  *
00390  * DESCRIPTION: Release a previously acquired Mutex, low level interface.
00391  *              Provides a common path that supports multiple releases (after
00392  *              previous multiple acquires) by the same thread.
00393  *
00394  * MUTEX:       Interpreter must be locked
00395  *
00396  * NOTE: This interface is called from three places:
00397  * 1) From AcpiExReleaseMutex, via an AML Acquire() operator
00398  * 2) From AcpiExReleaseGlobalLock when an AML Field access requires the
00399  *    global lock
00400  * 3) From the external interface, AcpiReleaseGlobalLock
00401  *
00402  ******************************************************************************/
00403 
00404 ACPI_STATUS
00405 AcpiExReleaseMutexObject (
00406     ACPI_OPERAND_OBJECT     *ObjDesc)
00407 {
00408     ACPI_STATUS             Status = AE_OK;
00409 
00410 
00411     ACPI_FUNCTION_TRACE (ExReleaseMutexObject);
00412 
00413 
00414     if (ObjDesc->Mutex.AcquisitionDepth == 0)
00415     {
00416         return (AE_NOT_ACQUIRED);
00417     }
00418 
00419     /* Match multiple Acquires with multiple Releases */
00420 
00421     ObjDesc->Mutex.AcquisitionDepth--;
00422     if (ObjDesc->Mutex.AcquisitionDepth != 0)
00423     {
00424         /* Just decrement the depth and return */
00425 
00426         return_ACPI_STATUS (AE_OK);
00427     }
00428 
00429     if (ObjDesc->Mutex.OwnerThread)
00430     {
00431         /* Unlink the mutex from the owner's list */
00432 
00433         AcpiExUnlinkMutex (ObjDesc);
00434         ObjDesc->Mutex.OwnerThread = NULL;
00435     }
00436 
00437     /* Release the mutex, special case for Global Lock */
00438 
00439     if (ObjDesc == AcpiGbl_GlobalLockMutex)
00440     {
00441         Status = AcpiEvReleaseGlobalLock ();
00442     }
00443     else
00444     {
00445         AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
00446     }
00447 
00448     /* Clear mutex info */
00449 
00450     ObjDesc->Mutex.ThreadId = 0;
00451     return_ACPI_STATUS (Status);
00452 }
00453 
00454 
00455 /*******************************************************************************
00456  *
00457  * FUNCTION:    AcpiExReleaseMutex
00458  *
00459  * PARAMETERS:  ObjDesc             - The object descriptor for this op
00460  *              WalkState           - Current method execution state
00461  *
00462  * RETURN:      Status
00463  *
00464  * DESCRIPTION: Release a previously acquired Mutex.
00465  *
00466  ******************************************************************************/
00467 
00468 ACPI_STATUS
00469 AcpiExReleaseMutex (
00470     ACPI_OPERAND_OBJECT     *ObjDesc,
00471     ACPI_WALK_STATE         *WalkState)
00472 {
00473     ACPI_STATUS             Status = AE_OK;
00474     UINT8                   PreviousSyncLevel;
00475     ACPI_THREAD_STATE       *OwnerThread;
00476 
00477 
00478     ACPI_FUNCTION_TRACE (ExReleaseMutex);
00479 
00480 
00481     if (!ObjDesc)
00482     {
00483         return_ACPI_STATUS (AE_BAD_PARAMETER);
00484     }
00485 
00486     OwnerThread = ObjDesc->Mutex.OwnerThread;
00487 
00488     /* The mutex must have been previously acquired in order to release it */
00489 
00490     if (!OwnerThread)
00491     {
00492         ACPI_ERROR ((AE_INFO,
00493             "Cannot release Mutex [%4.4s], not acquired",
00494             AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
00495         return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
00496     }
00497 
00498     /* Must have a valid thread ID */
00499 
00500     if (!WalkState->Thread)
00501     {
00502         ACPI_ERROR ((AE_INFO,
00503             "Cannot release Mutex [%4.4s], null thread info",
00504             AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
00505         return_ACPI_STATUS (AE_AML_INTERNAL);
00506     }
00507 
00508     /*
00509      * The Mutex is owned, but this thread must be the owner.
00510      * Special case for Global Lock, any thread can release
00511      */
00512     if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
00513         (ObjDesc != AcpiGbl_GlobalLockMutex))
00514     {
00515         ACPI_ERROR ((AE_INFO,
00516             "Thread %u cannot release Mutex [%4.4s] acquired by thread %u",
00517             (UINT32) WalkState->Thread->ThreadId,
00518             AcpiUtGetNodeName (ObjDesc->Mutex.Node),
00519             (UINT32) OwnerThread->ThreadId));
00520         return_ACPI_STATUS (AE_AML_NOT_OWNER);
00521     }
00522 
00523     /*
00524      * The sync level of the mutex must be equal to the current sync level. In
00525      * other words, the current level means that at least one mutex at that
00526      * level is currently being held. Attempting to release a mutex of a
00527      * different level can only mean that the mutex ordering rule is being
00528      * violated. This behavior is clarified in ACPI 4.0 specification.
00529      */
00530     if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
00531     {
00532         ACPI_ERROR ((AE_INFO,
00533             "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %u current %u",
00534             AcpiUtGetNodeName (ObjDesc->Mutex.Node),
00535             ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));
00536         return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
00537     }
00538 
00539     /*
00540      * Get the previous SyncLevel from the head of the acquired mutex list.
00541      * This handles the case where several mutexes at the same level have been
00542      * acquired, but are not released in reverse order.
00543      */
00544     PreviousSyncLevel =
00545         OwnerThread->AcquiredMutexList->Mutex.OriginalSyncLevel;
00546 
00547     Status = AcpiExReleaseMutexObject (ObjDesc);
00548     if (ACPI_FAILURE (Status))
00549     {
00550         return_ACPI_STATUS (Status);
00551     }
00552 
00553     if (ObjDesc->Mutex.AcquisitionDepth == 0)
00554     {
00555         /* Restore the previous SyncLevel */
00556 
00557         OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
00558     }
00559 
00560     return_ACPI_STATUS (Status);
00561 }
00562 
00563 
00564 /*******************************************************************************
00565  *
00566  * FUNCTION:    AcpiExReleaseAllMutexes
00567  *
00568  * PARAMETERS:  Thread              - Current executing thread object
00569  *
00570  * RETURN:      Status
00571  *
00572  * DESCRIPTION: Release all mutexes held by this thread
00573  *
00574  * NOTE: This function is called as the thread is exiting the interpreter.
00575  * Mutexes are not released when an individual control method is exited, but
00576  * only when the parent thread actually exits the interpreter. This allows one
00577  * method to acquire a mutex, and a different method to release it, as long as
00578  * this is performed underneath a single parent control method.
00579  *
00580  ******************************************************************************/
00581 
00582 void
00583 AcpiExReleaseAllMutexes (
00584     ACPI_THREAD_STATE       *Thread)
00585 {
00586     ACPI_OPERAND_OBJECT     *Next = Thread->AcquiredMutexList;
00587     ACPI_OPERAND_OBJECT     *ObjDesc;
00588 
00589 
00590     ACPI_FUNCTION_ENTRY ();
00591 
00592 
00593     /* Traverse the list of owned mutexes, releasing each one */
00594 
00595     while (Next)
00596     {
00597         ObjDesc = Next;
00598         Next = ObjDesc->Mutex.Next;
00599 
00600         ObjDesc->Mutex.Prev = NULL;
00601         ObjDesc->Mutex.Next = NULL;
00602         ObjDesc->Mutex.AcquisitionDepth = 0;
00603 
00604         /* Release the mutex, special case for Global Lock */
00605 
00606         if (ObjDesc == AcpiGbl_GlobalLockMutex)
00607         {
00608             /* Ignore errors */
00609 
00610             (void) AcpiEvReleaseGlobalLock ();
00611         }
00612         else
00613         {
00614             AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
00615         }
00616 
00617         /* Mark mutex unowned */
00618 
00619         ObjDesc->Mutex.OwnerThread = NULL;
00620         ObjDesc->Mutex.ThreadId = 0;
00621 
00622         /* Update Thread SyncLevel (Last mutex is the important one) */
00623 
00624         Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
00625     }
00626 }

Generated on Fri May 25 2012 04:25:31 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.