]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Nt32Pkg/TimerDxe/Timer.c
Nt32Pkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / Nt32Pkg / TimerDxe / Timer.c
index 3997c5f913f5291e8d23bdebbe080bb18623cb5b..f3e1e32d08a9aa708688d5ce2210c3cfc98fdd8a 100644 (file)
@@ -1,13 +1,7 @@
-/*++\r
+/**@file\r
 \r
-Copyright (c) 2006, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 Module Name:\r
 \r
@@ -21,7 +15,7 @@ Abstract:
   timer service.  In the future, the Thread creation should possibly be \r
   abstracted by the CPU architectural protocol\r
 \r
---*/\r
+**/\r
 \r
 #include "Timer.h"\r
 \r
@@ -115,9 +109,12 @@ Returns:
   if (!mCancelTimerThread) {\r
   \r
     //\r
-    //  Suspend the main thread until we are done\r
+    // Suspend the main thread until we are done.\r
+    // Enter the critical section before suspending\r
+    // and leave the critical section after resuming\r
+    // to avoid deadlock between main and timer thread.\r
     //\r
-\r
+    gWinNt->EnterCriticalSection (&mNtCriticalSection);\r
     gWinNt->SuspendThread (mNtMainThreadHandle);\r
 \r
     //\r
@@ -127,6 +124,7 @@ Returns:
     //\r
     if (mCancelTimerThread) {\r
       gWinNt->ResumeThread (mNtMainThreadHandle);\r
+      gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
       gWinNt->timeKillEvent (wTimerID);\r
       mMMTimerThreadID = 0;\r
       return ;\r
@@ -138,19 +136,21 @@ Returns:
       //  Resume the main thread\r
       //\r
       gWinNt->ResumeThread (mNtMainThreadHandle);\r
+      gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
 \r
       //\r
       //  Wait for interrupts to be enabled.\r
       //\r
       mCpu->GetInterruptState (mCpu, &InterruptState);\r
       while (!InterruptState) {\r
-        gWinNt->Sleep (0);\r
+        gWinNt->Sleep (1);\r
         mCpu->GetInterruptState (mCpu, &InterruptState);\r
       }\r
        \r
       //\r
       //  Suspend the main thread until we are done\r
       //\r
+      gWinNt->EnterCriticalSection (&mNtCriticalSection);\r
       gWinNt->SuspendThread (mNtMainThreadHandle);\r
       mCpu->GetInterruptState (mCpu, &InterruptState);\r
     }\r
@@ -174,9 +174,7 @@ Returns:
       //  expired since the last call is 10,000 times the number\r
       //  of ms.  (or 100ns units)\r
       //\r
-      gWinNt->EnterCriticalSection (&mNtCriticalSection);\r
       CallbackFunction = mTimerNotifyFunction;\r
-      gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
 \r
       //\r
       // Only invoke the callback function if a Non-NULL handler has been\r
@@ -194,6 +192,7 @@ Returns:
     //  Resume the main thread\r
     //\r
     gWinNt->ResumeThread (mNtMainThreadHandle);\r
+    gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
   } else {\r
     gWinNt->timeKillEvent (wTimerID);\r
     mMMTimerThreadID = 0;\r
@@ -492,7 +491,7 @@ Returns:
 \r
   EFI_SUCCESS       - The soft timer interrupt was generated.\r
 \r
-  EFI_UNSUPPORTEDT  - The platform does not support the generation of soft timer interrupts.\r
+  EFI_UNSUPPORTED   - The platform does not support the generation of soft timer interrupts.\r
 \r
 --*/\r
 {\r
@@ -531,7 +530,9 @@ Returns:
   EFI_STATUS  Status;\r
   UINTN       Result;\r
   EFI_HANDLE  Handle;\r
-\r
+  EFI_HANDLE  hSourceProcessHandle;\r
+  EFI_HANDLE  hSourceHandle;\r
+  EFI_HANDLE  hTargetProcessHandle;\r
   //\r
   // Make sure the Timer Architectural Protocol is not already installed in the system\r
   //\r
@@ -540,16 +541,19 @@ Returns:
   //\r
   // Get the CPU Architectural Protocol instance\r
   //\r
-  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, &mCpu);\r
+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID**)&mCpu);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   //  Get our handle so the timer tick thread can suspend\r
   //\r
+  hSourceProcessHandle = gWinNt->GetCurrentProcess ();\r
+  hSourceHandle        = gWinNt->GetCurrentThread ();\r
+  hTargetProcessHandle = gWinNt->GetCurrentProcess ();\r
   Result = gWinNt->DuplicateHandle (\r
-                    gWinNt->GetCurrentProcess (),\r
-                    gWinNt->GetCurrentThread (),\r
-                    gWinNt->GetCurrentProcess (),\r
+                    hSourceProcessHandle,\r
+                    hSourceHandle,\r
+                    hTargetProcessHandle,\r
                     &mNtMainThreadHandle,\r
                     0,\r
                     FALSE,\r