diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2007-04-03 08:05:44 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2007-04-03 08:05:44 +0000 |
commit | 5580441acd58a8850e70767fc09899dacbd178c8 (patch) | |
tree | 96d6c1a7f653b837ecf0e4d69400bfc4be4b2cb1 /sys | |
parent | 5b93fa777227ca6c9b54d583dfb61a891f76e3f8 (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.c | 12 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 49 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 48 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 8 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 24 | ||||
-rw-r--r-- | sys/kern/kern_synch.c | 11 | ||||
-rw-r--r-- | sys/sys/proc.h | 35 |
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 */ |