#include	"mk.h"

typedef struct Event
{
	int pid;
	Job *job;
} Event;
static Event *events;
static int nevents, nrunning, nproclimit;

typedef struct Process
{
	int pid;
	int status;
	struct Process *b, *f;
} Process;
static Process *phead, *pfree;
static void sched(void);
static void pnew(int, int), pdelete(Process *);

int pidslot(int);

void
run(Job *j)
{
	Job *jj;

	if(jobs){
		for(jj = jobs; jj->next; jj = jj->next)
			;
		jj->next = j;
	} else 
		jobs = j;
	j->next = 0;
	/* this code also in waitup after parse redirect */
	if(nrunning < nproclimit)
		sched();
}

static void
sched(void)
{
	char *flags;
	Job *j;
	Bufblock *buf;
	int slot;
	Node *n;
	Envy *e;

	if(jobs == 0){
		usage();
		return;
	}
	j = jobs;
	jobs = j->next;
	if(DEBUG(D_EXEC))
		fprint(1, "firing up job for target %s\n", wtos(j->t, ' '));
	slot = nextslot();
	events[slot].job = j;
	buf = newbuf();
	e = buildenv(j, slot);
	shprint(j->r->recipe, e, buf, j->r->shellt);
	if(!tflag && (nflag || !(j->r->attr&QUIET)))
		Bwrite(&bout, buf->start, (long)strlen(buf->start));
	freebuf(buf);
	if(nflag||tflag){
		for(n = j->n; n; n = n->next){
			if(tflag){
				if(!(n->flags&VIRTUAL))
					touch(n->name);
				else if(explain)
					Bprint(&bout, "no touch of virtual '%s'\n", n->name);
			}
			n->time = time((long *)0);
			MADESET(n, MADE);
		}
	} else {
		if(DEBUG(D_EXEC))
			fprint(1, "recipe='%s'", j->r->recipe);/**/
		Bflush(&bout);
		if(j->r->attr&NOMINUSE)
			flags = 0;
		else
			flags = "-e";
		events[slot].pid = execsh(flags, j->r->recipe, 0, e, j->r->shellt, j->r->shellcmd);
		usage();
		nrunning++;
		if(DEBUG(D_EXEC))
			fprint(1, "pid for target %s = %d\n", wtos(j->t, ' '), events[slot].pid);
	}
}

int
waitup(int echildok, int *retstatus)
{
	Envy *e;
	int pid;
	int slot;
	Symtab *s;
	Word *w;
	Job *j;
	char buf[ERRMAX];
	Bufblock *bp;
	int uarg = 0;
	int done;
	Node *n;
	Process *p;
	extern int runerrs;

	/* first check against the proces slist */
	if(retstatus)
		for(p = phead; p; p = p->f)
			if(p->pid == *retstatus){
				*retstatus = p->status;
				pdelete(p);
				return(-1);
			}
again:		/* rogue processes */
	pid = waitfor(buf);
	if(pid == -1){
		if(echildok > 0)
			return(1);
		else {
			fprint(2, "mk: (waitup %d): %r\n", echildok);
			Exit();
		}
	}
	if(DEBUG(D_EXEC))
		fprint(1, "waitup got pid=%d, status='%s'\n", pid, buf);
	if(retstatus && pid == *retstatus){
		*retstatus = buf[0]? 1:0;
		return(-1);
	}
	slot = pidslot(pid);
	if(slot < 0){
		if(DEBUG(D_EXEC))
			fprint(2, "mk: wait returned unexpected process %d\n", pid);
		pnew(pid, buf[0]? 1:0);
		goto again;
	}
	j = events[slot].job;
	usage();
	nrunning--;
	events[slot].pid = -1;
	if(buf[0]){
		e = buildenv(j, slot);
		bp = newbuf();
		shprint(j->r->recipe, e, bp, j->r->shellt);
		front(bp->start);
		fprint(2, "mk: %s: exit status=%s", bp->start, buf);
		freebuf(bp);
		for(n = j->n, done = 0; n; n = n->next)
			if(n->flags&DELETE){
				if(done++ == 0)
					fprint(2, ", deleting");
				fprint(2, " '%s'", n->name);
				delete(n->name);
			}
		fprint(2, "\n");
		if(kflag){
			runerrs++;
			uarg = 1;
		} else {
			jobs = 0;
			Exit();
		}
	}
	for(w = j->t; w; w = w->next){
		if((s = symlook(w->s, S_NODE, 0)) == 0)
			continue;	/* not interested in this node */
		update(uarg, (Node *)s->value);
	}
	if(nrunning < nproclimit)
		sched();
	return(0);
}

void
nproc(void)
{
	Symtab *sym;
	Word *w;

	if(sym = symlook("NPROC", S_VAR, 0)) {
		w = (Word *) sym->value;
		if (w && w->s && w->s[0])
			nproclimit = atoi(w->s);
	}
	if(nproclimit < 1)
		nproclimit = 1;
	if(DEBUG(D_EXEC))
		fprint(1, "nprocs = %d\n", nproclimit);
	if(nproclimit > nevents){
		if(nevents)
			events = (Event *)Realloc((char *)events, nproclimit*sizeof(Event));
		else
			events = (Event *)Malloc(nproclimit*sizeof(Event));
		while(nevents < nproclimit)
			events[nevents++].pid = 0;
	}
}

int
nextslot(void)
{
	int i;

	for(i = 0; i < nproclimit; i++)
		if(events[i].pid <= 0) return i;
	assert("out of slots!!", 0);
	return 0;	/* cyntax */
}

int
pidslot(int pid)
{
	int i;

	for(i = 0; i < nevents; i++)
		if(events[i].pid == pid) return(i);
	if(DEBUG(D_EXEC))
		fprint(2, "mk: wait returned unexpected process %d\n", pid);
	return(-1);
}


static void
pnew(int pid, int status)
{
	Process *p;

	if(pfree){
		p = pfree;
		pfree = p->f;
	} else
		p = (Process *)Malloc(sizeof(Process));
	p->pid = pid;
	p->status = status;
	p->f = phead;
	phead = p;
	if(p->f)
		p->f->b = p;
	p->b = 0;
}

static void
pdelete(Process *p)
{
	if(p->f)
		p->f->b = p->b;
	if(p->b)
		p->b->f = p->f;
	else
		phead = p->f;
	p->f = pfree;
	pfree = p;
}

void
killchildren(char *msg)
{
	Process *p;

	kflag = 1;	/* to make sure waitup doesn't exit */
	jobs = 0;	/* make sure no more get scheduled */
	for(p = phead; p; p = p->f)
		expunge(p->pid, msg);
	while(waitup(1, (int *)0) == 0)
		;
	Bprint(&bout, "mk: %s\n", msg);
	Exit();
}

static long tslot[1000];
static long tick;

void
usage(void)
{
	long t;

	time(&t);
	if(tick)
		tslot[nrunning] += (t-tick);
	tick = t;
}

void
prusage(void)
{
	int i;

	usage();
	for(i = 0; i <= nevents; i++)
		fprint(1, "%d: %ld\n", i, tslot[i]);
}
