feat(libkernel): implement pthread_sigmask
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
57f96fd2b3
commit
df415ff1fd
|
|
@ -162,6 +162,11 @@ int APS5_VABI sigprocmask_nid_postfix(int how, const void* set, void* previousSe
|
|||
return _sigprocmask_nid_postfix(how, static_cast<const GuestSignalSet*>(set),
|
||||
static_cast<GuestSignalSet*>(previousSet));
|
||||
}
|
||||
|
||||
int APS5_VABI pthread_sigmask_nid_postfix(int how, const GuestSignalSet* set, GuestSignalSet* previousSet) {
|
||||
if (set != nullptr && (how < 1 || how > 3)) return 22;
|
||||
return _sigprocmask_nid_postfix(how, set, previousSet);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ Handler APS5_VABI signal_nid_postfix(int, Handler);
|
|||
int APS5_VABI raise_nid_postfix(int);
|
||||
int APS5_VABI sigaction_nid_postfix(int, const void*, void*);
|
||||
int APS5_VABI sigprocmask_nid_postfix(int, const void*, void*);
|
||||
int APS5_VABI pthread_sigmask_nid_postfix(int, const void*, void*);
|
||||
int* APS5_VABI __error_nid_postfix();
|
||||
int APS5_VABI _is_signal_return_nid_postfix(std::uint64_t);
|
||||
}
|
||||
|
|
@ -59,6 +60,16 @@ int main() {
|
|||
Require(sigprocmask_nid_postfix(2, &blocked, nullptr) == 0);
|
||||
Require(sigprocmask_nid_postfix(1, nullptr, &previous) == 0);
|
||||
Require(previous.bits[0] == 0);
|
||||
*__error_nid_postfix() = 0;
|
||||
Require(pthread_sigmask_nid_postfix(1, &blocked, nullptr) == 0);
|
||||
Require(pthread_sigmask_nid_postfix(0, &blocked, &previous) == 22);
|
||||
Require(pthread_sigmask_nid_postfix(4, &blocked, &previous) == 22);
|
||||
Require(*__error_nid_postfix() == 0);
|
||||
Require(pthread_sigmask_nid_postfix(0, nullptr, &previous) == 0);
|
||||
Require(previous.bits[0] == 0x20);
|
||||
Require(sigprocmask_nid_postfix(1, nullptr, &previous) == 0 && previous.bits[0] == 0x20);
|
||||
Require(pthread_sigmask_nid_postfix(2, &blocked, &previous) == 0 && previous.bits[0] == 0x20);
|
||||
Require(pthread_sigmask_nid_postfix(1, nullptr, &previous) == 0 && previous.bits[0] == 0);
|
||||
|
||||
const auto callback = reinterpret_cast<std::uintptr_t>(Callback);
|
||||
const auto infoCallback = reinterpret_cast<std::uintptr_t>(InfoCallback);
|
||||
|
|
|
|||
|
|
@ -319,6 +319,7 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- [sceKernelRaiseException](../../core/libs/prx/libkernel/System/src/Exception.cpp) delivers on Windows only and throws on Linux
|
||||
- [sceKernelRaiseException](../../core/libs/prx/libkernel/System/src/Exception.cpp) builds the handler's `ucontext` with FreeBSD's amd64 layout (16-byte sigmask, `mcontext` at 0x40, `mc_rsp` at 0xf8); the console's layout is not verified beyond the fields PS5Util reads
|
||||
- [sceKernelRaiseException](../../core/libs/prx/libkernel/System/src/Exception.cpp) does not consult the target thread's signal mask
|
||||
- [pthread_sigmask](../../core/libs/prx/libkernel/System/src/Signals.cpp) (libkernel) shares the process-wide mask of `sigprocmask` and `_sigprocmask`, which keeps only the first 32 signals; FreeBSD keeps a mask per thread
|
||||
- [sceKernelRaiseException](../../core/libs/prx/libkernel/System/src/Exception.cpp) reaches a thread that waits in an alertable `TimedWait` wait through an APC. A thread blocked anywhere else, including all waits under `APS5_COARSE_TIMED_WAITS` and host waits inside the emulator, is redirected and runs the handler only when that wait returns
|
||||
- [sceKernelRaiseException](../../core/libs/prx/libkernel/System/src/Exception.cpp) on Windows runs the handler wherever the target thread was interrupted. It waits only while the thread is inside winpthreads or restoring a context through `NtContinue`, and throws if that lasts 1 s, so a handler that calls into other host code the thread was interrupted in, such as the C runtime's heap or a lock of the emulator, can deadlock on it or reenter it
|
||||
- [sigaltstack](../../core/libs/prx/libkernel/System/src/Signals.cpp) (libkernel) records each thread's alternate signal stack and reports it back, following FreeBSD's `kern_sigaltstack` (`EINVAL` for flags other than `SS_DISABLE`, `ENOMEM` below `MINSIGSTKSZ` 2048), but handlers never run on it, so `SS_ONSTACK` and `EPERM` are never reported
|
||||
|
|
|
|||
Loading…
Reference in New Issue