Annotation of researchv10no/cmd/mk/src/run.c, revision 1.1.1.1

1.1       root        1: #include       "mk.h"
                      2: 
                      3: typedef struct Event
                      4: {
                      5:        int pid;
                      6:        Job *job;
                      7: } Event;
                      8: static Event *events;
                      9: static int nevents, nrunning;
                     10: typedef struct Process
                     11: {
                     12:        int pid;
                     13:        int status;
                     14:        struct Process *b, *f;
                     15: } Process;
                     16: static Process *phead, *pfree;
                     17: static void pnew(), pdelete();
                     18: static char *envy[1024];
                     19: static char **special;
                     20: static pidslot();
                     21: 
                     22: run(j)
                     23:        Job *j;
                     24: {
                     25:        register Job *jj;
                     26: 
                     27:        if(jobs){
                     28:                for(jj = jobs; jj->next; jj = jj->next)
                     29:                        ;
                     30:                jj->next = j;
                     31:        } else 
                     32:                jobs = j;
                     33:        j->next = 0;
                     34:        /* this code also in waitup after parse redirect */
                     35:        if(nrunning < nproclimit)
                     36:                sched();
                     37: }
                     38: 
                     39: sched()
                     40: {
                     41:        register Job *j;
                     42:        char buf[BIGBLOCK];
                     43:        int slot, pip[2], pid;
                     44:        Node *n;
                     45: 
                     46:        if(jobs == 0){
                     47:                account();
                     48:                return;
                     49:        }
                     50:        j = jobs;
                     51:        jobs = j->next;
                     52:        if(DEBUG(D_EXEC))
                     53:                fprint(1, "firing up job for target %s\n", wtos(j->t));
                     54:        slot = nextslot();
                     55:        events[slot].job = j;
                     56:        dovars(j, slot);
                     57:        shprint(j->r->recipe, envy, buf);
                     58:        if(!tflag && !mflag && (nflag || !(j->r->attr&QUIET)))
                     59:                Fwrite(1, buf, (long)strlen(buf));
                     60:        if(mflag){
                     61:                for(n = j->n; n; n = n->next)
                     62:                        symlook(n->name, S_MAKEFILE, (char *)j);
                     63:        }
                     64:        if(nflag||tflag){
                     65:                for(n = j->n; n; n = n->next){
                     66:                        if(tflag){
                     67:                                if(!(n->flags&VIRTUAL))
                     68:                                        touch(n->name);
                     69:                                else if(explain)
                     70:                                        Fprint(1, "no touch of virtual '%s'\n", n->name);
                     71:                        }
                     72:                        n->time = time((long *)0);
                     73:                        MADESET(n, MADE);
                     74:                }
                     75:        } else {
                     76:                Fexit(0);
                     77:                if(j->r->attr&RED){
                     78:                        if(pipe(pip) < 0){
                     79:                                perror("pipe");
                     80:                                Exit();
                     81:                        }
                     82:                }
                     83:                if((pid = fork()) < 0){
                     84:                        perror("mk fork");
                     85:                        Exit();
                     86:                }
                     87:                if(pid == 0){
                     88:                        if(j->r->attr&RED){
                     89:                                close(pip[0]);
                     90:                                dup2(pip[1], 1);
                     91:                                close(pip[1]);
                     92:                        }
                     93:                        if(pipe(pip) < 0){
                     94:                                perror("pipe-i");
                     95:                                Exit();
                     96:                        }
                     97:                        if((pid = fork()) < 0){
                     98:                                perror("mk fork");
                     99:                                Exit();
                    100:                        }
                    101:                        if(pid != 0){
                    102:                                close(pip[1]);
                    103:                                dup2(pip[0], 0);
                    104:                                close(pip[0]);
                    105:                                execle(SHELL, "sh", "-e", (char *)0, envy);
                    106:                                perror(SHELL);
                    107:                                _exit(1);
                    108:                        } else {
                    109:                                int k;
                    110:                                char *s, *send;
                    111: 
                    112:                                close(pip[0]);
                    113:                                s = j->r->recipe;
                    114:                                send = s+strlen(s);
                    115:                                while(s < send){
                    116:                                        if((k = write(pip[1], s, send-s)) < 0)
                    117:                                                break;
                    118:                                        s += k;
                    119:                                }
                    120:                                _exit(0);
                    121:                        }
                    122:                }
                    123:                account();
                    124:                nrunning++;
                    125:                if(j->r->attr&RED)
                    126:                        close(pip[1]), j->fd = pip[0];
                    127:                else
                    128:                        j->fd = -1;
                    129:                if(DEBUG(D_EXEC))
                    130:                        fprint(1, "pid for target %s = %d\n", wtos(j->t), pid);
                    131:                events[slot].pid = pid;
                    132:        }
                    133: }
                    134: 
                    135: waitup(echildok, retstatus)
                    136:        int *retstatus;
                    137: {
                    138:        int status, pid;
                    139:        int slot;
                    140:        Symtab *s;
                    141:        Word *w;
                    142:        Job *j;
                    143:        char buf[64];
                    144:        char buf1[BIGBLOCK];
                    145:        int uarg = 0;
                    146:        int done;
                    147:        Node *n;
                    148:        Process *p;
                    149:        extern int errno, runerrs;
                    150: 
                    151:        /* first check against the proces slist */
                    152:        if(retstatus)
                    153:                for(p = phead; p; p = p->f)
                    154:                        if(p->pid == *retstatus){
                    155:                                *retstatus = p->status;
                    156:                                pdelete(p);
                    157:                                return(-1);
                    158:                        }
                    159: again:         /* rogue processes */
                    160:        if((pid = wait(&status)) < 0){
                    161:                if(echildok > 0){
                    162:                        return(1);
                    163:                } else {
                    164:                        fprint(2, "mk: (waitup %d) ", echildok);
                    165:                        perror("mk wait");
                    166:                        Exit();
                    167:                }
                    168:        }
                    169:        if(DEBUG(D_EXEC))
                    170:                fprint(1, "waitup got pid=%d, status=0x%ux\n", pid, status);
                    171:        if(retstatus && (pid == *retstatus)){
                    172:                *retstatus = status;
                    173:                return(-1);
                    174:        }
                    175:        slot = pidslot(pid);
                    176:        if(slot < 0){
                    177:                if(DEBUG(D_EXEC))
                    178:                        fprint(2, "mk: wait returned unexpected process %d\n", pid);
                    179:                pnew(pid, status);
                    180:                goto again;
                    181:        }
                    182:        j = events[slot].job;
                    183:        account();
                    184:        nrunning--;
                    185:        events[slot].pid = -1;
                    186:        if(status){
                    187:                dovars(j, slot);
                    188:                shprint(j->r->recipe, envy, buf1);
                    189:                front(buf1);
                    190:                Fprint(2, "mk: %s: exit status=%d", buf1, 0xFF&(status>>8));
                    191:                status &= 0xFF;
                    192:                if(status&0x7F)
                    193:                        Fprint(2, " signal=%d", status&0x7F);
                    194:                if(status&0x80)
                    195:                        Fprint(2, ", core dumped");
                    196:                for(n = j->n, done = 0; n; n = n->next)
                    197:                        if(n->flags&DELETE){
                    198:                                if(done++ == 0)
                    199:                                        Fprint(2, ", deleting");
                    200:                                Fprint(2, " '%s'", n->name);
                    201:                        }
                    202:                Fputc(2, '\n');
                    203:                for(n = j->n, done = 0; n; n = n->next)
                    204:                        if(n->flags&DELETE){
                    205:                                if(done++ == 0)
                    206:                                        Fflush(2);
                    207:                                delete(n->name);
                    208:                        }
                    209:                if(kflag){
                    210:                        runerrs++;
                    211:                        uarg = 1;
                    212:                        Fflush(2);
                    213:                } else {
                    214:                        jobs = 0;
                    215:                        Exit();
                    216:                }
                    217:        }
                    218:        if(j->fd >= 0){
                    219:                sprint(buf, "process %d", pid);
                    220:                parse(buf, j->fd, 0, 0);
                    221:                execinit();     /* reread environ */
                    222:                nproc();
                    223:                while(jobs && (nrunning < nproclimit))
                    224:                        sched();
                    225:        }
                    226:        for(w = j->t; w; w = w->next){
                    227:                if((s = symlook(w->s, S_NODE, (char *)0)) == 0)
                    228:                        continue;       /* not interested in this node */
                    229:                update(uarg, (Node *)s->value);
                    230:        }
                    231:        if(nrunning < nproclimit)
                    232:                sched();
                    233:        return(0);
                    234: }
                    235: 
                    236: execinit()
                    237: {
                    238:        extern char **environ;
                    239:        extern char **vardump();
                    240:        register char *s, *ss, c;
                    241:        Symtab *st;
                    242: 
                    243:        environ = envy;
                    244:        special = vardump(envy);
                    245:        if(st = symlook("ENVIRON", S_VAR, (char *)0))
                    246:                for(s = st->value; *s;){
                    247:                        for(ss = s; *ss && (*ss != 1); ss++);
                    248:                        c = *ss;
                    249:                        *ss = 0;
                    250:                        *special++ = strdup(s);
                    251:                        s = ss;
                    252:                        if(*ss = c)
                    253:                                s++;
                    254:                }
                    255:        *special = 0;
                    256: }
                    257: 
                    258: char *myenv[] =
                    259: {
                    260:        "target", "stem", "prereq", "pid", "nproc", "newprereq",
                    261:        "alltarget",
                    262:        "stem1", "stem2", "stem3", "stem4", "stem5", "stem6",
                    263:        "stem7", "stem8", "stem9", "stem0", 0
                    264: };
                    265: 
                    266: dovars(j, slot)
                    267:        register Job *j;
                    268: {
                    269:        char buf[BIGBLOCK];
                    270:        char *s, *t;
                    271:        int i, n = 0;
                    272: 
                    273: #define        SPECIAL ((sizeof myenv)/(sizeof myenv[0])-1)
                    274: #define        VSET(name, exp) {strcpy(buf, "name="); strcpy(strchr(buf, 0), exp);}
                    275: 
                    276:        for(i = 0; i < SPECIAL; i++)
                    277:                if(special[i])
                    278:                        free(special[i]);
                    279:        VSET(target, s = wtos(j->t));
                    280:        special[n++] = strdup(buf);
                    281:        free(s);
                    282:        /* WATCH OUT; stem set below if reg exp!! */
                    283:        VSET(stem, j->stem);
                    284:        special[n++] = strdup(buf);
                    285:        VSET(prereq, s = wtos(j->p));
                    286:        special[n++] = strdup(buf);
                    287:        free(s);
                    288:        sprint(buf, "pid=%d", getpid());
                    289:        special[n++] = strdup(buf);
                    290:        sprint(buf, "nproc=%d", slot);
                    291:        special[n++] = strdup(buf);
                    292:        VSET(newprereq, s = wtos(j->np));
                    293:        special[n++] = strdup(buf);
                    294:        free(s);
                    295:        VSET(alltarget, s = wtos(j->at));
                    296:        special[n++] = strdup(buf);
                    297:        free(s);
                    298:        for(i = 0; i <= 9; i++){
                    299:                sprint(buf, "stem%d=", i);
                    300:                if(j->r->attr&REGEXP){
                    301:                        for(s = buf; *s; s++);
                    302:                        for(t = j->match[i].sp; t < j->match[i].ep; *s++ = *t++);
                    303:                        *s = 0;
                    304:                }
                    305:                special[n+i] = strdup(buf);
                    306:                if((i == 1) && (j->r->attr&REGEXP)){
                    307:                        buf[1] = 's'; buf[2] = 't'; buf[3] = 'e'; buf[4] = 'm';
                    308:                        special[1] = strdup(buf+1);
                    309:                }
                    310:        }
                    311:        special[SPECIAL] = 0;
                    312: }
                    313: 
                    314: nproc()
                    315: {
                    316:        register Symtab *sym;
                    317: 
                    318:        if(sym = symlook("NPROC", S_VAR, (char *)0))
                    319:                nproclimit = atoi(sym->value);
                    320:        if(nproclimit < 1)
                    321:                nproclimit = 1;
                    322:        if(DEBUG(D_EXEC))
                    323:                fprint(1, "nprocs = %d\n", nproclimit);
                    324:        if(nproclimit > nevents){
                    325:                if(nevents)
                    326:                        events = (Event *)realloc((char *)events, nproclimit*sizeof(Event));
                    327:                else
                    328:                        events = (Event *)malloc(nproclimit*sizeof(Event));
                    329:                while(nevents < nproclimit)
                    330:                        events[nevents++].pid = 0;
                    331:        }
                    332: }
                    333: 
                    334: nextslot()
                    335: {
                    336:        register i;
                    337: 
                    338:        for(i = 0; i < nproclimit; i++)
                    339:                if(events[i].pid <= 0) return(i);
                    340:        assert("out of slots!!", 0);
                    341:        return(0);      /* cyntax */
                    342: }
                    343: 
                    344: static
                    345: pidslot(pid)
                    346: {
                    347:        register i;
                    348: 
                    349:        for(i = 0; i < nevents; i++)
                    350:                if(events[i].pid == pid) return(i);
                    351:        return(-1);
                    352: }
                    353: 
                    354: static void
                    355: pnew(pid, status)
                    356: {
                    357:        register Process *p;
                    358: 
                    359:        if(pfree){
                    360:                p = pfree;
                    361:                pfree = p->f;
                    362:        } else
                    363:                p = (Process *)Malloc(sizeof(Process));
                    364:        p->pid = pid;
                    365:        p->status = status;
                    366:        p->f = phead;
                    367:        phead = p;
                    368:        if(p->f)
                    369:                p->f->b = p;
                    370:        p->b = 0;
                    371: }
                    372: 
                    373: static void
                    374: pdelete(p)
                    375:        Process *p;
                    376: {
                    377:        if(p->f)
                    378:                p->f->b = p->b;
                    379:        if(p->b)
                    380:                p->b->f = p->f;
                    381:        else
                    382:                phead = p->f;
                    383:        p->f = pfree;
                    384:        pfree = p;
                    385: }
                    386: 
                    387: static long tslot[1000];
                    388: static long tick;
                    389: 
                    390: account()
                    391: {
                    392:        long t;
                    393: 
                    394:        time(&t);
                    395:        if(tick)
                    396:                tslot[nrunning] += (t-tick);
                    397:        tick = t;
                    398: }
                    399: 
                    400: praccount()
                    401: {
                    402:        int i;
                    403: 
                    404:        account();
                    405:        for(i = 0; i <= nevents; i++)
                    406:                Fprint(1, "%d: %ld\n", i, tslot[i]);
                    407: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.