summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1999-01-07 21:23:50 +0000
committerjulian <julian@FreeBSD.org>1999-01-07 21:23:50 +0000
commita7b385889ec602ef4648e627bcb67bf0fd8d539d (patch)
tree1272156e48dfdcff77f2732eaba7e964197de3bb /sys/kern
parent4cb6632c89aa14d9544a8ffe3e463e6e21aec1f3 (diff)
downloadFreeBSD-src-a7b385889ec602ef4648e627bcb67bf0fd8d539d.zip
FreeBSD-src-a7b385889ec602ef4648e627bcb67bf0fd8d539d.tar.gz
Changes to the LINUX_THREADS support to only allocate extra memory for
shared signal handling when there is shared signal handling being used. This removes the main objection to making the shared signal handling a standard ability in rfork() and friends and 'unconditionalising' this code. (i.e. the allocation of an extra 328 bytes per process). Signal handling information remains in the U area until such a time as it's reference count would be incremented to > 1. At that point a new struct is malloc'd and maintained in KVM so that it can be shared between the processes (threads) using it. A function to check the reference count and move the struct back to the U area when it drops back to 1 is also supplied. Signal information is therefore now swapable for all processes that are not sharing that information with other processes. THis should addres the concerns raised by Garrett and others. Submitted by: "Richard Seaman, Jr." <dick@tar.com>
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c12
-rw-r--r--sys/kern/kern_exit.c43
-rw-r--r--sys/kern/kern_fork.c36
3 files changed, 55 insertions, 36 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 9269b26..246684f 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
- * $Id: init_main.c,v 1.101 1998/12/19 08:23:31 julian Exp $
+ * $Id: init_main.c,v 1.102 1998/12/30 10:38:58 dfr Exp $
*/
#include "opt_devfs.h"
@@ -469,22 +469,12 @@ proc0_init(dummy)
#endif /* INCOMPAT_LITES2*/
#endif
-#ifndef COMPAT_LINUX_THREADS
/*
* We continue to place resource usage info and signal
* actions in the user struct so they're pageable.
*/
p->p_stats = &p->p_addr->u_stats;
p->p_sigacts = &p->p_addr->u_sigacts;
-#else
- /*
- * We continue to place resource usage info in the user struct so
- * it's pageable.
- */
- p->p_stats = &p->p_addr->u_stats;
-
- p->p_sigacts = &p->p_procsig->ps_sigacts;
-#endif /* COMPAT_LINUX_THREADS */
/*
* Charge root for one process.
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 7de0c48..7be01af 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
- * $Id: kern_exit.c,v 1.69 1998/11/11 10:03:54 truckman Exp $
+ * $Id: kern_exit.c,v 1.70 1998/12/19 02:55:33 julian Exp $
*/
#include "opt_compat.h"
@@ -73,6 +73,9 @@
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_zone.h>
+#ifdef COMPAT_LINUX_THREADS
+#include <sys/user.h>
+#endif
static MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status");
@@ -438,14 +441,6 @@ loop:
if (uap->pid != WAIT_ANY &&
p->p_pid != uap->pid && p->p_pgid != -uap->pid)
continue;
-#ifdef COMPAT_LINUX_THREADS
- #if 0
- if ((p->p_sigparent != 0) ^ ((uap->options & WLINUXCLONE) != 0)) {
- continue;
- }
- #endif
-
-#endif /* COMPAT_LINUX_THREADS */
nfound++;
if (p->p_stat == SZOMB) {
/* charge childs scheduling cpu usage to parent */
@@ -515,11 +510,11 @@ loop:
#ifdef COMPAT_LINUX_THREADS
if (--p->p_procsig->ps_refcnt == 0) {
- free(p->p_procsig, M_TEMP);
+ if (p->p_sigacts != &p->p_addr->u_sigacts)
+ FREE(p->p_sigacts, M_SUBPROC);
+ FREE(p->p_procsig, M_SUBPROC);
p->p_procsig = NULL;
- p->p_sigacts = NULL;
}
-
#endif /* COMPAT_LINUX_THREADS */
/*
* Give machine-dependent layer a chance
@@ -576,11 +571,6 @@ proc_reparent(child, parent)
LIST_REMOVE(child, p_sibling);
LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
child->p_pptr = parent;
-#ifdef COMPAT_LINUX_THREADS
- #if 0
- child->p_sigparent = 0;
- #endif
-#endif /* COMPAT_LINUX_THREADS */
}
/*
@@ -636,3 +626,22 @@ rm_at_exit(function)
}
return (count);
}
+
+#ifdef COMPAT_LINUX_THREADS
+void check_sigacts (void)
+{
+ struct proc *p = curproc;
+ struct sigacts *pss;
+ int s;
+
+ if (p->p_procsig->ps_refcnt == 1 &&
+ p->p_sigacts != &p->p_addr->u_sigacts) {
+ pss = p->p_sigacts;
+ s = splhigh();
+ p->p_addr->u_sigacts = *pss;
+ p->p_sigacts = &p->p_addr->u_sigacts;
+ splx(s);
+ FREE(pss, M_SUBPROC);
+ }
+}
+#endif
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index ef38e01..732712b 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
- * $Id: kern_fork.c,v 1.52 1998/11/09 15:07:41 truckman Exp $
+ * $Id: kern_fork.c,v 1.53 1998/12/19 02:55:33 julian Exp $
*/
#include "opt_ktrace.h"
@@ -64,7 +64,7 @@
#ifdef COMPAT_LINUX_THREADS
#include <machine/frame.h>
-
+#include <sys/user.h>
#endif /* COMPAT_LINUX_THREADS */
#ifdef SMP
static int fast_vfork = 0; /* Doesn't work on SMP yet. */
@@ -331,21 +331,41 @@ again:
#ifdef COMPAT_LINUX_THREADS
if (flags & RFSIGSHARE) {
+ p2->p_procsig = p1->p_procsig;
p2->p_procsig->ps_refcnt++;
+ if (p1->p_sigacts == &p1->p_addr->u_sigacts) {
+ struct sigacts *newsigacts;
+ int s;
+
+ if (p2->p_procsig->ps_refcnt != 2)
+ printf ("PID:%d Creating shared sigacts with procsig->ps_refcnt %d\n",
+ p2->p_pid, p2->p_procsig->ps_refcnt);
+ /* Create the shared sigacts structure */
+ MALLOC (newsigacts, struct sigacts *, sizeof (struct sigacts),
+ M_SUBPROC, M_WAITOK);
+ s = splhigh();
+ /* Set p_sigacts to the new shared structure. Note that this
+ * is updating p1->p_sigacts at the same time, since p_sigacts
+ * is just a pointer to the shared p_procsig->ps_sigacts.
+ */
+ p2->p_sigacts = newsigacts;
+ /* Copy in the values from the u area */
+ *p2->p_sigacts = p1->p_addr->u_sigacts;
+ splx (s);
+ }
} else {
- p2->p_procsig = malloc(sizeof(struct procsig), M_TEMP, M_WAITOK);
- p2->p_procsig->ps_refcnt = 1;
- p2->p_procsig->ps_posix = 0;
+ MALLOC (p2->p_procsig, struct procsig *, sizeof(struct procsig),
+ M_SUBPROC, M_WAITOK);
bcopy(&p1->p_procsig->ps_begincopy, &p2->p_procsig->ps_begincopy,
(unsigned)&p1->p_procsig->ps_endcopy -
(unsigned)&p1->p_procsig->ps_begincopy);
+ p2->p_procsig->ps_refcnt = 1;
+ /* Note that we fill in the values of sigacts in vm_fork */
+ p2->p_sigacts = NULL;
}
if (flags & RFLINUXTHPN) {
p2->p_sigparent = SIGUSR1;
}
- p2->p_sigacts = &p2->p_procsig->ps_sigacts;
- if((flags & RFTHREAD) != 0 && (flags & RFPOSIXSIG) != 0)
- p2->p_procsig->ps_posix = 1;
#endif /* COMPAT_LINUX_THREADS */
/* bump references to the text vnode (for procfs) */
p2->p_textvp = p1->p_textvp;
OpenPOWER on IntegriCloud