summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorThomas Nordin <nordin@cvs.openbsd.org>2002-02-16 00:54:50 +0000
committerThomas Nordin <nordin@cvs.openbsd.org>2002-02-16 00:54:50 +0000
commita7545bb7c5b71d6fd31e8d095f073f57f3e71469 (patch)
tree00b57ec8f0367028abfd9aadf65cba0a4e7425b7 /sys
parent010a254f06000b8decbb84ab7fa34242af37ef78 (diff)
Simplify pid selection algorithm. ok art@ deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_fork.c68
1 files changed, 23 insertions, 45 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 6c8c72c04e5..5c5e49446e3 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.51 2002/02/14 22:58:15 art Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.52 2002/02/16 00:54:49 nordin Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -69,6 +69,7 @@ int randompid; /* when set to 1, pid's go random */
pid_t lastpid;
struct forkstat forkstat;
+int pidtaken(pid_t);
/*ARGSUSED*/
int
@@ -148,7 +149,6 @@ fork1(p1, exitsig, flags, stack, stacksize, func, arg, retval)
struct proc *newproc;
struct vmspace *vm;
int count;
- static int pidchecked = 0;
vaddr_t uaddr;
int s;
extern void endtsleep __P((void *));
@@ -186,49 +186,10 @@ fork1(p1, exitsig, flags, stack, stacksize, func, arg, retval)
/* Allocate new proc. */
newproc = pool_get(&proc_pool, PR_WAITOK);
- lastpid++;
- if (randompid)
- lastpid = PID_MAX;
-retry:
- /*
- * If the process ID prototype has wrapped around,
- * restart somewhat above 0, as the low-numbered procs
- * tend to include daemons that don't exit.
- */
- if (lastpid >= PID_MAX) {
- lastpid = arc4random() % PID_MAX;
- pidchecked = 0;
- }
- if (lastpid >= pidchecked) {
- int doingzomb = 0;
-
- pidchecked = PID_MAX;
- /*
- * Scan the active and zombie procs to check whether this pid
- * is in use. Remember the lowest pid that's greater
- * than lastpid, so we can avoid checking for a while.
- */
- p2 = LIST_FIRST(&allproc);
-again:
- for (; p2 != 0; p2 = LIST_NEXT(p2, p_list)) {
- while (p2->p_pid == lastpid ||
- p2->p_pgrp->pg_id == lastpid) {
- lastpid++;
- if (lastpid >= pidchecked)
- goto retry;
- }
- if (p2->p_pid > lastpid && pidchecked > p2->p_pid)
- pidchecked = p2->p_pid;
- if (p2->p_pgrp->pg_id > lastpid &&
- pidchecked > p2->p_pgrp->pg_id)
- pidchecked = p2->p_pgrp->pg_id;
- }
- if (!doingzomb) {
- doingzomb = 1;
- p2 = LIST_FIRST(&zombproc);
- goto again;
- }
- }
+ /* Find an unused pid satisfying 1 <= lastpid <= PID_MAX */
+ do {
+ lastpid = 1 + (randompid ? arc4random() : lastpid) % PID_MAX;
+ } while (pidtaken(lastpid));
nprocs++;
p2 = newproc;
@@ -415,3 +376,20 @@ again:
return (0);
}
+/*
+ * Checks for current use of a pid, either as a pid or pgid.
+ */
+int
+pidtaken(pid_t pid)
+{
+ struct proc *p;
+
+ 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_pgid == pid)
+ return (1);
+ return (0);
+}