chuqui@nsc.UUCP (Chuq Von Rospach) (06/24/84)
while ripping apart inews and the batching schemes during the Great Inews Rewrite pilgrimage, I found an inefficiency problem in Peter Gross's bnproc that was rather easy to fix, so I did until I can get bnproc integrated into inews. For every message shoved into bnproc it was calling popen() to spawn rnews. Well, popen() uses the wonderful system() call, which spawns a shell which spawns rnews. That is TWO processes per message. When you consider we are averaging 300-500 messages a day, that is a lot of overhead. This version of bnproc looks in "defs.h" for the home of rnews (defined by the string RNEWS, normally /usr/bin) and forks and execl()'s it directly. My timing tests show that the original version used about 2.5 CPU seconds per message (with two processes) while this version uses about 2.3 CPU seconds per message (doesn't sound like much, but forking is an expensive process when we are talking about 500 of them!). This should help sites using this batch scheme until I teach inews enough so we don't fork at all. chuq P.S. I've also gotten bnuuxqt.c running under 4.2. The changes were easy, but if you are interested in a copy, let me know. --- bnproc.c --- # ifndef NOSCCS static char *sccsid = "%W% %G%"; # endif /***************************************************************************** * bnproc: break up and process the batched news files * *****************************************************************************/ #include <stdio.h> #include <signal.h> #include "../src/defs.h" char buf[80]; FILE *prnews(); main(ac, av) char **av; { nice(40); /* be VERY nice */ while(--ac > 0) process(*++av); exit(0); } process(fn) char *fn; { long size; register FILE *ifn, *pfn; if ((ifn = fopen(fn, "r")) == NULL) return; while(fgets(buf, sizeof(buf), ifn) != NULL) { long atol(); register c; size = atol(buf); if(size <= 0) continue; pfn = prnews(); /* spawn rnews efficiently */ while(--size >= 0 && (c = getc(ifn)) != EOF) putc(c, pfn); pclose(pfn); } fclose(ifn); } /* * This is a modified version of popen. Rather than * forking off a shell, you get a bare process. * this process will be rnews, with no arguments. This is for * efficiency reasons since the standard popen spawns a shell * AND the process, and two processes per message is a bit much. */ #define RDR 0 #define WTR 1 static int mopen_pid[20]; FILE * prnews() { int p[2]; register myside, hisside, pid; char *sendto = NULL; if(pipe(p) < 0) return NULL; myside = p[WTR]; hisside = p[RDR]; if((pid = fork()) == 0) { /* myside and hisside reverse roles in child */ close(myside); close(0); dup(hisside); close(hisside); execl(RNEWS, "rnews", 0); _exit(1); } if(pid == -1) return NULL; mopen_pid[myside] = pid; close(hisside); return(fdopen(myside, "w")); } -- From the ledge of the seventh cornice: Chuq Von Rospach {amd,fortune,hplabs,ihnp4}!nsc!chuqui (408) 733-2600 x242 You can't always get what you want, but if you try sometime you just might find, you'll get what you need! -- Rolling Stones