Blame


1 76193d7c 2003-09-30 devnull #include "mk.h"
2 76193d7c 2003-09-30 devnull
3 76193d7c 2003-09-30 devnull typedef struct Event
4 76193d7c 2003-09-30 devnull {
5 76193d7c 2003-09-30 devnull int pid;
6 76193d7c 2003-09-30 devnull Job *job;
7 76193d7c 2003-09-30 devnull } Event;
8 76193d7c 2003-09-30 devnull static Event *events;
9 76193d7c 2003-09-30 devnull static int nevents, nrunning, nproclimit;
10 76193d7c 2003-09-30 devnull
11 76193d7c 2003-09-30 devnull typedef struct Process
12 76193d7c 2003-09-30 devnull {
13 76193d7c 2003-09-30 devnull int pid;
14 76193d7c 2003-09-30 devnull int status;
15 76193d7c 2003-09-30 devnull struct Process *b, *f;
16 76193d7c 2003-09-30 devnull } Process;
17 76193d7c 2003-09-30 devnull static Process *phead, *pfree;
18 76193d7c 2003-09-30 devnull static void sched(void);
19 76193d7c 2003-09-30 devnull static void pnew(int, int), pdelete(Process *);
20 76193d7c 2003-09-30 devnull
21 76193d7c 2003-09-30 devnull int pidslot(int);
22 76193d7c 2003-09-30 devnull
23 76193d7c 2003-09-30 devnull void
24 76193d7c 2003-09-30 devnull run(Job *j)
25 76193d7c 2003-09-30 devnull {
26 76193d7c 2003-09-30 devnull Job *jj;
27 76193d7c 2003-09-30 devnull
28 76193d7c 2003-09-30 devnull if(jobs){
29 76193d7c 2003-09-30 devnull for(jj = jobs; jj->next; jj = jj->next)
30 76193d7c 2003-09-30 devnull ;
31 76193d7c 2003-09-30 devnull jj->next = j;
32 fa325e9b 2020-01-10 cross } else
33 76193d7c 2003-09-30 devnull jobs = j;
34 76193d7c 2003-09-30 devnull j->next = 0;
35 76193d7c 2003-09-30 devnull /* this code also in waitup after parse redirect */
36 76193d7c 2003-09-30 devnull if(nrunning < nproclimit)
37 76193d7c 2003-09-30 devnull sched();
38 76193d7c 2003-09-30 devnull }
39 76193d7c 2003-09-30 devnull
40 76193d7c 2003-09-30 devnull static void
41 76193d7c 2003-09-30 devnull sched(void)
42 76193d7c 2003-09-30 devnull {
43 76193d7c 2003-09-30 devnull char *flags;
44 76193d7c 2003-09-30 devnull Job *j;
45 76193d7c 2003-09-30 devnull Bufblock *buf;
46 76193d7c 2003-09-30 devnull int slot;
47 76193d7c 2003-09-30 devnull Node *n;
48 76193d7c 2003-09-30 devnull Envy *e;
49 76193d7c 2003-09-30 devnull
50 76193d7c 2003-09-30 devnull if(jobs == 0){
51 76193d7c 2003-09-30 devnull usage();
52 76193d7c 2003-09-30 devnull return;
53 76193d7c 2003-09-30 devnull }
54 76193d7c 2003-09-30 devnull j = jobs;
55 76193d7c 2003-09-30 devnull jobs = j->next;
56 76193d7c 2003-09-30 devnull if(DEBUG(D_EXEC))
57 76193d7c 2003-09-30 devnull fprint(1, "firing up job for target %s\n", wtos(j->t, ' '));
58 76193d7c 2003-09-30 devnull slot = nextslot();
59 76193d7c 2003-09-30 devnull events[slot].job = j;
60 76193d7c 2003-09-30 devnull buf = newbuf();
61 76193d7c 2003-09-30 devnull e = buildenv(j, slot);
62 9aa1c92f 2005-01-04 devnull shprint(j->r->recipe, e, buf, j->r->shellt);
63 76193d7c 2003-09-30 devnull if(!tflag && (nflag || !(j->r->attr&QUIET)))
64 76193d7c 2003-09-30 devnull Bwrite(&bout, buf->start, (long)strlen(buf->start));
65 76193d7c 2003-09-30 devnull freebuf(buf);
66 76193d7c 2003-09-30 devnull if(nflag||tflag){
67 76193d7c 2003-09-30 devnull for(n = j->n; n; n = n->next){
68 76193d7c 2003-09-30 devnull if(tflag){
69 76193d7c 2003-09-30 devnull if(!(n->flags&VIRTUAL))
70 76193d7c 2003-09-30 devnull touch(n->name);
71 76193d7c 2003-09-30 devnull else if(explain)
72 76193d7c 2003-09-30 devnull Bprint(&bout, "no touch of virtual '%s'\n", n->name);
73 76193d7c 2003-09-30 devnull }
74 76193d7c 2003-09-30 devnull n->time = time((long *)0);
75 76193d7c 2003-09-30 devnull MADESET(n, MADE);
76 76193d7c 2003-09-30 devnull }
77 76193d7c 2003-09-30 devnull } else {
78 76193d7c 2003-09-30 devnull if(DEBUG(D_EXEC))
79 76193d7c 2003-09-30 devnull fprint(1, "recipe='%s'", j->r->recipe);/**/
80 76193d7c 2003-09-30 devnull Bflush(&bout);
81 76193d7c 2003-09-30 devnull if(j->r->attr&NOMINUSE)
82 76193d7c 2003-09-30 devnull flags = 0;
83 76193d7c 2003-09-30 devnull else
84 76193d7c 2003-09-30 devnull flags = "-e";
85 9aa1c92f 2005-01-04 devnull events[slot].pid = execsh(flags, j->r->recipe, 0, e, j->r->shellt, j->r->shellcmd);
86 76193d7c 2003-09-30 devnull usage();
87 76193d7c 2003-09-30 devnull nrunning++;
88 76193d7c 2003-09-30 devnull if(DEBUG(D_EXEC))
89 76193d7c 2003-09-30 devnull fprint(1, "pid for target %s = %d\n", wtos(j->t, ' '), events[slot].pid);
90 76193d7c 2003-09-30 devnull }
91 76193d7c 2003-09-30 devnull }
92 76193d7c 2003-09-30 devnull
93 76193d7c 2003-09-30 devnull int
94 76193d7c 2003-09-30 devnull waitup(int echildok, int *retstatus)
95 76193d7c 2003-09-30 devnull {
96 76193d7c 2003-09-30 devnull Envy *e;
97 76193d7c 2003-09-30 devnull int pid;
98 76193d7c 2003-09-30 devnull int slot;
99 76193d7c 2003-09-30 devnull Symtab *s;
100 76193d7c 2003-09-30 devnull Word *w;
101 76193d7c 2003-09-30 devnull Job *j;
102 76193d7c 2003-09-30 devnull char buf[ERRMAX];
103 76193d7c 2003-09-30 devnull Bufblock *bp;
104 76193d7c 2003-09-30 devnull int uarg = 0;
105 76193d7c 2003-09-30 devnull int done;
106 76193d7c 2003-09-30 devnull Node *n;
107 76193d7c 2003-09-30 devnull Process *p;
108 76193d7c 2003-09-30 devnull extern int runerrs;
109 76193d7c 2003-09-30 devnull
110 76193d7c 2003-09-30 devnull /* first check against the proces slist */
111 76193d7c 2003-09-30 devnull if(retstatus)
112 76193d7c 2003-09-30 devnull for(p = phead; p; p = p->f)
113 76193d7c 2003-09-30 devnull if(p->pid == *retstatus){
114 76193d7c 2003-09-30 devnull *retstatus = p->status;
115 76193d7c 2003-09-30 devnull pdelete(p);
116 76193d7c 2003-09-30 devnull return(-1);
117 76193d7c 2003-09-30 devnull }
118 76193d7c 2003-09-30 devnull again: /* rogue processes */
119 76193d7c 2003-09-30 devnull pid = waitfor(buf);
120 76193d7c 2003-09-30 devnull if(pid == -1){
121 76193d7c 2003-09-30 devnull if(echildok > 0)
122 76193d7c 2003-09-30 devnull return(1);
123 76193d7c 2003-09-30 devnull else {
124 76193d7c 2003-09-30 devnull fprint(2, "mk: (waitup %d): %r\n", echildok);
125 76193d7c 2003-09-30 devnull Exit();
126 76193d7c 2003-09-30 devnull }
127 76193d7c 2003-09-30 devnull }
128 76193d7c 2003-09-30 devnull if(DEBUG(D_EXEC))
129 76193d7c 2003-09-30 devnull fprint(1, "waitup got pid=%d, status='%s'\n", pid, buf);
130 76193d7c 2003-09-30 devnull if(retstatus && pid == *retstatus){
131 76193d7c 2003-09-30 devnull *retstatus = buf[0]? 1:0;
132 76193d7c 2003-09-30 devnull return(-1);
133 76193d7c 2003-09-30 devnull }
134 76193d7c 2003-09-30 devnull slot = pidslot(pid);
135 76193d7c 2003-09-30 devnull if(slot < 0){
136 76193d7c 2003-09-30 devnull if(DEBUG(D_EXEC))
137 76193d7c 2003-09-30 devnull fprint(2, "mk: wait returned unexpected process %d\n", pid);
138 76193d7c 2003-09-30 devnull pnew(pid, buf[0]? 1:0);
139 76193d7c 2003-09-30 devnull goto again;
140 76193d7c 2003-09-30 devnull }
141 76193d7c 2003-09-30 devnull j = events[slot].job;
142 76193d7c 2003-09-30 devnull usage();
143 76193d7c 2003-09-30 devnull nrunning--;
144 76193d7c 2003-09-30 devnull events[slot].pid = -1;
145 76193d7c 2003-09-30 devnull if(buf[0]){
146 76193d7c 2003-09-30 devnull e = buildenv(j, slot);
147 76193d7c 2003-09-30 devnull bp = newbuf();
148 9aa1c92f 2005-01-04 devnull shprint(j->r->recipe, e, bp, j->r->shellt);
149 76193d7c 2003-09-30 devnull front(bp->start);
150 76193d7c 2003-09-30 devnull fprint(2, "mk: %s: exit status=%s", bp->start, buf);
151 76193d7c 2003-09-30 devnull freebuf(bp);
152 76193d7c 2003-09-30 devnull for(n = j->n, done = 0; n; n = n->next)
153 76193d7c 2003-09-30 devnull if(n->flags&DELETE){
154 76193d7c 2003-09-30 devnull if(done++ == 0)
155 76193d7c 2003-09-30 devnull fprint(2, ", deleting");
156 76193d7c 2003-09-30 devnull fprint(2, " '%s'", n->name);
157 76193d7c 2003-09-30 devnull delete(n->name);
158 76193d7c 2003-09-30 devnull }
159 76193d7c 2003-09-30 devnull fprint(2, "\n");
160 76193d7c 2003-09-30 devnull if(kflag){
161 76193d7c 2003-09-30 devnull runerrs++;
162 76193d7c 2003-09-30 devnull uarg = 1;
163 76193d7c 2003-09-30 devnull } else {
164 76193d7c 2003-09-30 devnull jobs = 0;
165 76193d7c 2003-09-30 devnull Exit();
166 76193d7c 2003-09-30 devnull }
167 76193d7c 2003-09-30 devnull }
168 76193d7c 2003-09-30 devnull for(w = j->t; w; w = w->next){
169 76193d7c 2003-09-30 devnull if((s = symlook(w->s, S_NODE, 0)) == 0)
170 76193d7c 2003-09-30 devnull continue; /* not interested in this node */
171 3fe9465a 2006-04-20 devnull update(uarg, s->u.ptr);
172 76193d7c 2003-09-30 devnull }
173 76193d7c 2003-09-30 devnull if(nrunning < nproclimit)
174 76193d7c 2003-09-30 devnull sched();
175 76193d7c 2003-09-30 devnull return(0);
176 76193d7c 2003-09-30 devnull }
177 76193d7c 2003-09-30 devnull
178 76193d7c 2003-09-30 devnull void
179 76193d7c 2003-09-30 devnull nproc(void)
180 76193d7c 2003-09-30 devnull {
181 76193d7c 2003-09-30 devnull Symtab *sym;
182 76193d7c 2003-09-30 devnull Word *w;
183 76193d7c 2003-09-30 devnull
184 76193d7c 2003-09-30 devnull if(sym = symlook("NPROC", S_VAR, 0)) {
185 3fe9465a 2006-04-20 devnull w = sym->u.ptr;
186 76193d7c 2003-09-30 devnull if (w && w->s && w->s[0])
187 76193d7c 2003-09-30 devnull nproclimit = atoi(w->s);
188 76193d7c 2003-09-30 devnull }
189 76193d7c 2003-09-30 devnull if(nproclimit < 1)
190 76193d7c 2003-09-30 devnull nproclimit = 1;
191 76193d7c 2003-09-30 devnull if(DEBUG(D_EXEC))
192 76193d7c 2003-09-30 devnull fprint(1, "nprocs = %d\n", nproclimit);
193 76193d7c 2003-09-30 devnull if(nproclimit > nevents){
194 76193d7c 2003-09-30 devnull if(nevents)
195 76193d7c 2003-09-30 devnull events = (Event *)Realloc((char *)events, nproclimit*sizeof(Event));
196 76193d7c 2003-09-30 devnull else
197 76193d7c 2003-09-30 devnull events = (Event *)Malloc(nproclimit*sizeof(Event));
198 76193d7c 2003-09-30 devnull while(nevents < nproclimit)
199 76193d7c 2003-09-30 devnull events[nevents++].pid = 0;
200 76193d7c 2003-09-30 devnull }
201 76193d7c 2003-09-30 devnull }
202 76193d7c 2003-09-30 devnull
203 76193d7c 2003-09-30 devnull int
204 76193d7c 2003-09-30 devnull nextslot(void)
205 76193d7c 2003-09-30 devnull {
206 76193d7c 2003-09-30 devnull int i;
207 76193d7c 2003-09-30 devnull
208 76193d7c 2003-09-30 devnull for(i = 0; i < nproclimit; i++)
209 76193d7c 2003-09-30 devnull if(events[i].pid <= 0) return i;
210 76193d7c 2003-09-30 devnull assert("out of slots!!", 0);
211 76193d7c 2003-09-30 devnull return 0; /* cyntax */
212 76193d7c 2003-09-30 devnull }
213 76193d7c 2003-09-30 devnull
214 76193d7c 2003-09-30 devnull int
215 76193d7c 2003-09-30 devnull pidslot(int pid)
216 76193d7c 2003-09-30 devnull {
217 76193d7c 2003-09-30 devnull int i;
218 76193d7c 2003-09-30 devnull
219 76193d7c 2003-09-30 devnull for(i = 0; i < nevents; i++)
220 76193d7c 2003-09-30 devnull if(events[i].pid == pid) return(i);
221 76193d7c 2003-09-30 devnull if(DEBUG(D_EXEC))
222 76193d7c 2003-09-30 devnull fprint(2, "mk: wait returned unexpected process %d\n", pid);
223 76193d7c 2003-09-30 devnull return(-1);
224 76193d7c 2003-09-30 devnull }
225 76193d7c 2003-09-30 devnull
226 76193d7c 2003-09-30 devnull
227 76193d7c 2003-09-30 devnull static void
228 76193d7c 2003-09-30 devnull pnew(int pid, int status)
229 76193d7c 2003-09-30 devnull {
230 76193d7c 2003-09-30 devnull Process *p;
231 76193d7c 2003-09-30 devnull
232 76193d7c 2003-09-30 devnull if(pfree){
233 76193d7c 2003-09-30 devnull p = pfree;
234 76193d7c 2003-09-30 devnull pfree = p->f;
235 76193d7c 2003-09-30 devnull } else
236 76193d7c 2003-09-30 devnull p = (Process *)Malloc(sizeof(Process));
237 76193d7c 2003-09-30 devnull p->pid = pid;
238 76193d7c 2003-09-30 devnull p->status = status;
239 76193d7c 2003-09-30 devnull p->f = phead;
240 76193d7c 2003-09-30 devnull phead = p;
241 76193d7c 2003-09-30 devnull if(p->f)
242 76193d7c 2003-09-30 devnull p->f->b = p;
243 76193d7c 2003-09-30 devnull p->b = 0;
244 76193d7c 2003-09-30 devnull }
245 76193d7c 2003-09-30 devnull
246 76193d7c 2003-09-30 devnull static void
247 76193d7c 2003-09-30 devnull pdelete(Process *p)
248 76193d7c 2003-09-30 devnull {
249 76193d7c 2003-09-30 devnull if(p->f)
250 76193d7c 2003-09-30 devnull p->f->b = p->b;
251 76193d7c 2003-09-30 devnull if(p->b)
252 76193d7c 2003-09-30 devnull p->b->f = p->f;
253 76193d7c 2003-09-30 devnull else
254 76193d7c 2003-09-30 devnull phead = p->f;
255 76193d7c 2003-09-30 devnull p->f = pfree;
256 76193d7c 2003-09-30 devnull pfree = p;
257 76193d7c 2003-09-30 devnull }
258 76193d7c 2003-09-30 devnull
259 76193d7c 2003-09-30 devnull void
260 76193d7c 2003-09-30 devnull killchildren(char *msg)
261 76193d7c 2003-09-30 devnull {
262 76193d7c 2003-09-30 devnull Process *p;
263 76193d7c 2003-09-30 devnull
264 76193d7c 2003-09-30 devnull kflag = 1; /* to make sure waitup doesn't exit */
265 76193d7c 2003-09-30 devnull jobs = 0; /* make sure no more get scheduled */
266 76193d7c 2003-09-30 devnull for(p = phead; p; p = p->f)
267 76193d7c 2003-09-30 devnull expunge(p->pid, msg);
268 76193d7c 2003-09-30 devnull while(waitup(1, (int *)0) == 0)
269 76193d7c 2003-09-30 devnull ;
270 76193d7c 2003-09-30 devnull Bprint(&bout, "mk: %s\n", msg);
271 76193d7c 2003-09-30 devnull Exit();
272 76193d7c 2003-09-30 devnull }
273 76193d7c 2003-09-30 devnull
274 76193d7c 2003-09-30 devnull static long tslot[1000];
275 76193d7c 2003-09-30 devnull static long tick;
276 76193d7c 2003-09-30 devnull
277 76193d7c 2003-09-30 devnull void
278 76193d7c 2003-09-30 devnull usage(void)
279 76193d7c 2003-09-30 devnull {
280 76193d7c 2003-09-30 devnull long t;
281 76193d7c 2003-09-30 devnull
282 76193d7c 2003-09-30 devnull time(&t);
283 76193d7c 2003-09-30 devnull if(tick)
284 76193d7c 2003-09-30 devnull tslot[nrunning] += (t-tick);
285 76193d7c 2003-09-30 devnull tick = t;
286 76193d7c 2003-09-30 devnull }
287 76193d7c 2003-09-30 devnull
288 76193d7c 2003-09-30 devnull void
289 76193d7c 2003-09-30 devnull prusage(void)
290 76193d7c 2003-09-30 devnull {
291 76193d7c 2003-09-30 devnull int i;
292 76193d7c 2003-09-30 devnull
293 76193d7c 2003-09-30 devnull usage();
294 76193d7c 2003-09-30 devnull for(i = 0; i <= nevents; i++)
295 76193d7c 2003-09-30 devnull fprint(1, "%d: %ld\n", i, tslot[i]);
296 76193d7c 2003-09-30 devnull }