9 static int nevents, nrunning, nproclimit;
11 typedef struct Process
15 struct Process *b, *f;
17 static Process *phead, *pfree;
18 static void sched(void);
19 static void pnew(int, int), pdelete(Process *);
29 for(jj = jobs; jj->next; jj = jj->next)
35 /* this code also in waitup after parse redirect */
36 if(nrunning < nproclimit)
57 fprint(1, "firing up job for target %s\n", wtos(j->t, ' '));
61 e = buildenv(j, slot);
62 shprint(j->r->recipe, e, buf);
63 if(!tflag && (nflag || !(j->r->attr&QUIET)))
64 Bwrite(&bout, buf->start, (long)strlen(buf->start));
67 for(n = j->n; n; n = n->next){
69 if(!(n->flags&VIRTUAL))
72 Bprint(&bout, "no touch of virtual '%s'\n", n->name);
74 n->time = time((long *)0);
79 fprint(1, "recipe='%s'", j->r->recipe);/**/
81 if(j->r->attr&NOMINUSE)
85 events[slot].pid = execsh(flags, j->r->recipe, 0, e);
89 fprint(1, "pid for target %s = %d\n", wtos(j->t, ' '), events[slot].pid);
94 waitup(int echildok, int *retstatus)
110 /* first check against the proces slist */
112 for(p = phead; p; p = p->f)
113 if(p->pid == *retstatus){
114 *retstatus = p->status;
118 again: /* rogue processes */
124 fprint(2, "mk: (waitup %d): %r\n", echildok);
129 fprint(1, "waitup got pid=%d, status='%s'\n", pid, buf);
130 if(retstatus && pid == *retstatus){
131 *retstatus = buf[0]? 1:0;
137 fprint(2, "mk: wait returned unexpected process %d\n", pid);
138 pnew(pid, buf[0]? 1:0);
141 j = events[slot].job;
144 events[slot].pid = -1;
146 e = buildenv(j, slot);
148 shprint(j->r->recipe, e, bp);
150 fprint(2, "mk: %s: exit status=%s", bp->start, buf);
152 for(n = j->n, done = 0; n; n = n->next)
155 fprint(2, ", deleting");
156 fprint(2, " '%s'", n->name);
168 for(w = j->t; w; w = w->next){
169 if((s = symlook(w->s, S_NODE, 0)) == 0)
170 continue; /* not interested in this node */
171 update(uarg, (Node *)s->value);
173 if(nrunning < nproclimit)
184 if(sym = symlook("NPROC", S_VAR, 0)) {
185 w = (Word *) sym->value;
186 if (w && w->s && w->s[0])
187 nproclimit = atoi(w->s);
192 fprint(1, "nprocs = %d\n", nproclimit);
193 if(nproclimit > nevents){
195 events = (Event *)Realloc((char *)events, nproclimit*sizeof(Event));
197 events = (Event *)Malloc(nproclimit*sizeof(Event));
198 while(nevents < nproclimit)
199 events[nevents++].pid = 0;
208 for(i = 0; i < nproclimit; i++)
209 if(events[i].pid <= 0) return i;
210 assert("out of slots!!", 0);
211 return 0; /* cyntax */
219 for(i = 0; i < nevents; i++)
220 if(events[i].pid == pid) return(i);
222 fprint(2, "mk: wait returned unexpected process %d\n", pid);
228 pnew(int pid, int status)
236 p = (Process *)Malloc(sizeof(Process));
260 killchildren(char *msg)
264 kflag = 1; /* to make sure waitup doesn't exit */
265 jobs = 0; /* make sure no more get scheduled */
266 for(p = phead; p; p = p->f)
267 expunge(p->pid, msg);
268 while(waitup(1, (int *)0) == 0)
270 Bprint(&bout, "mk: %s\n", msg);
274 static long tslot[1000];
284 tslot[nrunning] += (t-tick);
294 for(i = 0; i <= nevents; i++)
295 fprint(1, "%d: %ld\n", i, tslot[i]);