diff options
author | Thomas Nordin <nordin@cvs.openbsd.org> | 2002-02-16 00:54:50 +0000 |
---|---|---|
committer | Thomas Nordin <nordin@cvs.openbsd.org> | 2002-02-16 00:54:50 +0000 |
commit | a7545bb7c5b71d6fd31e8d095f073f57f3e71469 (patch) | |
tree | 00b57ec8f0367028abfd9aadf65cba0a4e7425b7 /sys | |
parent | 010a254f06000b8decbb84ab7fa34242af37ef78 (diff) |
Simplify pid selection algorithm. ok art@ deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_fork.c | 68 |
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); +} |