summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2007-04-03 08:05:44 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2007-04-03 08:05:44 +0000
commit5580441acd58a8850e70767fc09899dacbd178c8 (patch)
tree96d6c1a7f653b837ecf0e4d69400bfc4be4b2cb1 /sys
parent5b93fa777227ca6c9b54d583dfb61a891f76e3f8 (diff)
Start moving state that is shared among threads in a process into
a new struct. Instead of doing a huge rename and deal with the fallout for weeks, like other projects that need no mention, we will slowly and carefully move things out of struct proc into a new struct process. - Create struct process and the infrastructure to create and remove them. - Move threads in a process into struct process. deraadt@, tedu@ ok
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/init_main.c12
-rw-r--r--sys/kern/kern_exit.c49
-rw-r--r--sys/kern/kern_fork.c48
-rw-r--r--sys/kern/kern_proc.c5
-rw-r--r--sys/kern/kern_prot.c8
-rw-r--r--sys/kern/kern_sig.c24
-rw-r--r--sys/kern/kern_synch.c11
-rw-r--r--sys/sys/proc.h35
8 files changed, 121 insertions, 71 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 291aa2e5a6a..01dd7faa856 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.137 2007/03/24 16:01:22 art Exp $ */
+/* $OpenBSD: init_main.c,v 1.138 2007/04/03 08:05:43 art Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -108,6 +108,7 @@ const char copyright[] =
struct session session0;
struct pgrp pgrp0;
struct proc proc0;
+struct process process0;
struct pcred cred0;
struct plimit limit0;
struct vmspace vmspace0;
@@ -258,6 +259,12 @@ main(void *framep)
/*
* Create process 0 (the swapper).
*/
+
+ process0.ps_mainproc = p;
+ TAILQ_INIT(&process0.ps_threads);
+ TAILQ_INSERT_TAIL(&process0.ps_threads, p, p_thr_link);
+ p->p_p = &process0;
+
LIST_INSERT_HEAD(&allproc, p, p_list);
p->p_pgrp = &pgrp0;
LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
@@ -269,9 +276,6 @@ main(void *framep)
session0.s_count = 1;
session0.s_leader = p;
- p->p_thrparent = p;
- LIST_INIT(&p->p_thrchildren);
-
atomic_setbits_int(&p->p_flag, P_SYSTEM | P_NOCLDWAIT);
p->p_stat = SONPROC;
p->p_nice = NZERO;
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 9823b41e223..775306320e6 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exit.c,v 1.63 2007/03/15 10:22:30 art Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.64 2007/04/03 08:05:43 art Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
@@ -125,30 +125,36 @@ exit1(struct proc *p, int rv, int flags)
* we have to be careful not to get recursively caught.
* this is kinda sick.
*/
- if (flags == EXIT_NORMAL && p != p->p_thrparent &&
- (p->p_thrparent->p_flag & P_WEXIT) == 0) {
+ if (flags == EXIT_NORMAL && p->p_p->ps_mainproc != p &&
+ (p->p_p->ps_mainproc->p_flag & P_WEXIT) == 0) {
/*
* we are one of the threads. we SIGKILL the parent,
* it will wake us up again, then we proceed.
*/
atomic_setbits_int(&p->p_thrparent->p_flag, P_IGNEXITRV);
- p->p_thrparent->p_xstat = rv;
- psignal(p->p_thrparent, SIGKILL);
- tsleep(&p->p_thrparent->p_thrchildren, PUSER, "thrdying", 0);
- } else if (p == p->p_thrparent) {
+ p->p_p->ps_mainproc->p_xstat = rv;
+ psignal(p->p_p->ps_mainproc, SIGKILL);
+ tsleep(p->p_p, PUSER, "thrdying", 0);
+ } else if (p == p->p_p->ps_mainproc) {
atomic_setbits_int(&p->p_flag, P_WEXIT);
if (flags == EXIT_NORMAL) {
- q = LIST_FIRST(&p->p_thrchildren);
+ q = TAILQ_FIRST(&p->p_p->ps_threads);
for (; q != NULL; q = nq) {
- nq = LIST_NEXT(q, p_thrsib);
+ nq = TAILQ_NEXT(q, p_thr_link);
+
+ /*
+ * Don't shoot ourselves again.
+ */
+ if (q == p)
+ continue;
atomic_setbits_int(&q->p_flag, P_IGNEXITRV);
q->p_xstat = rv;
psignal(q, SIGKILL);
}
}
- wakeup(&p->p_thrchildren);
- while (!LIST_EMPTY(&p->p_thrchildren))
- tsleep(&p->p_thrchildren, PUSER, "thrdeath", 0);
+ wakeup(p->p_p);
+ while (!TAILQ_EMPTY(&p->p_p->ps_threads))
+ tsleep(&p->p_p->ps_threads, PUSER, "thrdeath", 0);
}
#endif
@@ -263,13 +269,11 @@ exit1(struct proc *p, int rv, int flags)
}
}
-#ifdef RTHREADS
/* unlink oursleves from the active threads */
- if (p != p->p_thrparent) {
- LIST_REMOVE(p, p_thrsib);
- if (LIST_EMPTY(&p->p_thrparent->p_thrchildren))
- wakeup(&p->p_thrparent->p_thrchildren);
- }
+ TAILQ_REMOVE(&p->p_p->ps_threads, p, p_thr_link);
+#ifdef RTHREADS
+ if (TAILQ_EMPTY(&p->p_p->ps_threads))
+ wakeup(&p->p_p->ps_threads);
#endif
/*
@@ -610,6 +614,15 @@ proc_zap(struct proc *p)
if (p->p_textvp)
vrele(p->p_textvp);
+ /*
+ * Remove us from our process list, possibly killing the process
+ * in the process (pun intended).
+ */
+
+ TAILQ_REMOVE(&p->p_p->ps_threads, p, p_thr_link);
+ if (TAILQ_EMPTY(&p->p_p->ps_threads))
+ pool_put(&process_pool, p->p_p);
+
pool_put(&proc_pool, p);
nprocs--;
}
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index da8d0df31c4..c187ea87f18 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.88 2007/03/24 16:01:22 art Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.89 2007/04/03 08:05:43 art Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -73,6 +73,8 @@ struct forkstat forkstat;
void fork_return(void *);
int pidtaken(pid_t);
+void process_new(struct proc *, struct proc *);
+
void
fork_return(void *arg)
{
@@ -147,6 +149,21 @@ sys_rfork(struct proc *p, void *v, register_t *retval)
return (fork1(p, SIGCHLD, flags, NULL, 0, NULL, NULL, retval, NULL));
}
+/*
+ * Allocate and initialize a new process.
+ */
+void
+process_new(struct proc *newproc, struct proc *parent)
+{
+ struct process *pr;
+
+ pr = pool_get(&process_pool, PR_WAITOK);
+ pr->ps_mainproc = newproc;
+ TAILQ_INIT(&pr->ps_threads);
+ TAILQ_INSERT_TAIL(&pr->ps_threads, newproc, p_thr_link);
+ newproc->p_p = pr;
+}
+
/* print the 'table full' message once per 10 seconds */
struct timeval fork_tfmrate = { 10, 0 };
@@ -209,6 +226,18 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
p2->p_exitsig = exitsig;
p2->p_forw = p2->p_back = NULL;
+#ifdef RTHREADS
+ if (flags & FORK_THREAD) {
+ atomic_setbits_int(&p2->p_flag, P_THREAD);
+ p2->p_p = p1->p_p;
+ TAILQ_INSERT_TAIL(&p2->p_p->ps_threads, p2, p_thr_link);
+ } else {
+ process_new(p2, p1);
+ }
+#else
+ process_new(p2, p1);
+#endif
+
/*
* Make a proc table entry for the new process.
* Start by zeroing the section of proc that is zero-initialized,
@@ -282,19 +311,6 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
atomic_setbits_int(&p2->p_flag, P_NOZOMBIE);
LIST_INIT(&p2->p_children);
-#ifdef RTHREADS
- if (flags & FORK_THREAD) {
- atomic_setbits_int(&p2->p_flag, P_THREAD);
- p2->p_thrparent = p1->p_thrparent;
- } else {
- p2->p_thrparent = p2;
- }
-#else
- p2->p_thrparent = p2;
-#endif
-
- LIST_INIT(&p2->p_thrchildren);
-
#ifdef KTRACE
/*
* Copy traceflag and tracefile if enabled.
@@ -366,10 +382,6 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling);
LIST_INSERT_AFTER(p1, p2, p_pglist);
-#ifdef RTHREADS
- if (flags & FORK_THREAD)
- LIST_INSERT_HEAD(&p1->p_thrparent->p_thrchildren, p2, p_thrsib);
-#endif
if (p2->p_flag & P_TRACED) {
p2->p_oppid = p1->p_pid;
if (p2->p_pptr != p1->p_pptr)
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 46b416d8507..a874415df47 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_proc.c,v 1.32 2007/03/15 10:22:30 art Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.33 2007/04/03 08:05:43 art Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
@@ -64,6 +64,7 @@ struct proclist allproc;
struct proclist zombproc;
struct pool proc_pool;
+struct pool process_pool;
struct pool rusage_pool;
struct pool ucred_pool;
struct pool pgrp_pool;
@@ -93,6 +94,8 @@ procinit(void)
pool_init(&proc_pool, sizeof(struct proc), 0, 0, 0, "procpl",
&pool_allocator_nointr);
+ pool_init(&process_pool, sizeof(struct process), 0, 0, 0, "processpl",
+ &pool_allocator_nointr);
pool_init(&rusage_pool, sizeof(struct rusage), 0, 0, 0, "zombiepl",
&pool_allocator_nointr);
pool_init(&ucred_pool, sizeof(struct ucred), 0, 0, 0, "ucredpl",
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index f9e195364e9..21737237f2f 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_prot.c,v 1.29 2007/03/15 10:22:30 art Exp $ */
+/* $OpenBSD: kern_prot.c,v 1.30 2007/04/03 08:05:43 art Exp $ */
/* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */
/*
@@ -60,10 +60,10 @@ int
sys_getpid(struct proc *p, void *v, register_t *retval)
{
- *retval = p->p_thrparent->p_pid;
+ *retval = p->p_p->ps_mainproc->p_pid;
#if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_IBCS2) || \
defined(COMPAT_FREEBSD) || defined(COMPAT_BSDOS)
- retval[1] = p->p_thrparent->p_pptr->p_pid;
+ retval[1] = p->p_p->ps_mainproc->p_pptr->p_pid;
#endif
return (0);
}
@@ -87,7 +87,7 @@ int
sys_getppid(struct proc *p, void *v, register_t *retval)
{
- *retval = p->p_pptr->p_pid;
+ *retval = p->p_p->ps_mainproc->p_pptr->p_pid;
return (0);
}
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 43691c0c4c9..5cc41b4c702 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.88 2007/03/15 10:22:30 art Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.89 2007/04/03 08:05:43 art Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -97,8 +97,9 @@ cansignal(struct proc *p, struct pcred *pc, struct proc *q, int signum)
#ifdef RTHREADS
/* a thread can only be signalled from within the same process */
- if (q->p_flag & P_THREAD)
- return (p->p_thrparent == q->p_thrparent);
+ if (q->p_flag & P_THREAD) {
+ return (p->p_p == q->p_p);
+ }
#endif
if (signum == SIGCONT && q->p_session == p->p_session)
@@ -787,7 +788,9 @@ psignal(struct proc *p, int signum)
return;
#ifdef RTHREADS
- LIST_FOREACH(q, &p->p_thrchildren, p_thrsib) {
+ TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
+ if (q == p)
+ continue;
if (q->p_sigdivert & (1 << signum)) {
q->p_sigdivert = 0;
psignal(q, signum);
@@ -839,16 +842,21 @@ psignal(struct proc *p, int signum)
if (prop & SA_CONT) {
#ifdef RTHREADS
- LIST_FOREACH(q, &p->p_thrchildren, p_thrsib)
- psignal(q, signum);
+ TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
+ if (q != p)
+ psignal(q, signum);
+ }
#endif
atomic_clearbits_int(&p->p_siglist, stopsigmask);
}
if (prop & SA_STOP) {
#ifdef RTHREADS
- LIST_FOREACH(q, &p->p_thrchildren, p_thrsib)
- psignal(q, signum);
+
+ TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
+ if (q != p)
+ psignal(q, signum);
+ }
#endif
atomic_clearbits_int(&p->p_siglist, contsigmask);
atomic_clearbits_int(&p->p_flag, P_CONTINUED);
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 485a144c0f8..5acff3ccad8 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_synch.c,v 1.78 2007/03/21 09:09:52 art Exp $ */
+/* $OpenBSD: kern_synch.c,v 1.79 2007/04/03 08:05:43 art Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
@@ -432,14 +432,7 @@ sys_thrwakeup(struct proc *p, void *v, register_t *retval)
struct proc *q;
int found = 0;
- /* have to check the parent, it's not in the thread list */
- if (p->p_thrparent->p_thrslpid == ident) {
- wakeup(&p->p_thrparent->p_thrslpid);
- p->p_thrparent->p_thrslpid = 0;
- if (++found == n)
- return (0);
- }
- LIST_FOREACH(q, &p->p_thrparent->p_thrchildren, p_thrsib) {
+ TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
if (q->p_thrslpid == ident) {
wakeup(&q->p_thrslpid);
q->p_thrslpid = 0;
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index f956d2be875..8e220b99980 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.92 2007/03/24 16:01:22 art Exp $ */
+/* $OpenBSD: proc.h,v 1.93 2007/04/03 08:05:43 art Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -117,19 +117,40 @@ extern int nemuls; /* Number of emuls */
/*
* Description of a process.
*
- * This structure contains the information needed to manage a thread of
+ * These structures contain the information needed to manage a thread of
* control, known in UN*X as a process; it has references to substructures
* containing descriptions of things that the process uses, but may share
* with related processes. The process structure and the substructures
* are always addressable except for those marked "(PROC ONLY)" below,
* which might be addressable only on a processor on which the process
* is running.
+ *
+ * struct process is the higher level process containing information
+ * shared by all threads in a process, while struct proc contains the
+ * run-time information needed by threads.
*/
-struct proc {
+struct process {
+ /*
+ * ps_mainproc is the main thread in the process.
+ * Ultimately, we shouldn't need that, threads should be able to exit
+ * at will. Unfortunately until the pid is moved into struct process
+ * we'll have to remember the main threads and abouse its pid as the
+ * the pid of the process. This is gross, but considering the horrible
+ * pid semantics we have right now, it's unavoidable.
+ */
+ struct proc *ps_mainproc;
+
+ TAILQ_HEAD(,proc) ps_threads; /* Threads in this process. */
+};
+
+struct proc {
struct proc *p_forw; /* Doubly-linked run/sleep queue. */
struct proc *p_back;
LIST_ENTRY(proc) p_list; /* List of all processes. */
+ struct process *p_p; /* The process of this thread. */
+ TAILQ_ENTRY(proc) p_thr_link;/* Threads in a process linkage. */
+
/* substructures: */
struct pcred *p_cred; /* Process owner's identity. */
struct filedesc *p_fd; /* Ptr to open files structure. */
@@ -161,12 +182,7 @@ struct proc {
pid_t p_oppid; /* Save parent pid during ptrace. XXX */
int p_dupfd; /* Sideways return value from filedescopen. XXX */
- /* threads are processes that sometimes use the parent thread's
- * info for userland visibility */
- struct proc *p_thrparent;
- LIST_ENTRY(proc) p_thrsib;
- LIST_HEAD(, proc) p_thrchildren;
- long p_thrslpid; /* for thrsleep syscall */
+ long p_thrslpid; /* for thrsleep syscall */
/* scheduling */
@@ -396,6 +412,7 @@ extern struct proclist zombproc; /* List of zombie processes. */
extern struct proc *initproc; /* Process slots for init, pager. */
extern struct proc *syncerproc; /* filesystem syncer daemon */
+extern struct pool process_pool; /* memory pool for processes */
extern struct pool proc_pool; /* memory pool for procs */
extern struct pool rusage_pool; /* memory pool for zombies */
extern struct pool ucred_pool; /* memory pool for ucreds */