diff options
author | davidxu <davidxu@FreeBSD.org> | 2005-10-14 12:43:47 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2005-10-14 12:43:47 +0000 |
commit | 3fbdb3c21524d9d95278ada1d61b4d1e6bee654b (patch) | |
tree | 95d82b1a11b0c187223f8ac12f020b19901fa750 /sys/alpha | |
parent | 6b2407fb7677ef2b8cef5c0925b3fe88a6ec7ca4 (diff) | |
download | FreeBSD-src-3fbdb3c21524d9d95278ada1d61b4d1e6bee654b.zip FreeBSD-src-3fbdb3c21524d9d95278ada1d61b4d1e6bee654b.tar.gz |
1. Change prototype of trapsignal and sendsig to use ksiginfo_t *, most
changes in MD code are trivial, before this change, trapsignal and
sendsig use discrete parameters, now they uses member fields of
ksiginfo_t structure. For sendsig, this change allows us to pass
POSIX realtime signal value to user code.
2. Remove cpu_thread_siginfo, it is no longer needed because we now always
generate ksiginfo_t data and feed it to libpthread.
3. Add p_sigqueue to proc structure to hold shared signals which were
blocked by all threads in the proc.
4. Add td_sigqueue to thread structure to hold all signals delivered to
thread.
5. i386 and amd64 now return POSIX standard si_code, other arches will
be fixed.
6. In this sigqueue implementation, pending signal set is kept as before,
an extra siginfo list holds additional siginfo_t data for signals.
kernel code uses psignal() still behavior as before, it won't be failed
even under memory pressure, only exception is when deleting a signal,
we should call sigqueue_delete to remove signal from sigqueue but
not SIGDELSET. Current there is no kernel code will deliver a signal
with additional data, so kernel should be as stable as before,
a ksiginfo can carry more information, for example, allow signal to
be delivered but throw away siginfo data if memory is not enough.
SIGKILL and SIGSTOP have fast path in sigqueue_add, because they can
not be caught or masked.
The sigqueue() syscall allows user code to queue a signal to target
process, if resource is unavailable, EAGAIN will be returned as
specification said.
Just before thread exits, signal queue memory will be freed by
sigqueue_flush.
Current, all signals are allowed to be queued, not only realtime signals.
Earlier patch reviewed by: jhb, deischen
Tested on: i386, amd64
Diffstat (limited to 'sys/alpha')
-rw-r--r-- | sys/alpha/alpha/machdep.c | 56 | ||||
-rw-r--r-- | sys/alpha/alpha/trap.c | 8 | ||||
-rw-r--r-- | sys/alpha/linux/linux_sysvec.c | 2 | ||||
-rw-r--r-- | sys/alpha/osf1/osf1_signal.c | 8 | ||||
-rw-r--r-- | sys/alpha/osf1/osf1_signal.h | 2 |
5 files changed, 37 insertions, 39 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index e09b5f6..b12e039 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -211,11 +211,10 @@ vm_offset_t phys_avail[10]; #define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2) #ifdef COMPAT_43 -void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code); +void osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); #endif #ifdef COMPAT_FREEBSD4 -static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, - u_long code); +static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); #endif static void get_fpcontext(struct thread *td, mcontext_t *mcp); @@ -1107,7 +1106,7 @@ DELAY(int n) */ #ifdef COMPAT_43 void -osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) +osendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask) { struct proc *p; struct thread *td; @@ -1115,10 +1114,14 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) struct trapframe *frame; struct sigacts *psp; int oonstack, fsize, rndfsize; + int sig; + int code; td = curthread; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); + sig = kp->ksi_signo; + code = kp->ksi_code; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -1177,7 +1180,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) /* Fill in POSIX parts */ ksi.si_signo = sig; ksi.si_code = code; - ksi.si_value.sigval_ptr = NULL; /* XXX */ + ksi.si_value = kp->ksi_value; /* * copy the frame out to userland. @@ -1212,7 +1215,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) #ifdef COMPAT_FREEBSD4 static void -freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) +freebsd4_sendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask) { struct proc *p; struct thread *td; @@ -1220,10 +1223,14 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) struct sigacts *psp; struct sigframe4 sf, *sfp; int oonstack, rndfsize; + int sig; + int code; td = curthread; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); + sig = kp->ksi_signo; + code = kp->ksi_code; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -1308,9 +1315,7 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si); /* Fill in POSIX parts */ - sf.sf_si.si_signo = sig; - sf.sf_si.si_code = code; - sf.sf_si.si_addr = (void*)frame->tf_regs[FRAME_TRAPARG_A0]; + sf.sf_si = kp->ksi_info; } else frame->tf_regs[FRAME_A1] = code; @@ -1323,7 +1328,7 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) #endif /* COMPAT_FREEBSD4 */ void -sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) +sendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask) { struct proc *p; struct thread *td; @@ -1331,21 +1336,25 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) struct sigacts *psp; struct sigframe sf, *sfp; int oonstack, rndfsize; + int sig; + int code; td = curthread; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); + sig = kp->ksi_signo; + code = kp->ksi_code; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); #ifdef COMPAT_FREEBSD4 if (SIGISMEMBER(psp->ps_freebsd4, sig)) { - freebsd4_sendsig(catcher, sig, mask, code); + freebsd4_sendsig(catcher, kp, mask); return; } #endif #ifdef COMPAT_43 if (SIGISMEMBER(psp->ps_osigset, sig)) { - osendsig(catcher, sig, mask, code); + osendsig(catcher, kp, mask); return; } #endif @@ -1432,9 +1441,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si); /* Fill in POSIX parts */ - sf.sf_si.si_signo = sig; - sf.sf_si.si_code = code; - sf.sf_si.si_addr = (void*)frame->tf_regs[FRAME_TRAPARG_A0]; + sf.sf_si = kp->ksi_info; } else frame->tf_regs[FRAME_A1] = code; @@ -1446,25 +1453,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) } /* - * Build siginfo_t for SA thread - */ -void -cpu_thread_siginfo(int sig, u_long code, siginfo_t *si) -{ - struct proc *p; - struct thread *td; - - td = curthread; - p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); - - bzero(si, sizeof(*si)); - si->si_signo = sig; - si->si_code = code; - /* XXXKSE fill other fields */ -} - -/* * System call to cleanup state after a signal * has been taken. Reset signal mask and * stack state from context left by sendsig (above). diff --git a/sys/alpha/alpha/trap.c b/sys/alpha/alpha/trap.c index dc800ef..7a62956f 100644 --- a/sys/alpha/alpha/trap.c +++ b/sys/alpha/alpha/trap.c @@ -264,6 +264,7 @@ trap(a0, a1, a2, entry, framep) #ifdef SMP register_t s; #endif + ksiginfo_t ksi; /* * Find our per-cpu globals. @@ -585,7 +586,12 @@ trap(a0, a1, a2, entry, framep) framep->tf_regs[FRAME_TRAPARG_A0] = a0; framep->tf_regs[FRAME_TRAPARG_A1] = a1; framep->tf_regs[FRAME_TRAPARG_A2] = a2; - trapsignal(td, i, ucode); + ksiginfo_init_trap(&ksi); + ksi.ksi_signo = i; + ksi.ksi_code = ucode; /* XXX, Should be POSIX si_code */ + ksi.ksi_addr = (void *)a0; + trapsignal(td, &ksi); + out: if (user) { framep->tf_regs[FRAME_SP] = alpha_pal_rdusp(); diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c index 784ec81..b6ce778 100644 --- a/sys/alpha/linux/linux_sysvec.c +++ b/sys/alpha/linux/linux_sysvec.c @@ -77,7 +77,7 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); -void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code); +void osendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask); static int elf_linux_fixup(register_t **stack_base, struct image_params *iparams); diff --git a/sys/alpha/osf1/osf1_signal.c b/sys/alpha/osf1/osf1_signal.c index 355cb1c..56e2298 100644 --- a/sys/alpha/osf1/osf1_signal.c +++ b/sys/alpha/osf1/osf1_signal.c @@ -459,7 +459,7 @@ osf1_kill(td, uap) */ void -osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) +osf1_sendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask) { int fsize, oonstack, rndfsize; struct thread *td; @@ -467,10 +467,14 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) osiginfo_t *sip, ksi; struct trapframe *frame; struct sigacts *psp; + int sig; + int code; td = curthread; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); + sig = kp->ksi_signo; + code = kp->ksi_code; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -526,7 +530,7 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) /* Fill in POSIX parts */ ksi.si_signo = sig; ksi.si_code = code; - ksi.si_value.sigval_ptr = NULL; /* XXX */ + ksi.si_value = kp->ksi_value; /* * copy the frame out to userland. diff --git a/sys/alpha/osf1/osf1_signal.h b/sys/alpha/osf1/osf1_signal.h index ec1fbeb..1ef5ac4 100644 --- a/sys/alpha/osf1/osf1_signal.h +++ b/sys/alpha/osf1/osf1_signal.h @@ -61,7 +61,7 @@ void bsd_to_osf1_sigaltstack(const struct sigaltstack *, struct osf1_sigaltstack void bsd_to_osf1_sigset(const sigset_t *, osf1_sigset_t *); void osf1_to_bsd_sigaltstack(const struct osf1_sigaltstack *, struct sigaltstack *); void osf1_to_bsd_sigset(const osf1_sigset_t *, sigset_t *); -void osf1_sendsig(sig_t, int , sigset_t *, u_long ); +void osf1_sendsig(sig_t, struct ksiginfo *, sigset_t *); #endif /* !_OSF1_SIGNAL_H */ |