Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern handle siginfo for deferred signals. Allocate a ksi...
details: https://anonhg.NetBSD.org/src/rev/96849fe9ff08
branches: trunk
changeset: 551928:96849fe9ff08
user: christos <christos%NetBSD.org@localhost>
date: Sun Sep 14 06:59:13 2003 +0000
description:
handle siginfo for deferred signals. Allocate a ksiginfo pool, and store
the information there.
TODO:
1. since timer stuff gets called from an interrupt context, we could
preallocate ksiginfo_t's from the pool, so we don't need a kmem
pool.
2. probably the sa signal delivery syscall can be changed to take
a ksiginfo_t so we can use only one pool.
3. maybe when we add realtime signal support, add a resource limit
on the number of ksiginfo_t's a process can allocate.
diffstat:
sys/kern/core_elf32.c | 8 +-
sys/kern/core_netbsd.c | 8 +-
sys/kern/kern_sig.c | 168 +++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 151 insertions(+), 33 deletions(-)
diffs (truncated from 382 to 300 lines):
diff -r fdd3e85666bc -r 96849fe9ff08 sys/kern/core_elf32.c
--- a/sys/kern/core_elf32.c Sun Sep 14 06:56:22 2003 +0000
+++ b/sys/kern/core_elf32.c Sun Sep 14 06:59:13 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: core_elf32.c,v 1.11 2003/09/06 22:03:09 christos Exp $ */
+/* $NetBSD: core_elf32.c,v 1.12 2003/09/14 06:59:13 christos Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: core_elf32.c,v 1.11 2003/09/06 22:03:09 christos Exp $");
+__KERNEL_RCSID(1, "$NetBSD: core_elf32.c,v 1.12 2003/09/14 06:59:13 christos Exp $");
/* If not included by core_elf64.c, ELFSIZE won't be defined. */
#ifndef ELFSIZE
@@ -303,8 +303,8 @@
if (offset) {
cpi.cpi_version = NETBSD_ELFCORE_PROCINFO_VERSION;
cpi.cpi_cpisize = sizeof(cpi);
- cpi.cpi_signo = p->p_sigctx.ps_siginfo.ksi_signo;
- cpi.cpi_sigcode = p->p_sigctx.ps_siginfo.ksi_trap;
+ cpi.cpi_signo = p->p_sigctx.ps_signo;
+ cpi.cpi_sigcode = p->p_sigctx.ps_code;
cpi.cpi_siglwp = p->p_sigctx.ps_lwp;
memcpy(&cpi.cpi_sigpend, &p->p_sigctx.ps_siglist,
diff -r fdd3e85666bc -r 96849fe9ff08 sys/kern/core_netbsd.c
--- a/sys/kern/core_netbsd.c Sun Sep 14 06:56:22 2003 +0000
+++ b/sys/kern/core_netbsd.c Sun Sep 14 06:59:13 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: core_netbsd.c,v 1.6 2003/09/06 22:03:09 christos Exp $ */
+/* $NetBSD: core_netbsd.c,v 1.7 2003/09/14 06:59:14 christos Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: core_netbsd.c,v 1.6 2003/09/06 22:03:09 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: core_netbsd.c,v 1.7 2003/09/14 06:59:14 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -82,8 +82,8 @@
cs.core.c_midmag = 0;
strncpy(cs.core.c_name, p->p_comm, MAXCOMLEN);
cs.core.c_nseg = 0;
- cs.core.c_signo = p->p_sigctx.ps_siginfo.ksi_signo;
- cs.core.c_ucode = p->p_sigctx.ps_siginfo.ksi_trap;
+ cs.core.c_signo = p->p_sigctx.ps_signo;
+ cs.core.c_ucode = p->p_sigctx.ps_code;
cs.core.c_cpusize = 0;
cs.core.c_tsize = (u_long)ctob(vm->vm_tsize);
cs.core.c_dsize = (u_long)ctob(vm->vm_dsize);
diff -r fdd3e85666bc -r 96849fe9ff08 sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c Sun Sep 14 06:56:22 2003 +0000
+++ b/sys/kern/kern_sig.c Sun Sep 14 06:59:13 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_sig.c,v 1.151 2003/09/13 15:32:41 christos Exp $ */
+/* $NetBSD: kern_sig.c,v 1.152 2003/09/14 06:59:14 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.151 2003/09/13 15:32:41 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.152 2003/09/14 06:59:14 christos Exp $");
#include "opt_ktrace.h"
#include "opt_compat_sunos.h"
@@ -82,10 +82,17 @@
static void child_psignal(struct proc *, int);
static void proc_stop(struct proc *);
static int build_corename(struct proc *, char [MAXPATHLEN]);
+static void ksiginfo_exithook(struct proc *, void *);
+static void ksiginfo_save(struct proc *, ksiginfo_t *);
+static void ksiginfo_del(struct proc *p, ksiginfo_t *);
+static void ksiginfo_put(struct proc *, ksiginfo_t *);
+static ksiginfo_t *ksiginfo_get(struct proc *, int);
+
sigset_t contsigmask, stopsigmask, sigcantmask;
struct pool sigacts_pool; /* memory pool for sigacts structures */
struct pool siginfo_pool; /* memory pool for siginfo structures */
+struct pool ksiginfo_pool; /* memory pool for ksiginfo structures */
/*
* Can process p, with pcred pc, send the signal signum to process q?
@@ -99,16 +106,101 @@
((signum) == SIGCONT && (q)->p_session == (p)->p_session))
/*
+ * return the first ksiginfo struct from our hash table
+ */
+static ksiginfo_t *
+ksiginfo_get(struct proc *p, int signo)
+{
+ ksiginfo_t *ksi, *hp = p->p_sigctx.ps_siginfo;
+
+ if ((ksi = hp) == NULL)
+ return NULL;
+
+ for (;;) {
+ if (ksi->ksi_signo == signo)
+ return ksi;
+ if ((ksi = ksi->ksi_next) == hp)
+ return NULL;
+ }
+}
+
+static void
+ksiginfo_put(struct proc *p, ksiginfo_t *ksi)
+{
+ ksiginfo_t *hp = p->p_sigctx.ps_siginfo;
+
+ if (hp == NULL)
+ p->p_sigctx.ps_siginfo = ksi->ksi_next = ksi->ksi_prev = ksi;
+ else {
+ ksi->ksi_prev = hp->ksi_prev;
+ hp->ksi_prev->ksi_next = ksi;
+ hp->ksi_prev = ksi;
+ ksi->ksi_next = hp;
+ }
+}
+
+static void
+ksiginfo_del(struct proc *p, ksiginfo_t *ksi)
+{
+ if (ksi->ksi_next == ksi)
+ p->p_sigctx.ps_siginfo = NULL;
+ else {
+ ksi->ksi_prev->ksi_next = ksi->ksi_next;
+ ksi->ksi_next->ksi_prev = ksi->ksi_prev;
+ }
+}
+
+static void
+ksiginfo_save(struct proc *p, ksiginfo_t *ksi)
+{
+ ksiginfo_t *kpool = NULL;
+ if ((SIGACTION_PS(p->p_sigacts, ksi->ksi_signo).sa_flags & SA_SIGINFO)
+ == 0)
+ return;
+ if (
+#ifdef notyet /* XXX: QUEUING */
+ ksi->ksi_signo >= SIGRTMIN ||
+#endif
+ (kpool = ksiginfo_get(p, ksi->ksi_signo)) == NULL) {
+ if ((kpool = pool_get(&ksiginfo_pool, PR_NOWAIT)) == NULL)
+ return;
+ *kpool = *ksi;
+ ksiginfo_put(p, kpool);
+ } else
+ *kpool = *ksi;
+}
+
+/*
+ * free all pending ksiginfo on exit
+ */
+static void
+ksiginfo_exithook(struct proc *p, void *v)
+{
+ ksiginfo_t *ksi, *hp = p->p_sigctx.ps_siginfo;
+
+ if (hp == NULL)
+ return;
+ for (;;) {
+ pool_put(&ksiginfo_pool, ksi);
+ if ((ksi = ksi->ksi_next) == hp)
+ break;
+ }
+}
+
+/*
* Initialize signal-related data structures.
*/
void
signal_init(void)
{
-
pool_init(&sigacts_pool, sizeof(struct sigacts), 0, 0, 0, "sigapl",
&pool_allocator_nointr);
pool_init(&siginfo_pool, sizeof(siginfo_t), 0, 0, 0, "siginfo",
&pool_allocator_nointr);
+ pool_init(&ksiginfo_pool, sizeof(ksiginfo_t), 0, 0, 0, "ksiginfo",
+ NULL);
+ exithook_establish(ksiginfo_exithook, NULL);
+ exechook_establish(ksiginfo_exithook, NULL);
}
/*
@@ -812,9 +904,10 @@
}
(void) spl0(); /* XXXSMP */
} else {
+ p->p_sigctx.ps_lwp = l->l_lid;
/* XXX for core dump/debugger */
- p->p_sigctx.ps_siginfo = *ksi;
- p->p_sigctx.ps_lwp = l->l_lid;
+ p->p_sigctx.ps_signo = ksi->ksi_signo;
+ p->p_sigctx.ps_code = ksi->ksi_trap;
kpsignal(p, ksi, NULL);
}
}
@@ -961,11 +1054,12 @@
if ((prop & SA_CANTMASK) == 0
&& p->p_sigctx.ps_sigwaited < 0
&& sigismember(&p->p_sigctx.ps_sigwait, signum)
- && p->p_stat != SSTOP) {
+ && p->p_stat != SSTOP) {
+ if (action == SIG_CATCH)
+ ksiginfo_save(p, ksi);
sigdelset(&p->p_sigctx.ps_siglist, signum);
p->p_sigctx.ps_sigwaited = signum;
sigemptyset(&p->p_sigctx.ps_sigwait);
-
if (dolock)
wakeup_one(&p->p_sigctx.ps_sigwait);
else
@@ -977,8 +1071,11 @@
* Defer further processing for signals which are held,
* except that stopped processes must be continued by SIGCONT.
*/
- if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP))
+ if (action == SIG_HOLD &&
+ ((prop & SA_CONT) == 0 || p->p_stat != SSTOP)) {
+ ksiginfo_save(p, ksi);
return;
+ }
/* XXXSMP: works, but icky */
if (dolock)
SCHED_LOCK(s);
@@ -1040,7 +1137,7 @@
*/
if ((prop & SA_CONT) && action == SIG_DFL) {
sigdelset(&p->p_sigctx.ps_siglist, signum);
- goto out;
+ goto done;
}
/*
@@ -1052,8 +1149,9 @@
* If a child holding parent blocked,
* stopping could cause deadlock.
*/
- if (p->p_flag & P_PPWAIT)
+ if (p->p_flag & P_PPWAIT) {
goto out;
+ }
sigdelset(&p->p_sigctx.ps_siglist, signum);
p->p_xstat = signum;
if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0) {
@@ -1064,7 +1162,7 @@
child_psignal(p, 0);
}
proc_stop(p); /* XXXSMP: recurse? */
- goto out;
+ goto done;
}
if (l == NULL) {
@@ -1077,7 +1175,7 @@
*/
if (allsusp && (signum == SIGKILL))
lwp_continue(suspended);
- goto out;
+ goto done;
}
/*
* All other (caught or default) signals
@@ -1092,7 +1190,7 @@
* then no further action is necessary.
*/
if (p->p_flag & P_TRACED)
- goto out;
+ goto done;
/*
* Kill signal always sets processes running,
@@ -1102,7 +1200,7 @@
l = proc_unstop(p);
if (l)
goto runfast;
- goto out;
+ goto done;
}
if (prop & SA_CONT) {
@@ -1135,7 +1233,7 @@
* (If we did the shell could get confused.)
*/
sigdelset(&p->p_sigctx.ps_siglist, signum);
- goto out;
+ goto done;
Home |
Main Index |
Thread Index |
Old Index