--- ray/src/rt/raypcalls.c 2003/02/22 02:07:29 2.1
+++ ray/src/rt/raypcalls.c 2004/03/30 16:13:01 2.6
@@ -1,5 +1,5 @@
#ifndef lint
-static const char RCSid[] = "$Id: raypcalls.c,v 2.1 2003/02/22 02:07:29 greg Exp $";
+static const char RCSid[] = "$Id: raypcalls.c,v 2.6 2004/03/30 16:13:01 schorsch Exp $";
#endif
/*
* raypcalls.c - interface for parallel rendering using Radiance
@@ -7,62 +7,7 @@ static const char RCSid[] = "$Id: raypcalls.c,v 2.1 20
* External symbols declared in ray.h
*/
-/* ====================================================================
- * The Radiance Software License, Version 1.0
- *
- * Copyright (c) 1990 - 2002 The Regents of the University of California,
- * through Lawrence Berkeley National Laboratory. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes Radiance software
- * (http://radsite.lbl.gov/)
- * developed by the Lawrence Berkeley National Laboratory
- * (http://www.lbl.gov/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
- * and "The Regents of the University of California" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact radiance@radsite.lbl.gov.
- *
- * 5. Products derived from this software may not be called "Radiance",
- * nor may "Radiance" appear in their name, without prior written
- * permission of Lawrence Berkeley National Laboratory.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of Lawrence Berkeley National Laboratory. For more
- * information on Lawrence Berkeley National Laboratory, please see
- * .
- */
+#include "copyright.h"
/*
* These calls are designed similarly to the ones in raycalls.c,
@@ -111,7 +56,7 @@ static const char RCSid[] = "$Id: raypcalls.c,v 2.1 20
* proportion to the number of CPUs you have available on your
* system. If the ray queue is full before the call, ray_pqueue()
* will block until a result is ready so it can queue this one.
- * The global int ray_idle indicates the number of currently idle
+ * The global int ray_pnidle indicates the number of currently idle
* children. If you want to check for completed rays without blocking,
* or get the results from rays that have been queued without
* queuing any new ones, the ray_presult() call is for you:
@@ -126,12 +71,12 @@ static const char RCSid[] = "$Id: raypcalls.c,v 2.1 20
* queue is completely empty. A negative return value
* indicates that a rendering process died. If this
* happens, ray_close(0) is automatically called to close
- * all child processes, and ray_nprocs is set to zero.
+ * all child processes, and ray_pnprocs is set to zero.
*
* If you just want to fill the ray queue without checking for
- * results, check ray_idle and call ray_psend():
+ * results, check ray_pnidle and call ray_psend():
*
- * while (ray_idle) {
+ * while (ray_pnidle) {
* ( set up ray )
* ray_psend(&myRay);
* }
@@ -179,8 +124,13 @@ static const char RCSid[] = "$Id: raypcalls.c,v 2.1 20
* but otherwise your process should not be compromised.
*/
-#include "ray.h"
+#include
+#include
+#include /* XXX platform */
+#include "rtprocess.h"
+#include "ray.h"
+#include "ambient.h"
#include "selcall.h"
#ifndef RAYQLEN
@@ -197,8 +147,8 @@ static const char RCSid[] = "$Id: raypcalls.c,v 2.1 20
extern char *shm_boundary; /* boundary of shared memory */
-int ray_nprocs = 0; /* number of child processes */
-int ray_idle = 0; /* number of idle children */
+int ray_pnprocs = 0; /* number of child processes */
+int ray_pnidle = 0; /* number of idle children */
static struct child_proc {
int pid; /* child process id */
@@ -215,11 +165,15 @@ static int r_recv_next; /* next receive ray placement
#define sendq_full() (r_send_next >= RAYQLEN)
+static int ray_pflush(void);
+static void ray_pchild(int fd_in, int fd_out);
-void
-ray_pinit(otnm, nproc) /* initialize ray-tracing processes */
-char *otnm;
-int nproc;
+
+extern void
+ray_pinit( /* initialize ray-tracing processes */
+ char *otnm,
+ int nproc
+)
{
if (nobjects > 0) /* close old calculation */
ray_pdone(0);
@@ -240,16 +194,16 @@ int nproc;
static int
-ray_pflush() /* send queued rays to idle children */
+ray_pflush(void) /* send queued rays to idle children */
{
int nc, n, nw, i, sfirst;
- if ((ray_idle <= 0 | r_send_next <= 0))
+ if ((ray_pnidle <= 0) | (r_send_next <= 0))
return(0); /* nothing we can send */
sfirst = 0; /* divvy up labor */
- nc = ray_idle;
- for (i = ray_nprocs; nc && i--; ) {
+ nc = ray_pnidle;
+ for (i = ray_pnprocs; nc && i--; ) {
if (r_proc[i].npending > 0)
continue; /* child looks busy */
n = (r_send_next - sfirst)/nc--;
@@ -265,7 +219,7 @@ ray_pflush() /* send queued rays to idle children */
while (n--) /* record ray IDs */
r_proc[i].rno[n] = r_queue[sfirst+n].rno;
sfirst += r_proc[i].npending;
- ray_idle--; /* now she's busy */
+ ray_pnidle--; /* now she's busy */
}
if (sfirst != r_send_next)
error(CONSISTENCY, "code screwup in ray_pflush");
@@ -274,9 +228,10 @@ ray_pflush() /* send queued rays to idle children */
}
-void
-ray_psend(r) /* add a ray to our send queue */
-RAY *r;
+extern void
+ray_psend( /* add a ray to our send queue */
+ RAY *r
+)
{
if (r == NULL)
return;
@@ -284,14 +239,15 @@ RAY *r;
if (sendq_full() && ray_pflush() <= 0)
error(INTERNAL, "ray_pflush failed in ray_psend");
- copystruct(&r_queue[r_send_next], r);
+ r_queue[r_send_next] = *r;
r_send_next++;
}
-int
-ray_pqueue(r) /* queue a ray for computation */
-RAY *r;
+extern int
+ray_pqueue( /* queue a ray for computation */
+ RAY *r
+)
{
if (r == NULL)
return(0);
@@ -299,31 +255,32 @@ RAY *r;
if (sendq_full()) {
RAY mySend;
int rval;
- copystruct(&mySend, r);
+ mySend = *r;
/* wait for a result */
rval = ray_presult(r, 0);
/* put new ray in queue */
- copystruct(&r_queue[r_send_next], &mySend);
+ r_queue[r_send_next] = mySend;
r_send_next++;
return(rval); /* done */
}
/* add ray to send queue */
- copystruct(&r_queue[r_send_next], r);
+ r_queue[r_send_next] = *r;
r_send_next++;
/* check for returned ray... */
if (r_recv_first >= r_recv_next)
return(0);
/* ...one is sitting in queue */
- copystruct(r, &r_queue[r_recv_first]);
+ *r = r_queue[r_recv_first];
r_recv_first++;
return(1);
}
-int
-ray_presult(r, poll) /* check for a completed ray */
-RAY *r;
-int poll;
+extern int
+ray_presult( /* check for a completed ray */
+ RAY *r,
+ int poll
+)
{
static struct timeval tpoll; /* zero timeval struct */
static fd_set readset, errset;
@@ -334,11 +291,11 @@ int poll;
return(0);
/* check queued results first */
if (r_recv_first < r_recv_next) {
- copystruct(r, &r_queue[r_recv_first]);
+ *r = r_queue[r_recv_first];
r_recv_first++;
return(1);
}
- n = ray_nprocs - ray_idle; /* pending before flush? */
+ n = ray_pnprocs - ray_pnidle; /* pending before flush? */
if (ray_pflush() < 0) /* send new rays to process */
return(-1);
@@ -346,18 +303,18 @@ int poll;
r_recv_first = r_recv_next = RAYQLEN;
if (!poll) /* count newly sent unless polling */
- n = ray_nprocs - ray_idle;
+ n = ray_pnprocs - ray_pnidle;
if (n <= 0) /* return if nothing to await */
return(0);
getready: /* any children waiting for us? */
- for (pn = ray_nprocs; pn--; )
+ for (pn = ray_pnprocs; pn--; )
if (FD_ISSET(r_proc[pn].fd_recv, &readset) ||
FD_ISSET(r_proc[pn].fd_recv, &errset))
break;
/* call select if we must */
if (pn < 0) {
FD_ZERO(&readset); FD_ZERO(&errset); n = 0;
- for (pn = ray_nprocs; pn--; ) {
+ for (pn = ray_pnprocs; pn--; ) {
if (r_proc[pn].npending > 0)
FD_SET(r_proc[pn].fd_recv, &readset);
FD_SET(r_proc[pn].fd_recv, &errset);
@@ -393,7 +350,7 @@ getready: /* any children waiting for us? */
if (n <= 0)
FD_CLR(r_proc[pn].fd_recv, &errset);
r_proc[pn].npending = 0;
- ray_idle++;
+ ray_pnidle++;
/* check for rendering errors */
if (!ok) {
ray_pclose(0); /* process died -- clean up */
@@ -409,15 +366,16 @@ getready: /* any children waiting for us? */
rp->slights = NULL;
}
/* return first ray received */
- copystruct(r, &r_queue[r_recv_first]);
+ *r = r_queue[r_recv_first];
r_recv_first++;
return(1);
}
-void
-ray_pdone(freall) /* reap children and free data */
-int freall;
+extern void
+ray_pdone( /* reap children and free data */
+ int freall
+)
{
ray_pclose(0); /* close child processes */
@@ -430,9 +388,10 @@ int freall;
static void
-ray_pchild(fd_in, fd_out) /* process rays (never returns) */
-int fd_in;
-int fd_out;
+ray_pchild( /* process rays (never returns) */
+ int fd_in,
+ int fd_out
+)
{
int n;
register int i;
@@ -476,13 +435,14 @@ int fd_out;
}
-void
-ray_popen(nadd) /* open the specified # processes */
-int nadd;
+extern void
+ray_popen( /* open the specified # processes */
+ int nadd
+)
{
/* check if our table has room */
- if (ray_nprocs + nadd > MAX_NPROCS)
- nadd = MAX_NPROCS - ray_nprocs;
+ if (ray_pnprocs + nadd > MAX_NPROCS)
+ nadd = MAX_NPROCS - ray_pnprocs;
if (nadd <= 0)
return;
fflush(stderr); /* clear pending output */
@@ -491,9 +451,9 @@ int nadd;
int p0[2], p1[2];
if (pipe(p0) < 0 || pipe(p1) < 0)
error(SYSTEM, "cannot create pipe");
- if ((r_proc[ray_nprocs].pid = fork()) == 0) {
+ if ((r_proc[ray_pnprocs].pid = fork()) == 0) {
int pn; /* close others' descriptors */
- for (pn = ray_nprocs; pn--; ) {
+ for (pn = ray_pnprocs; pn--; ) {
close(r_proc[pn].fd_send);
close(r_proc[pn].fd_recv);
}
@@ -501,21 +461,22 @@ int nadd;
/* following call never returns */
ray_pchild(p1[0], p0[1]);
}
- if (r_proc[ray_nprocs].pid < 0)
+ if (r_proc[ray_pnprocs].pid < 0)
error(SYSTEM, "cannot fork child process");
close(p1[0]); close(p0[1]);
- r_proc[ray_nprocs].fd_send = p1[1];
- r_proc[ray_nprocs].fd_recv = p0[0];
- r_proc[ray_nprocs].npending = 0;
- ray_nprocs++;
- ray_idle++;
+ r_proc[ray_pnprocs].fd_send = p1[1];
+ r_proc[ray_pnprocs].fd_recv = p0[0];
+ r_proc[ray_pnprocs].npending = 0;
+ ray_pnprocs++;
+ ray_pnidle++;
}
}
-void
-ray_pclose(nsub) /* close one or more child processes */
-int nsub;
+extern void
+ray_pclose( /* close one or more child processes */
+ int nsub
+)
{
static int inclose = 0;
RAY res;
@@ -524,26 +485,26 @@ int nsub;
return;
inclose++;
/* check argument */
- if ((nsub <= 0 | nsub > ray_nprocs))
- nsub = ray_nprocs;
+ if ((nsub <= 0) | (nsub > ray_pnprocs))
+ nsub = ray_pnprocs;
/* clear our ray queue */
while (ray_presult(&res,0) > 0)
;
/* clean up children */
while (nsub--) {
int status;
- ray_nprocs--;
- close(r_proc[ray_nprocs].fd_recv);
- close(r_proc[ray_nprocs].fd_send);
- while (wait(&status) != r_proc[ray_nprocs].pid)
+ ray_pnprocs--;
+ close(r_proc[ray_pnprocs].fd_recv);
+ close(r_proc[ray_pnprocs].fd_send);
+ while (wait(&status) != r_proc[ray_pnprocs].pid)
;
if (status) {
sprintf(errmsg,
"rendering process %d exited with code %d",
- r_proc[ray_nprocs].pid, status>>8);
+ r_proc[ray_pnprocs].pid, status>>8);
error(WARNING, errmsg);
}
- ray_idle--;
+ ray_pnidle--;
}
inclose--;
}