#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);
	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);
		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);
		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]);
}
