summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2013-06-05 00:53:28 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2013-06-05 00:53:28 +0000
commite9bbd641054badfebf5127a5572b4f342e0fbd1d (patch)
tree0db749db29ee9d1dfa1d3c4fca1fb6dd44fbff9d
parent1784fbc18e244969eb2bb128ef3922fc0be9562b (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.c3
-rw-r--r--sys/kern/kern_fork.c47
-rw-r--r--sys/sys/proc.h6
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. */