EmulatorPkg: Add IsSigTermSignaled mechanism. When Host app receiving SigTerm signal, the background threads may not receive the same. This IsSigTermSignaled can be used for background threads to do the graceful termination. Change-Id: I77374ad2a88b5a015ab8564560cbd95f4bd7ae5d Hsd-es-id: <HSD-ES bug/ise id> Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
diff --git a/EmulatorPkg/Include/Library/EmuSignalLib.h b/EmulatorPkg/Include/Library/EmuSignalLib.h index e4f6f36..25d6666 100644 --- a/EmulatorPkg/Include/Library/EmuSignalLib.h +++ b/EmulatorPkg/Include/Library/EmuSignalLib.h
@@ -47,4 +47,27 @@ IN UINTN SignalNumber ); +/** + Get IsSigTermSignaled value. + + @retval Value current IsSigTermSignaled value. + +**/ +UINT32 +EFIAPI +EmuGetIsSigTermSignaled ( + VOID + ); + +/** + Set IsSigTermSignaled value. + + @param[in] Value desired IsSigTermSignaled value. + +**/ +VOID +EFIAPI +EmuSetIsSigTermSignaled ( + IN UINT32 value + ); #endif
diff --git a/EmulatorPkg/Include/Protocol/EmuSignal.h b/EmulatorPkg/Include/Protocol/EmuSignal.h index 0af1c67..114749e 100644 --- a/EmulatorPkg/Include/Protocol/EmuSignal.h +++ b/EmulatorPkg/Include/Protocol/EmuSignal.h
@@ -87,10 +87,34 @@ IN UINTN SignalNumber ); +/** + Get IsSigTermSignaled value. + + @retval IsSigTermSignaled value + +**/ +typedef +UINT32 +(EFIAPI *EMU_GET_IS_SIGTERM_SIGNALED)( + VOID + ); + +/** + Set IsSigTermSignaled value. + @param[in] value for IsSigTermSignaled + +**/ +typedef +VOID +(EFIAPI *EMU_SET_IS_SIGTERM_SIGNALED)( + IN UINT32 value + ); struct _EMU_SIGNAL_THUNK_PROTOCOL { EMU_SIGNAL_REGISTER_SIGNAL_HANDLER RegisterSignalHandler; EMU_SIGNAL_UNREGISTER_SIGNAL_HANDLER UnregisterSignalHandler; + EMU_GET_IS_SIGTERM_SIGNALED GetIsSigTermSignaled; + EMU_SET_IS_SIGTERM_SIGNALED SetIsSigTermSignaled; }; #endif
diff --git a/EmulatorPkg/Library/DxeEmuSignalLib/DxeEmuSignalLib.c b/EmulatorPkg/Library/DxeEmuSignalLib/DxeEmuSignalLib.c index 54d7d5d..b69e915 100644 --- a/EmulatorPkg/Library/DxeEmuSignalLib/DxeEmuSignalLib.c +++ b/EmulatorPkg/Library/DxeEmuSignalLib/DxeEmuSignalLib.c
@@ -110,3 +110,41 @@ ASSERT (gEmuSignal != NULL); return gEmuSignal->UnregisterSignalHandler (SignalNumber); } + +/** + Get IsSigTermSignaled value. + + @retval Value current IsSigTermSignaled value. + +**/ +UINT32 +EFIAPI +EmuGetIsSigTermSignaled ( + VOID + ) +{ + UINT32 value; + + ASSERT (gEmuSignal != NULL); + value = gEmuSignal->GetIsSigTermSignaled(); + + return value; +} + +/** + Set IsSigTermSignaled value. + + @param[in] Value desired IsSigTermSignaled value. + +**/ +VOID +EFIAPI +EmuSetIsSigTermSignaled ( + IN UINT32 value + ) +{ + ASSERT (gEmuSignal != NULL); + gEmuSignal->SetIsSigTermSignaled(value); + + return; +} \ No newline at end of file
diff --git a/EmulatorPkg/Unix/Host/Arm/Gasket.c b/EmulatorPkg/Unix/Host/Arm/Gasket.c index 83da57a..9fcb8bb 100644 --- a/EmulatorPkg/Unix/Host/Arm/Gasket.c +++ b/EmulatorPkg/Unix/Host/Arm/Gasket.c
@@ -964,3 +964,21 @@ { return SignalClose (This); } + +UINT32 +EFIAPI +GasketGetIsSigTermSignaled ( + VOID + ) +{ + return GetIsSigTermSignaled (); +} + +VOID +EFIAPI +GasketSetIsSigTermSignaled ( + IN UINT32 value + ) +{ + return SetIsSigTermSignaled (value); +}
diff --git a/EmulatorPkg/Unix/Host/Arm/GasketFunctionDefinitions.h b/EmulatorPkg/Unix/Host/Arm/GasketFunctionDefinitions.h index 89e6f6f..07152e0 100644 --- a/EmulatorPkg/Unix/Host/Arm/GasketFunctionDefinitions.h +++ b/EmulatorPkg/Unix/Host/Arm/GasketFunctionDefinitions.h
@@ -1168,4 +1168,28 @@ IN EMU_IO_THUNK_PROTOCOL *This ); +/** + Get IsSigTermSignaled value. + + @retval Value current IsSigTermSignaled value. + +**/ +UINT32 +EFIAPI +GetIsSigTermSignaled ( + VOID + ); + +/** + Set IsSigTermSignaled value. + + @param[in] Value desired IsSigTermSignaled value. + +**/ +VOID +EFIAPI +SetIsSigTermSignaled ( + IN UINT32 value + ); + #endif
diff --git a/EmulatorPkg/Unix/Host/Gasket.h b/EmulatorPkg/Unix/Host/Gasket.h index 930a99d..50f40fc 100644 --- a/EmulatorPkg/Unix/Host/Gasket.h +++ b/EmulatorPkg/Unix/Host/Gasket.h
@@ -700,4 +700,28 @@ IN EMU_IO_THUNK_PROTOCOL *This ); +/** + Get IsSigTermSignaled value. + + @retval value current IsSigTermSignaled value. + +**/ +UINT32 +EFIAPI +GasketGetIsSigTermSignaled ( + VOID + ); + +/** + Set IsSigTermSignaled value. + + @param[in] value desired IsSigTermSignaled value. + +**/ +VOID +EFIAPI +GasketSetIsSigTermSignaled ( + IN UINT32 value + ); + #endif
diff --git a/EmulatorPkg/Unix/Host/Ia32/Gasket.S b/EmulatorPkg/Unix/Host/Ia32/Gasket.S index 2418632..dd850c1 100644 --- a/EmulatorPkg/Unix/Host/Ia32/Gasket.S +++ b/EmulatorPkg/Unix/Host/Ia32/Gasket.S
@@ -1567,4 +1567,28 @@ leave ret +ASM_GLOBAL ASM_PFX(GasketGetIsSigTermSignaled) +ASM_PFX(GasketGetIsSigTermSignaled): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + call ASM_PFX(GetIsSigTermSignaled) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSetIsSigTermSignaled) +ASM_PFX(GasketSetIsSigTermSignaled): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SetIsSigTermSignaled) + + leave + ret
diff --git a/EmulatorPkg/Unix/Host/Signal.c b/EmulatorPkg/Unix/Host/Signal.c index a048b24..7cd7160 100644 --- a/EmulatorPkg/Unix/Host/Signal.c +++ b/EmulatorPkg/Unix/Host/Signal.c
@@ -13,6 +13,9 @@ STATIC EMU_SIGNAL_HANDLER mSigSegvHandler = NULL; STATIC EMU_SIGNAL_HANDLER mSigTermHandler = NULL; +UINT32 mIsSigTermSignaled = 0; +VOID *mMutex = NULL; + /** Converts from emulator thunk signal numbers to UNIX signal numbers. Emulator thunk signal numbers exist so that the only place platform-specific UNIX @@ -261,9 +264,74 @@ return EFI_SUCCESS; } +UINTN +EFIAPI +PthreadMutexLock ( + IN VOID *Mutex + ); + +UINTN +EFIAPI +PthreadMutexUnLock ( + IN VOID *Mutex + ); + +VOID * +PthreadMutexInit ( + IN VOID + ); + +/** + Get IsSigTermSignaled value. + + @retval Value current IsSigTermSignaled value. + +**/ +UINT32 +EFIAPI +GetIsSigTermSignaled ( + VOID + ) +{ + UINT32 value; + + if (mMutex == NULL) { + mMutex = PthreadMutexInit(); + } + PthreadMutexLock(mMutex); + value = mIsSigTermSignaled; + PthreadMutexUnLock(mMutex); + + return value; +} + +/** + Set IsSigTermSignaled value. + + @param[in] Value desired IsSigTermSignaled value. + +**/ +VOID +EFIAPI +SetIsSigTermSignaled ( + IN UINT32 value + ) +{ + if (mMutex == NULL) { + mMutex = PthreadMutexInit(); + } + PthreadMutexLock(mMutex); + mIsSigTermSignaled = value; + PthreadMutexUnLock(mMutex); + + return; +} + EMU_SIGNAL_THUNK_PROTOCOL gEmuSignalThunk = { GasketRegisterSignalHandler, - GasketUnregisterSignalHandler + GasketUnregisterSignalHandler, + GasketGetIsSigTermSignaled, + GasketSetIsSigTermSignaled }; EFI_STATUS
diff --git a/EmulatorPkg/Unix/Host/X64/Gasket.S b/EmulatorPkg/Unix/Host/X64/Gasket.S index ae1126c..e0d23e3 100644 --- a/EmulatorPkg/Unix/Host/X64/Gasket.S +++ b/EmulatorPkg/Unix/Host/X64/Gasket.S
@@ -1712,4 +1712,35 @@ popq %rbp ret +ASM_GLOBAL ASM_PFX(GasketGetIsSigTermSignaled) +ASM_PFX(GasketGetIsSigTermSignaled): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + + call ASM_PFX(GetIsSigTermSignaled) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSetIsSigTermSignaled) +ASM_PFX(GasketSetIsSigTermSignaled): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SetIsSigTermSignaled) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret