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'\n", 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) ", echildok);
130 fprint(1, "waitup got pid=%d, status='%s'\n", pid, buf);
131 if(retstatus && pid == *retstatus){
132 *retstatus = buf[0]? 1:0;
138 fprint(2, "mk: wait returned unexpected process %d\n", pid);
139 pnew(pid, buf[0]? 1:0);
142 j = events[slot].job;
145 events[slot].pid = -1;
147 e = buildenv(j, slot);
149 shprint(j->r->recipe, e, bp);
151 fprint(2, "mk: %s: exit status=%s", bp->start, buf);
153 for(n = j->n, done = 0; n; n = n->next)
156 fprint(2, ", deleting");
157 fprint(2, " '%s'", n->name);
169 for(w = j->t; w; w = w->next){
170 if((s = symlook(w->s, S_NODE, 0)) == 0)
171 continue; /* not interested in this node */
172 update(uarg, s->u.ptr);
174 if(nrunning < nproclimit)
185 if(sym = symlook("NPROC", S_VAR, 0)) {
187 if (w && w->s && w->s[0])
188 nproclimit = atoi(w->s);
193 fprint(1, "nprocs = %d\n", nproclimit);
194 if(nproclimit > nevents){
196 events = (Event *)Realloc((char *)events, nproclimit*sizeof(Event));
198 events = (Event *)Malloc(nproclimit*sizeof(Event));
199 while(nevents < nproclimit)
200 events[nevents++].pid = 0;
209 for(i = 0; i < nproclimit; i++)
210 if(events[i].pid <= 0) return i;
211 assert(/*out of slots!!*/ 0);
212 return 0; /* cyntax */
220 for(i = 0; i < nevents; i++)
221 if(events[i].pid == pid) return(i);
223 fprint(2, "mk: wait returned unexpected process %d\n", pid);
229 pnew(int pid, int status)
237 p = (Process *)Malloc(sizeof(Process));
261 killchildren(char *msg)
265 kflag = 1; /* to make sure waitup doesn't exit */
266 jobs = 0; /* make sure no more get scheduled */
267 for(p = phead; p; p = p->f)
268 expunge(p->pid, msg);
269 while(waitup(1, (int *)0) == 0)
271 Bprint(&bout, "mk: %s\n", msg);
275 static long tslot[1000];
285 tslot[nrunning] += (t-tick);
295 for(i = 0; i <= nevents; i++)
296 fprint(1, "%d: %ld\n", i, tslot[i]);