usr.bin/make KQUEUE

Max Okumoto okumoto at ucsd.edu
Mon Nov 22 17:00:14 PST 2004


Guess this one got lost in the crash.

				Max

PatchSet 282 Date: 2002/10/04 21:30:03 Author: phk
        o Give make(1) the ability to use KQUEUE to wait for worker
          processes instead of polling for them.
PatchSet 302 Date: 2002/12/01 13:38:25 Author: ru
        o Bootstrapping aid from pre-kqueue(2) systems, e.g.
          4.0-RELEASE.
PatchSet 342 Date: 2004/04/20 23:04:12 Author: green
        o Treat kevent(2) returning an error EINTR as the non-error
          it is.
---------------------
PatchSet 282
Date: 2002/10/04 21:30:03
Author: phk
Log:
Give make(1) the ability to use KQUEUE to wait for worker processes
instead of polling for them.

Unfortunately we cannot enable it yet because it panics the kernel
somewhere in kqueue.

Submitted by:	Stefan Farfeleder <e0026813 at xxxxxxxxxxxxxxxxxx>

Members: 
	Makefile:1.27->1.28 
	job.c:1.43->1.44 
	job.h:1.18->1.19 

Index: Makefile
===================================================================
RCS file: /usr/home/okumoto/Work/make/fbsd-cvs/src/usr.bin/make/Makefile,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- Makefile	17 Sep 2002 22:31:26 -0000	1.27
+++ Makefile	4 Oct 2002 20:30:03 -0000	1.28
@@ -19,6 +19,9 @@
 .if defined(_UPGRADING)
 CFLAGS+=-D__FBSDID=__RCSID
 .endif
+
+# XXX: kernel currently broken
+# CFLAGS+=-DUSE_KQUEUE
 
 main.o: ${MAKEFILE}
 
Index: job.c
===================================================================
RCS file: /usr/home/okumoto/Work/make/fbsd-cvs/src/usr.bin/make/job.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- job.c	29 Sep 2002 00:20:28 -0000	1.43
+++ job.c	4 Oct 2002 20:30:03 -0000	1.44
@@ -106,6 +106,7 @@
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
+#include <sys/event.h>
 #include <sys/wait.h>
 #include <err.h>
 #include <errno.h>
@@ -237,9 +238,13 @@
 				 * (2) a job can only be run locally, but
 				 * nLocal equals maxLocal */
 #ifndef RMT_WILL_WATCH
+#ifdef USE_KQUEUE
+static int	kqfd;		/* File descriptor obtained by kqueue() */
+#else
 static fd_set  	outputs;    	/* Set of descriptors of pipes connected to
 				 * the output channels of children */
 #endif
+#endif
 
 STATIC GNode   	*lastNode;	/* The node for which output was most recently
 				 * produced. */
@@ -692,7 +697,7 @@
     if (usePipes) {
 #ifdef RMT_WILL_WATCH
 	Rmt_Ignore(job->inPipe);
-#else
+#elif !defined(USE_KQUEUE)
 	FD_CLR(job->inPipe, &outputs);
 #endif
 	if (job->outPipe != job->inPipe) {
@@ -1267,10 +1272,22 @@
 	     * position in the buffer to the beginning and mark another
 	     * stream to watch in the outputs mask
 	     */
+#ifdef USE_KQUEUE
+	    struct kevent	kev[2];
+#endif
 	    job->curPos = 0;
 
 #ifdef RMT_WILL_WATCH
 	    Rmt_Watch(job->inPipe, JobLocalInput, job);
+#elif defined(USE_KQUEUE)
+	    EV_SET(&kev[0], job->inPipe, EVFILT_READ, EV_ADD, 0, 0, job);
+	    EV_SET(&kev[1], job->pid, EVFILT_PROC, EV_ADD | EV_ONESHOT,
+		NOTE_EXIT, 0, NULL);
+	    if (kevent(kqfd, kev, 2, NULL, 0, NULL) != 0) {
+		/* kevent() will fail if the job is already finished */
+		if (errno != EBADF && errno != ESRCH)
+		    Punt("kevent: %s", strerror(errno));
+	    }
 #else
 	    FD_SET(job->inPipe, &outputs);
 #endif /* RMT_WILL_WATCH */
@@ -2229,10 +2246,16 @@
 Job_CatchOutput()
 {
     int           	  nfds;
+#ifdef USE_KQUEUE
+#define KEV_SIZE	4
+    struct kevent	  kev[KEV_SIZE];
+    int			  i;
+#else
     struct timeval	  timeout;
     fd_set           	  readfds;
     LstNode		  ln;
     Job		   	  *job;
+#endif
 #ifdef RMT_WILL_WATCH
     int	    	  	  pnJobs;   	/* Previous nJobs */
 #endif
@@ -2262,6 +2285,27 @@
     }
 #else
     if (usePipes) {
+#ifdef USE_KQUEUE
+	if ((nfds = kevent(kqfd, NULL, 0, kev, KEV_SIZE, NULL)) == -1) {
+	    Punt("kevent: %s", strerror(errno));
+	} else {
+	    for (i = 0; i < nfds; i++) {
+		if (kev[i].flags & EV_ERROR) {
+		    warnc(kev[i].data, "kevent");
+		    continue;
+		}
+		switch (kev[i].filter) {
+		case EVFILT_READ:
+		    JobDoOutput(kev[i].udata, FALSE);
+		    break;
+		case EVFILT_PROC:
+		    /* Just wake up and let Job_CatchChildren() collect the
+		     * terminated job. */
+		    break;
+		}
+	    }
+	}
+#else
 	readfds = outputs;
 	timeout.tv_sec = SEL_SEC;
 	timeout.tv_usec = SEL_USEC;
@@ -2282,6 +2326,7 @@
 	    }
 	    Lst_Close(jobs);
 	}
+#endif /* !USE_KQUEUE */
     }
 #endif /* RMT_WILL_WATCH */
 }
@@ -2408,6 +2453,12 @@
     }
     if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) {
 	(void) signal(SIGWINCH, JobPassSig);
+    }
+#endif
+
+#ifdef USE_KQUEUE
+    if ((kqfd = kqueue()) == -1) {
+	Punt("kqueue: %s", strerror(errno));
     }
 #endif
 
Index: job.h
===================================================================
RCS file: /usr/home/okumoto/Work/make/fbsd-cvs/src/usr.bin/make/job.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- job.h	26 Sep 2002 01:39:22 -0000	1.18
+++ job.h	4 Oct 2002 20:30:03 -0000	1.19
@@ -50,6 +50,7 @@
 
 #define	TMPPAT	"/tmp/makeXXXXXXXXXX"
 
+#ifndef USE_KQUEUE
 /*
  * The SEL_ constants determine the maximum amount of time spent in select
  * before coming out to see if a child has finished. SEL_SEC is the number of
@@ -57,6 +58,7 @@
  */
 #define	SEL_SEC		0
 #define	SEL_USEC	100000
+#endif /* !USE_KQUEUE */
 
 
 /*-
---------------------
PatchSet 302
Date: 2002/12/01 13:38:25
Author: ru
Log:
Bootstrapping aid from pre-kqueue(2) systems, e.g. 4.0-RELEASE.

Submitted by:	jmallett
Approved by:	re (bmah)

Members: 
	job.c:1.47->1.48 

Index: job.c
===================================================================
RCS file: /usr/home/okumoto/Work/make/fbsd-cvs/src/usr.bin/make/job.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- job.c	28 Oct 2002 23:33:57 -0000	1.47
+++ job.c	1 Dec 2002 13:38:25 -0000	1.48
@@ -106,7 +106,9 @@
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
+#ifdef USE_KQUEUE
 #include <sys/event.h>
+#endif
 #include <sys/wait.h>
 #include <err.h>
 #include <errno.h>
---------------------
PatchSet 342
Date: 2004/04/20 23:04:12
Author: green
Log:
Treat kevent(2) returning an error EINTR as the non-error it is.

Members: 
	job.c:1.48->1.49 

Index: job.c
===================================================================
RCS file: /usr/home/okumoto/Work/make/fbsd-cvs/src/usr.bin/make/job.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- job.c	1 Dec 2002 13:38:25 -0000	1.48
+++ job.c	20 Apr 2004 22:04:12 -0000	1.49
@@ -1263,7 +1263,7 @@
 		NOTE_EXIT, 0, NULL);
 	    if (kevent(kqfd, kev, 2, NULL, 0, NULL) != 0) {
 		/* kevent() will fail if the job is already finished */
-		if (errno != EBADF && errno != ESRCH)
+		if (errno != EINTR && errno != EBADF && errno != ESRCH)
 		    Punt("kevent: %s", strerror(errno));
 	    }
 #else
@@ -2250,7 +2250,8 @@
     if (usePipes) {
 #ifdef USE_KQUEUE
 	if ((nfds = kevent(kqfd, NULL, 0, kev, KEV_SIZE, NULL)) == -1) {
-	    Punt("kevent: %s", strerror(errno));
+	    if (errno != EINTR)
+		Punt("kevent: %s", strerror(errno));
 	} else {
 	    for (i = 0; i < nfds; i++) {
 		if (kev[i].flags & EV_ERROR) {




More information about the Submit mailing list