Kernel/LibC: Implement sigwait
This commit is contained in:
parent
247743ef9c
commit
def236b7cd
|
@ -194,6 +194,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_sigpending(sigset_t* set);
|
BAN::ErrorOr<long> sys_sigpending(sigset_t* set);
|
||||||
BAN::ErrorOr<long> sys_sigprocmask(int how, const sigset_t* set, sigset_t* oset);
|
BAN::ErrorOr<long> sys_sigprocmask(int how, const sigset_t* set, sigset_t* oset);
|
||||||
BAN::ErrorOr<long> sys_sigsuspend(const sigset_t* set);
|
BAN::ErrorOr<long> sys_sigsuspend(const sigset_t* set);
|
||||||
|
BAN::ErrorOr<long> sys_sigwait(const sigset_t* set, int* sig);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime);
|
BAN::ErrorOr<long> sys_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime);
|
||||||
BAN::ErrorOr<long> sys_yield();
|
BAN::ErrorOr<long> sys_yield();
|
||||||
|
|
|
@ -2665,6 +2665,42 @@ namespace Kernel
|
||||||
return BAN::Error::from_errno(EINTR);
|
return BAN::Error::from_errno(EINTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> Process::sys_sigwait(const sigset_t* set, int* sig)
|
||||||
|
{
|
||||||
|
LockGuard _(m_process_lock);
|
||||||
|
|
||||||
|
auto& thread = Thread::current();
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
TRY(validate_pointer_access(set, sizeof(sigset_t), false));
|
||||||
|
TRY(validate_pointer_access(sig, sizeof(int), true));
|
||||||
|
|
||||||
|
{
|
||||||
|
SpinLockGuard _1(thread.m_signal_lock);
|
||||||
|
SpinLockGuard _2(m_signal_lock);
|
||||||
|
|
||||||
|
const uint64_t pending = thread.m_signal_pending_mask | this->m_signal_pending_mask;
|
||||||
|
if (const auto wait_mask = pending & *set)
|
||||||
|
{
|
||||||
|
for (size_t i = _SIGMIN; i <= _SIGMAX; i++)
|
||||||
|
{
|
||||||
|
const auto mask = 1ull << i;
|
||||||
|
if (!(wait_mask & mask))
|
||||||
|
continue;
|
||||||
|
thread.m_signal_pending_mask &= ~mask;
|
||||||
|
this->m_signal_pending_mask &= ~mask;
|
||||||
|
*sig = i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Processor::scheduler().block_current_thread(nullptr, -1, &m_process_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime)
|
BAN::ErrorOr<long> Process::sys_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime)
|
||||||
{
|
{
|
||||||
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
|
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
|
||||||
|
|
|
@ -91,6 +91,7 @@ __BEGIN_DECLS
|
||||||
O(SYS_SIGPENDING, sigpending) \
|
O(SYS_SIGPENDING, sigpending) \
|
||||||
O(SYS_SIGPROCMASK, sigprocmask) \
|
O(SYS_SIGPROCMASK, sigprocmask) \
|
||||||
O(SYS_SIGSUSPEND, sigsuspend) \
|
O(SYS_SIGSUSPEND, sigsuspend) \
|
||||||
|
O(SYS_SIGWAIT, sigwait) \
|
||||||
O(SYS_SETITIMER, setitimer) \
|
O(SYS_SETITIMER, setitimer) \
|
||||||
O(SYS_POSIX_OPENPT, posix_openpt) \
|
O(SYS_POSIX_OPENPT, posix_openpt) \
|
||||||
O(SYS_PTSNAME, ptsname) \
|
O(SYS_PTSNAME, ptsname) \
|
||||||
|
|
|
@ -169,3 +169,10 @@ int sigsuspend(const sigset_t* sigmask)
|
||||||
{
|
{
|
||||||
return syscall(SYS_SIGSUSPEND, sigmask);
|
return syscall(SYS_SIGSUSPEND, sigmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sigwait(const sigset_t* __restrict set, int* __restrict sig)
|
||||||
|
{
|
||||||
|
if (syscall(SYS_SIGWAIT, set, sig) == -1)
|
||||||
|
return errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue