Annotation of researchv10no/cmd/mk/export/run.c, revision 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.