ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo2l.c
Revision: 3.9
Committed: Fri Dec 12 11:13:17 1997 UTC (26 years, 4 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 3.8: +25 -23 lines
Log Message:
implemented kill, clobber and restart commands

File Contents

# User Rev Content
1 gregl 3.1 /* Copyright (c) 1997 Silicon Graphics, Inc. */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ SGI";
5     #endif
6    
7     /*
8     * Routines for local rtrace execution
9     */
10    
11     #include "rholo.h"
12     #include "random.h"
13 gregl 3.6 #include "paths.h"
14 gregl 3.3 #include "selcall.h"
15 gregl 3.1 #include <signal.h>
16     #include <sys/time.h>
17    
18     #ifndef MAXPROC
19 gregl 3.8 #define MAXPROC 64
20 gregl 3.1 #endif
21    
22 gregl 3.8 int nprocs = 0; /* running process count */
23    
24 gregl 3.6 static char pfile[] = TEMPLATE; /* persist file name */
25 gregl 3.1
26     static int rtpd[MAXPROC][3]; /* process descriptors */
27     static float *rtbuf = NULL; /* allocated i/o buffer */
28     static int maxqlen = 0; /* maximum packets per queue */
29    
30     static PACKET *pqueue[MAXPROC]; /* packet queues */
31     static int pqlen[MAXPROC]; /* packet queue lengths */
32    
33    
34     int
35     start_rtrace() /* start rtrace process */
36     {
37     static char buf1[8];
38     int rmaxpack = 0;
39 gregl 3.9 int psiz, n;
40 gregl 3.1 /* get number of processes */
41 gregl 3.9 if (ncprocs <= 0)
42 gregl 3.1 return(0);
43 gregl 3.9 if (ncprocs > MAXPROC) {
44 gregl 3.1 sprintf(errmsg,
45     "number of rtrace processes reduced from %d to %d",
46 gregl 3.9 ncprocs, MAXPROC);
47 gregl 3.1 error(WARNING, errmsg);
48 gregl 3.9 ncprocs = MAXPROC;
49 gregl 3.1 }
50 gregl 3.9 if (rtargv[rtargc-1] != vval(OCTREE)) {
51     /* add compulsory options */
52     rtargv[rtargc++] = "-i-";
53     rtargv[rtargc++] = "-I-";
54     rtargv[rtargc++] = "-h-";
55     rtargv[rtargc++] = "-ld-";
56     sprintf(buf1, "%d", RPACKSIZ);
57     rtargv[rtargc++] = "-x"; rtargv[rtargc++] = buf1;
58     rtargv[rtargc++] = "-y"; rtargv[rtargc++] = "0";
59     rtargv[rtargc++] = "-fff";
60     rtargv[rtargc++] = vbool(VDIST) ? "-ovl" : "-ovL";
61     if (nowarn)
62     rtargv[rtargc++] = "-w-";
63     if (ncprocs > 1) {
64     mktemp(pfile);
65     rtargv[rtargc++] = "-PP"; rtargv[rtargc++] = pfile;
66     }
67     rtargv[rtargc++] = vval(OCTREE);
68     rtargv[rtargc] = NULL;
69 gregl 3.1 }
70     maxqlen = 0;
71 gregl 3.9 for (nprocs = 0; nprocs < ncprocs; nprocs++) { /* spawn children */
72 gregl 3.1 psiz = open_process(rtpd[nprocs], rtargv);
73     if (psiz <= 0)
74     error(SYSTEM, "cannot start rtrace process");
75     n = psiz/(RPACKSIZ*6*sizeof(float));
76     if (maxqlen == 0) {
77     if (!(maxqlen = n))
78     error(INTERNAL,
79     "bad pipe buffer size assumption");
80     } else if (n != maxqlen)
81     error(INTERNAL, "varying pipe buffer size!");
82     rmaxpack += n;
83     }
84     rtbuf = (float *)malloc(RPACKSIZ*6*sizeof(float)*maxqlen);
85     if (rtbuf == NULL)
86     error(SYSTEM, "malloc failure in start_rtrace");
87     return(rmaxpack);
88     }
89    
90    
91     static int
92     bestout() /* get best process to process packet */
93     {
94     int cnt;
95     register int pn, i;
96    
97     pn = 0; /* find shortest queue */
98     for (i = 1; i < nprocs; i++)
99     if (pqlen[i] < pqlen[pn])
100     pn = i;
101     /* sanity check */
102     if (pqlen[pn] == maxqlen)
103     return(-1);
104     cnt = 0; /* count number of ties */
105     for (i = pn; i < nprocs; i++)
106     if (pqlen[i] == pqlen[pn])
107     cnt++;
108     /* break ties fairly */
109     if ((cnt = random() % cnt))
110     for (i = pn; i < nprocs; i++)
111     if (pqlen[i] == pqlen[pn] && !cnt--)
112     return(i);
113     return(pn);
114     }
115    
116    
117     int
118     slots_avail() /* count packet slots available */
119     {
120     register int nslots = 0;
121     register int i;
122    
123     for (i = nprocs; i--; )
124     nslots += maxqlen - pqlen[i];
125     return(nslots);
126     }
127    
128    
129     queue_packet(p) /* queue up a beam packet */
130     register PACKET *p;
131     {
132     int pn, n;
133     /* determine process to write to */
134     if ((pn = bestout()) < 0)
135     error(INTERNAL, "rtrace input queues are full!");
136     /* write out the packet */
137     packrays(rtbuf, p);
138     if ((n = p->nr) < RPACKSIZ) /* add flush block? */
139     bzero((char *)(rtbuf+6*n++), 6*sizeof(float));
140     if (writebuf(rtpd[pn][1], (char *)rtbuf, 6*sizeof(float)*n) < 0)
141     error(SYSTEM, "write error in queue_packet");
142     p->next = NULL;
143     if (!pqlen[pn]++) /* add it to the end of the queue */
144     pqueue[pn] = p;
145     else {
146     register PACKET *rpl = pqueue[pn];
147     while (rpl->next != NULL)
148     rpl = rpl->next;
149     rpl->next = p;
150     }
151     }
152    
153    
154     PACKET *
155     get_packets(poll) /* read packets from rtrace processes */
156     int poll;
157     {
158     static struct timeval tpoll; /* zero timeval struct */
159     fd_set readset, errset;
160     PACKET *pldone = NULL, *plend;
161     register PACKET *p;
162     int n, nr;
163     register int pn;
164     float *bp;
165     /* prepare select call */
166     FD_ZERO(&readset); FD_ZERO(&errset); n = 0;
167     for (pn = nprocs; pn--; ) {
168     if (pqlen[pn])
169     FD_SET(rtpd[pn][0], &readset);
170     FD_SET(rtpd[pn][0], &errset);
171     if (rtpd[pn][0] >= n)
172     n = rtpd[pn][0] + 1;
173     }
174     /* make the call */
175     n = select(n, &readset, (fd_set *)NULL, &errset,
176     poll ? &tpoll : (struct timeval *)NULL);
177     if (n < 0) {
178     if (errno == EINTR) /* interrupted select call */
179     return(NULL);
180     error(SYSTEM, "select call failure in get_packets");
181     }
182     if (n == 0) /* is nothing ready? */
183     return(NULL);
184     /* make read call(s) */
185     for (pn = 0; pn < nprocs; pn++) {
186     if (!FD_ISSET(rtpd[pn][0], &readset) &&
187     !FD_ISSET(rtpd[pn][0], &errset))
188     continue;
189     reread:
190     n = read(rtpd[pn][0], (char *)rtbuf,
191     4*sizeof(float)*RPACKSIZ*pqlen[pn]);
192     if (n < 0) {
193     if (errno == EINTR | errno == EAGAIN)
194     goto reread;
195     error(SYSTEM, "read error in get_packets");
196     }
197     if (n == 0)
198     goto eoferr;
199     bp = rtbuf; /* finish processing */
200     for (p = pqueue[pn]; n && p != NULL; p = p->next) {
201     if ((nr = p->nr) < RPACKSIZ)
202     nr++; /* add flush block */
203     n -= 4*sizeof(float)*nr;
204     if (n < 0) { /* get remainder */
205     n += readbuf(rtpd[pn][0],
206     (char *)(bp+4*nr)+n, -n);
207     if (n)
208     goto eoferr;
209     }
210     donerays(p, bp);
211     bp += 4*nr;
212     pqlen[pn]--;
213     }
214     if (n) /* read past end? */
215     error(INTERNAL, "packet sync error in get_packets");
216     /* take from queue */
217 gregl 3.2 if (pldone == NULL)
218 gregl 3.1 pldone = plend = pqueue[pn];
219     else
220     plend->next = pqueue[pn];
221     while (plend->next != p)
222     plend = plend->next;
223     plend->next = NULL;
224     pqueue[pn] = p;
225     }
226     return(pldone); /* return finished packets */
227     eoferr:
228 gregl 3.3 error(USER, "rtrace process died");
229 gregl 3.1 }
230    
231    
232     PACKET *
233     do_packets(pl) /* queue a packet list, return finished */
234     register PACKET *pl;
235     {
236     register PACKET *p;
237     /* consistency check */
238     if (nprocs < 1)
239     error(CONSISTENCY, "do_packets called with no active process");
240     /* queue each new packet */
241     while (pl != NULL) {
242     p = pl; pl = p->next; p->next = NULL;
243     queue_packet(p);
244     }
245     return(get_packets(slots_avail())); /* return processed packets */
246     }
247    
248    
249     PACKET *
250     flush_queue() /* empty all rtrace queues */
251     {
252     PACKET *rpdone = NULL;
253     register PACKET *rpl;
254     float *bp;
255     register PACKET *p;
256     int i, n, nr;
257    
258     for (i = 0; i < nprocs; i++)
259     if (pqlen[i]) {
260     if (rpdone == NULL) { /* tack on queue */
261     rpdone = rpl = pqueue[i];
262 gregl 3.4 if ((nr = rpl->nr) < RPACKSIZ) nr++;
263 gregl 3.1 } else {
264     rpl->next = pqueue[i];
265 gregl 3.2 nr = 0;
266 gregl 3.1 }
267 gregl 3.2 while (rpl->next != NULL) {
268     nr += (rpl = rpl->next)->nr;
269     if (rpl->nr < RPACKSIZ)
270     nr++; /* add flush block */
271     }
272 gregl 3.1 n = readbuf(rtpd[i][0], (char *)rtbuf,
273 gregl 3.2 4*sizeof(float)*nr);
274 gregl 3.1 if (n < 0)
275     error(SYSTEM, "read failure in flush_queue");
276     bp = rtbuf; /* process packets */
277     for (p = pqueue[i]; p != NULL; p = p->next) {
278     if ((nr = p->nr) < RPACKSIZ)
279     nr++; /* add flush block */
280     n -= 4*sizeof(float)*nr;
281     if (n >= 0)
282     donerays(p, bp);
283     else
284     p->nr = 0; /* short data error */
285     bp += 4*nr;
286     }
287     pqueue[i] = NULL; /* zero this queue */
288     pqlen[i] = 0;
289     }
290     return(rpdone); /* return all packets completed */
291     }
292    
293    
294     static
295     killpersist() /* kill persistent process */
296     {
297     FILE *fp;
298     int pid;
299    
300 gregl 3.6 if ((fp = fopen(pfile, "r")) == NULL)
301 gregl 3.1 return;
302     if (fscanf(fp, "%*s %d", &pid) != 1 || kill(pid, SIGALRM) < 0)
303 gregl 3.6 unlink(pfile);
304 gregl 3.1 fclose(fp);
305     }
306    
307    
308     int
309     end_rtrace() /* close rtrace process(es) */
310     {
311     int status = 0, rv;
312    
313     if (nprocs > 1)
314     killpersist();
315     while (nprocs > 0) {
316     rv = close_process(rtpd[--nprocs]);
317     if (rv > 0)
318     status = rv;
319     }
320     free((char *)rtbuf);
321     rtbuf = NULL;
322     maxqlen = 0;
323     return(status);
324     }