-/*++\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
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
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
//\r
if (mCancelTimerThread) {\r
gWinNt->ResumeThread (mNtMainThreadHandle);\r
+ gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
gWinNt->timeKillEvent (wTimerID);\r
mMMTimerThreadID = 0;\r
return ;\r
// 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
// 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
// Resume the main thread\r
//\r
gWinNt->ResumeThread (mNtMainThreadHandle);\r
+ gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
} else {\r
gWinNt->timeKillEvent (wTimerID);\r
mMMTimerThreadID = 0;\r
\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
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
//\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