Subject: Re: more on exit performance
To: <>
From: David Laight <david@l8s.co.uk>
List: tech-perform
Date: 11/02/2003 10:48:21
> 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: david@l8s.co.uk