diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2013-06-05 00:53:28 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2013-06-05 00:53:28 +0000 |
commit | e9bbd641054badfebf5127a5572b4f342e0fbd1d (patch) | |
tree | 0db749db29ee9d1dfa1d3c4fca1fb6dd44fbff9d | |
parent | 1784fbc18e244969eb2bb128ef3922fc0be9562b (diff) |
factor out pid allocation to functions. add a small cache of recently
exited pids that won't get recycled.
ok deraadt
-rw-r--r-- | sys/kern/kern_exit.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 47 | ||||
-rw-r--r-- | sys/sys/proc.h | 6 |
3 files changed, 44 insertions, 12 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index a9acc650ac5..27b95adead7 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exit.c,v 1.124 2013/06/01 04:05:26 tedu Exp $ */ +/* $OpenBSD: kern_exit.c,v 1.125 2013/06/05 00:53:26 tedu Exp $ */ /* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */ /* @@ -644,6 +644,7 @@ proc_zap(struct proc *p) nprocesses--; } + freepid(p->p_pid); pool_put(&proc_pool, p); nthreads--; } diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 378b367efe5..8cb56608824 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.149 2013/06/03 22:35:15 guenther Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.150 2013/06/05 00:53:26 tedu Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -72,7 +72,6 @@ int nprocesses = 1; /* process 0 */ int nthreads = 1; /* proc 0 */ int randompid; /* when set to 1, pid's go random */ -pid_t lastpid; struct forkstat forkstat; void fork_return(void *); @@ -436,11 +435,7 @@ fork1(struct proc *curp, int exitsig, int flags, void *stack, pid_t *tidptr, newstrp = systrace_getproc(); #endif - /* Find an unused pid satisfying 1 <= lastpid <= PID_MAX */ - do { - lastpid = 1 + (randompid ? arc4random() : lastpid) % PID_MAX; - } while (pidtaken(lastpid)); - p->p_pid = lastpid; + p->p_pid = allocpid(); LIST_INSERT_HEAD(&allproc, p, p_list); LIST_INSERT_HEAD(PIDHASH(p->p_pid), p, p_hash); @@ -562,22 +557,56 @@ fork1(struct proc *curp, int exitsig, int flags, void *stack, pid_t *tidptr, /* * Checks for current use of a pid, either as a pid or pgid. */ +pid_t oldpids[100]; int -pidtaken(pid_t pid) +ispidtaken(pid_t pid) { + uint32_t i; struct proc *p; + for (i = 0; i < nitems(oldpids); i++) + if (pid == oldpids[i]) + return (1); + if (pfind(pid) != NULL) return (1); if (pgfind(pid) != NULL) return (1); LIST_FOREACH(p, &zombproc, p_list) { - if (p->p_pid == pid || (p->p_p->ps_pgrp && p->p_p->ps_pgrp->pg_id == pid)) + if (p->p_pid == pid || + (p->p_p->ps_pgrp && p->p_p->ps_pgrp->pg_id == pid)) return (1); } return (0); } +/* Find an unused pid satisfying 1 <= lastpid <= PID_MAX */ +pid_t +allocpid(void) +{ + static pid_t lastpid; + pid_t pid; + + if (!randompid) { + /* only used early on for system processes */ + pid = ++lastpid; + } else { + do { + pid = 1 + arc4random_uniform(PID_MAX - 1); + } while (ispidtaken(pid)); + } + + return pid; +} + +void +freepid(pid_t pid) +{ + static uint32_t idx; + + oldpids[idx++ % nitems(oldpids)] = pid; +} + #if defined(MULTIPROCESSOR) /* * XXX This is a slight hack to get newly-formed processes to diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 4e9c677d918..9a8a00f4e27 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.166 2013/06/03 16:55:22 guenther Exp $ */ +/* $OpenBSD: proc.h,v 1.167 2013/06/05 00:53:27 tedu Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -514,7 +514,9 @@ extern struct pool session_pool; /* memory pool for sessions */ extern struct pool pgrp_pool; /* memory pool for pgrps */ extern struct pool pcred_pool; /* memory pool for pcreds */ -struct simplelock; +int ispidtaken(pid_t); +pid_t allocpid(void); +void freepid(pid_t); struct process *prfind(pid_t); /* Find process by id. */ struct proc *pfind(pid_t); /* Find thread by id. */ |