Re: more on exit performance

David Laight <[email protected]>
Newsgroups gmane.os.netbsd.devel.performance
Message-ID <[email protected]>
> find_stopped_child() walks a linked-list of the proc's children.
> there are several ways to improve this:
> 
>  (1) for (pid > 0), we can just look the pid up in the pid_table
>      instead of finding it via the parent.

Probably worth while - untested patch below.

>  (2) for (pid == -1), we can keep the stopped and dead children on
>      separate lists, and only look at the list(s) that we care about.

Why not just requeue a stopped child at the top of the sibling list?
It will save all the extra pointers (and data structures to get wrong!).
I don't know how how many children the benchmark process has, but I
suspet it is a lot!  Even then this gains <10%, for a normal process
(and system workload) it must be noise.

It might also be necessary to count the stopped children - saving the
initial scan of the entire list in order to sleep.

I'd actually worry more about the scheduler scanning the 'allproc'
lists on every clock tick (why not just the runnable process/lwp lists?).
 
>  (3) for (pid < -1), we can similarly look up the pgrp in pid_table
>      and keep the stopped and dead children on separate lists in the pgrp.

Can't possibly happen often enough to worry about.

	David

Index: kern_exit.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exit.c,v
retrieving revision 1.124
diff -u -p -r1.124 kern_exit.c
--- kern_exit.c	2003/09/16 13:46:24	1.124
+++ kern_exit.c	2003/11/02 10:39:49
@@ -718,10 +727,16 @@ find_stopped_child(struct proc *parent, 
 	for (;;) {
 		c_found = 0;
 		LIST_FOREACH(child, &parent->p_children, p_sibling) {
-			if (pid != WAIT_ANY &&
-			    child->p_pid != pid &&
-			    child->p_pgid != -pid)
-				continue;
+			if (pid >= 0) {
+				if (child->p_pid != pid) {
+					child = pfind(pid);
+					if (child == NULL
+					    || child->p_parent != parent)
+						break;
+				}
+			} else
+				if (pid != WAIT_ANY && child->p_pgid != -pid)
+					continue;
 			/*
 			 * Wait for processes with p_exitsig != SIGCHLD
 			 * processes only if WALTSIG is set; wait for
@@ -730,8 +745,11 @@ find_stopped_child(struct proc *parent, 
 			 */
 			if (((options & WALLSIG) == 0) &&
 			    (options & WALTSIG ? child->p_exitsig == SIGCHLD
-						: P_EXITSIG(child) != SIGCHLD))
+						: P_EXITSIG(child) != SIGCHLD)){
+				if (child->p_pid == pid)
+					break;
 				continue;
+			}
 
 			c_found = 1;
 			if (child->p_stat == SZOMB &&
@@ -748,6 +766,8 @@ find_stopped_child(struct proc *parent, 
 				*child_p = child;
 				return 0;
 			}
+			if (child->p_pid == pid)
+				break;
 		}
 		if (c_found == 0)
 			return ECHILD;
-- 
David Laight: [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.