uint4 cmj_iostart(struct CLB *lnk, uint4 operation, unsigned int state)
{
	uint4 status;
	error_def(CMI_DCNINPROG);
	error_def(CMI_LNKNOTIDLE);
	void cmj_ast();

	if (lnk->sta != CM_CLB_IDLE)
		return (lnk->sta == CM_CLB_DISCONNECT) ? CMI_DCNINPROG : CMI_LNKNOTIDLE;
        lnk->sta = (unsigned char)state;
	if (lnk->ast)
	{
                status = sys$qio(EFN$C_ENF, lnk->dch, operation,
			&lnk->ios, cmj_ast, lnk,
			lnk->mbf, lnk->cbl, 0, 0, 0, 0);
	} else
	{
                status = sys$qio(EFN$C_ENF, lnk->dch, operation,
			&lnk->ios, 0, 0, lnk->mbf, lnk->cbl, 0, 0, 0, 0);
		if (1 & status)
		{
			status = sys$synch(EFN$C_ENF, &lnk->ios);
			cmj_fini(lnk);
			if (1 & status)
				status = lnk->ios.status;
		}
	}
	return status;
}
Exemple #2
0
/*
 * change the system date on the master
 */
static void
mchgdate(struct tsp *msg)
{
	char tname[MAXHOSTNAMELEN];
	char olddate[32];
	struct timeval otime, ntime;

	strlcpy(tname, msg->tsp_name, sizeof(tname));

	xmit(TSP_DATEACK, msg->tsp_seq, &from);

	strlcpy(olddate, date(), sizeof(olddate));

	/* adjust time for residence on the queue */
	gettimeofday(&otime, 0);
	adj_msg_time(msg,&otime);

	timevalsub(&ntime, &msg->tsp_time, &otime);
	if (ntime.tv_sec < MAXADJ && ntime.tv_sec > -MAXADJ) {
		/*
		 * do not change the clock if we can adjust it
		 */
		dictate = 3;
		synch(tvtomsround(ntime));
	} else {
		logwtmp("|", "date", "");
		settimeofday(&msg->tsp_time, 0);
		logwtmp("{", "date", "");
		spreadtime();
	}

	syslog(LOG_NOTICE, "date changed by %s from %s",
	       tname, olddate);
}
void ojdefimage (mstr *image)
{
	static mstr imagebuf = {0, 0};
	int4 status;
	unsigned char local_buff[MAX_FILSPC_LEN];
	short iosb[4];
	unsigned short length;
	struct
	{
		item_list_3	le[1];
		int4		terminator;
	}		item_list;

	if (!imagebuf.addr)
	{
		item_list.le[0].buffer_length = MAX_FILSPC_LEN;
		item_list.le[0].item_code = JPI$_IMAGNAME;
		item_list.le[0].buffer_address = local_buff;
		item_list.le[0].return_length_address = &length;
		item_list.terminator = 0;
		status = sys$getjpi (0, 0, 0, &item_list, &iosb[0], 0, 0);
		if (!(status & 1))
			rts_error(VARLSTCNT(1) status);
		sys$synch (efn_immed_wait, &iosb[0]);
		if (!(iosb[0] & 1))
			rts_error(VARLSTCNT(1) iosb[0]);
		imagebuf.addr = malloc(length);
		imagebuf.len = length;
		memcpy(imagebuf.addr, local_buff, length);
	}
	*image = imagebuf;
	return;
}
Exemple #4
0
void
synch(Reg *r, Bits dif)
{
	Reg *r1;
	int z;

	for(r1 = r; r1 != R; r1 = (Reg*)r1->f.s1) {
		for(z=0; z<BITS; z++) {
			dif.b[z] = (dif.b[z] &
				~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
					r1->set.b[z] | r1->regdiff.b[z];
			if(dif.b[z] != r1->regdiff.b[z]) {
				r1->regdiff.b[z] = dif.b[z];
				change++;
			}
		}
		if(r1->f.active)
			break;
		r1->f.active = 1;
		for(z=0; z<BITS; z++)
			dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
		if(r1->f.s2 != nil)
			synch((Reg*)r1->f.s2, dif);
	}
}
Exemple #5
0
asmlinkage int exe$getjpiw(unsigned int efn, unsigned int *pidadr, void * prcnam, void *itmlst, struct _iosb *iosb, void (*astadr)(), unsigned long long astprm)
{

    /* I think this is about it */

    int status=exe$getjpi(efn,pidadr,prcnam,itmlst,iosb,astadr,astprm);
    if ((status&1)==0) return status;
    return exe$synch(efn,iosb);

}
void mup_bak_pause(void)
{
	int4	pause[2];

	pause[0] = 2 * -10000000;
	pause[1] = -1;
	if (sys$setimr( efn_immed_wait, &pause, 0, 0, 0) == SS$_NORMAL)	/* Safety wait to make sure that all blocks have been */
	{	sys$synch(efn_immed_wait, 0);				/* returned to the frozen queues before flushing      */
	}

	return;
}
Exemple #7
0
/*
 * change the system date on the master
 */
static void
mchgdate(struct tsp *msg)
{
	char tname[MAXHOSTNAMELEN];
	char olddate[32];
	struct timeval otime, ntime, tmptv;
	struct utmpx utx;

	(void)strcpy(tname, msg->tsp_name);

	xmit(TSP_DATEACK, msg->tsp_seq, &from);

	(void)strcpy(olddate, date());

	/* adjust time for residence on the queue */
	(void)gettimeofday(&otime, NULL);
	adj_msg_time(msg,&otime);

 	tmptv.tv_sec = msg->tsp_time.tv_sec;
 	tmptv.tv_usec = msg->tsp_time.tv_usec;
	timevalsub(&ntime, &tmptv, &otime);
	if (ntime.tv_sec < MAXADJ && ntime.tv_sec > -MAXADJ) {
		/*
		 * do not change the clock if we can adjust it
		 */
		dictate = 3;
		synch(tvtomsround(ntime));
	} else {
		utx.ut_type = OLD_TIME;
		(void)gettimeofday(&utx.ut_tv, NULL);
		pututxline(&utx);
 		(void)settimeofday(&tmptv, 0);
		utx.ut_type = NEW_TIME;
		(void)gettimeofday(&utx.ut_tv, NULL);
		pututxline(&utx);
		spreadtime();
	}

	syslog(LOG_NOTICE, "date changed by %s from %s",
	       tname, olddate);
}
void
OpenDDS::DCPS::TcpSendStrategy::schedule_output()
{
  DBG_ENTRY_LVL("TcpSendStrategy","schedule_output",6);

  // Notify the reactor to adjust its processing policy according to mode_.
  synch()->work_available();

  if (DCPS_debug_level > 4) {
    const char* action = "";
    if( mode() == MODE_DIRECT) {
      action = "canceling";
    } else if( (mode() == MODE_QUEUE)
            || (mode() == MODE_SUSPEND)) {
      action = "starting";
    }
    ACE_DEBUG((LM_DEBUG,
               ACE_TEXT("(%P|%t) TcpSendStrategy::schedule_output() [%d] - ")
               ACE_TEXT("%C data queueing for handle %d.\n"),
               id(),action,get_handle()));
  }
}
Exemple #9
0
int sys$qiow(unsigned int efn, unsigned short int chan,unsigned int func, struct _iosb *iosb, void(*astadr)(__unknown_params), long  astprm, void*p1, long p2, long  p3, long p4, long p5, long p6)
{
    struct struct_qio s;
    s.efn=efn;
    s.chan=chan;
    s.func=func;
    s.iosb=iosb;
    s.astadr=astadr;
    s.astprm=astprm;
    s.p1=p1;
    s.p2=p2;
    s.p3=p3;
    s.p4=p4;
    s.p5=p5;
    s.p6=p6;
#ifdef __x86_64__
    syscall_struct();
#endif
    int status = INLINE_SYSCALL($qio,1,&s);
    if ((status&1)==0) return status;
    return exe$synch(efn,iosb);
}
Exemple #10
0
unsigned int lib$wait(float *seconds, int flags, int float_type) {
  // check pointer
  if (*seconds<0 || *seconds>100000)
    return LIB$_INVARG;
  float hundreds_f = *seconds * 100;
  long long hundreds = hundreds_f;
  long long vmstime = - hundreds * 100000;
  int sts;
  if (flags & 1) { // LIB$K_NOWAKE is 1
    sts = sys$setimr (0, &vmstime, dummyast, 0, 0);
    if ((sts & 1) == 0)
      return sts;
    sts = sys$synch (0, 0);
    if ((sts & 1) == 0)
      return sts;
  } else {
    sts = sys$schdwk(0, 0, &vmstime, 0);
    if ((sts & 1) == 0)
      return sts;
    return sys$hiber();
  }
  return SS$_NORMAL;
}
Exemple #11
0
void
regopt(Prog *firstp)
{
	Reg *r, *r1;
	Prog *p;
	Graph *g;
	ProgInfo info;
	int i, z;
	uint32 vreg;
	Bits bit;

	if(first) {
		fmtinstall('Q', Qconv);
		exregoffset = D_R15;
		first = 0;
	}

	mergetemp(firstp);

	/*
	 * control flow is more complicated in generated go code
	 * than in generated c code.  define pseudo-variables for
	 * registers, so we have complete register usage information.
	 */
	nvar = NREGVAR;
	memset(var, 0, NREGVAR*sizeof var[0]);
	for(i=0; i<NREGVAR; i++) {
		if(regnodes[i] == N)
			regnodes[i] = newname(lookup(regname[i]));
		var[i].node = regnodes[i];
	}

	regbits = RtoB(D_SP);
	for(z=0; z<BITS; z++) {
		externs.b[z] = 0;
		params.b[z] = 0;
		consts.b[z] = 0;
		addrs.b[z] = 0;
		ovar.b[z] = 0;
	}

	// build list of return variables
	setoutvar();

	/*
	 * pass 1
	 * build aux data structure
	 * allocate pcs
	 * find use and set of variables
	 */
	g = flowstart(firstp, sizeof(Reg));
	if(g == nil)
		return;
	firstr = (Reg*)g->start;

	for(r = firstr; r != R; r = (Reg*)r->f.link) {
		p = r->f.prog;
		if(p->as == AVARDEF)
			continue;
		proginfo(&info, p);

		// Avoid making variables for direct-called functions.
		if(p->as == ACALL && p->to.type == D_EXTERN)
			continue;

		r->use1.b[0] |= info.reguse | info.regindex;
		r->set.b[0] |= info.regset;

		bit = mkvar(r, &p->from);
		if(bany(&bit)) {
			if(info.flags & LeftAddr)
				setaddrs(bit);
			if(info.flags & LeftRead)
				for(z=0; z<BITS; z++)
					r->use1.b[z] |= bit.b[z];
			if(info.flags & LeftWrite)
				for(z=0; z<BITS; z++)
					r->set.b[z] |= bit.b[z];
		}

		bit = mkvar(r, &p->to);
		if(bany(&bit)) {	
			if(info.flags & RightAddr)
				setaddrs(bit);
			if(info.flags & RightRead)
				for(z=0; z<BITS; z++)
					r->use2.b[z] |= bit.b[z];
			if(info.flags & RightWrite)
				for(z=0; z<BITS; z++)
					r->set.b[z] |= bit.b[z];
		}
	}

	for(i=0; i<nvar; i++) {
		Var *v = var+i;
		if(v->addr) {
			bit = blsh(i);
			for(z=0; z<BITS; z++)
				addrs.b[z] |= bit.b[z];
		}

		if(debug['R'] && debug['v'])
			print("bit=%2d addr=%d et=%-6E w=%-2d s=%N + %lld\n",
				i, v->addr, v->etype, v->width, v->node, v->offset);
	}

	if(debug['R'] && debug['v'])
		dumpit("pass1", &firstr->f, 1);

	/*
	 * pass 2
	 * find looping structure
	 */
	flowrpo(g);

	if(debug['R'] && debug['v'])
		dumpit("pass2", &firstr->f, 1);

	/*
	 * pass 3
	 * iterate propagating usage
	 * 	back until flow graph is complete
	 */
loop1:
	change = 0;
	for(r = firstr; r != R; r = (Reg*)r->f.link)
		r->f.active = 0;
	for(r = firstr; r != R; r = (Reg*)r->f.link)
		if(r->f.prog->as == ARET)
			prop(r, zbits, zbits);
loop11:
	/* pick up unreachable code */
	i = 0;
	for(r = firstr; r != R; r = r1) {
		r1 = (Reg*)r->f.link;
		if(r1 && r1->f.active && !r->f.active) {
			prop(r, zbits, zbits);
			i = 1;
		}
	}
	if(i)
		goto loop11;
	if(change)
		goto loop1;

	if(debug['R'] && debug['v'])
		dumpit("pass3", &firstr->f, 1);

	/*
	 * pass 4
	 * iterate propagating register/variable synchrony
	 * 	forward until graph is complete
	 */
loop2:
	change = 0;
	for(r = firstr; r != R; r = (Reg*)r->f.link)
		r->f.active = 0;
	synch(firstr, zbits);
	if(change)
		goto loop2;

	if(debug['R'] && debug['v'])
		dumpit("pass4", &firstr->f, 1);

	/*
	 * pass 4.5
	 * move register pseudo-variables into regu.
	 */
	for(r = firstr; r != R; r = (Reg*)r->f.link) {
		r->regu = (r->refbehind.b[0] | r->set.b[0]) & REGBITS;

		r->set.b[0] &= ~REGBITS;
		r->use1.b[0] &= ~REGBITS;
		r->use2.b[0] &= ~REGBITS;
		r->refbehind.b[0] &= ~REGBITS;
		r->refahead.b[0] &= ~REGBITS;
		r->calbehind.b[0] &= ~REGBITS;
		r->calahead.b[0] &= ~REGBITS;
		r->regdiff.b[0] &= ~REGBITS;
		r->act.b[0] &= ~REGBITS;
	}

	/*
	 * pass 5
	 * isolate regions
	 * calculate costs (paint1)
	 */
	r = firstr;
	if(r) {
		for(z=0; z<BITS; z++)
			bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
			  ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
		if(bany(&bit) && !r->f.refset) {
			// should never happen - all variables are preset
			if(debug['w'])
				print("%L: used and not set: %Q\n", r->f.prog->lineno, bit);
			r->f.refset = 1;
		}
	}
	for(r = firstr; r != R; r = (Reg*)r->f.link)
		r->act = zbits;
	rgp = region;
	nregion = 0;
	for(r = firstr; r != R; r = (Reg*)r->f.link) {
		for(z=0; z<BITS; z++)
			bit.b[z] = r->set.b[z] &
			  ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
		if(bany(&bit) && !r->f.refset) {
			if(debug['w'])
				print("%L: set and not used: %Q\n", r->f.prog->lineno, bit);
			r->f.refset = 1;
			excise(&r->f);
		}
		for(z=0; z<BITS; z++)
			bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
		while(bany(&bit)) {
			i = bnum(bit);
			rgp->enter = r;
			rgp->varno = i;
			change = 0;
			paint1(r, i);
			bit.b[i/32] &= ~(1L<<(i%32));
			if(change <= 0)
				continue;
			rgp->cost = change;
			nregion++;
			if(nregion >= NRGN) {
				if(debug['R'] && debug['v'])
					print("too many regions\n");
				goto brk;
			}
			rgp++;
		}
	}
brk:
	qsort(region, nregion, sizeof(region[0]), rcmp);

	if(debug['R'] && debug['v'])
		dumpit("pass5", &firstr->f, 1);

	/*
	 * pass 6
	 * determine used registers (paint2)
	 * replace code (paint3)
	 */
	rgp = region;
	for(i=0; i<nregion; i++) {
		bit = blsh(rgp->varno);
		vreg = paint2(rgp->enter, rgp->varno);
		vreg = allreg(vreg, rgp);
		if(rgp->regno != 0) {
			if(debug['R'] && debug['v']) {
				Var *v;

				v = var + rgp->varno;
				print("registerize %N+%lld (bit=%2d et=%2E) in %R\n",
						v->node, v->offset, rgp->varno, v->etype, rgp->regno);
			}
			paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
		}
		rgp++;
	}

	if(debug['R'] && debug['v'])
		dumpit("pass6", &firstr->f, 1);
	
	/*
	 * free aux structures. peep allocates new ones.
	 */
	flowend(g);
	firstr = R;

	/*
	 * pass 7
	 * peep-hole on basic block
	 */
	if(!debug['R'] || debug['P'])
		peep(firstp);

	/*
	 * eliminate nops
	 */
	for(p=firstp; p!=P; p=p->link) {
		while(p->link != P && p->link->as == ANOP)
			p->link = p->link->link;
		if(p->to.type == D_BRANCH)
			while(p->to.u.branch != P && p->to.u.branch->as == ANOP)
				p->to.u.branch = p->to.u.branch->link;
	}

	if(debug['R']) {
		if(ostats.ncvtreg ||
		   ostats.nspill ||
		   ostats.nreload ||
		   ostats.ndelmov ||
		   ostats.nvar ||
		   ostats.naddr ||
		   0)
			print("\nstats\n");

		if(ostats.ncvtreg)
			print("	%4d cvtreg\n", ostats.ncvtreg);
		if(ostats.nspill)
			print("	%4d spill\n", ostats.nspill);
		if(ostats.nreload)
			print("	%4d reload\n", ostats.nreload);
		if(ostats.ndelmov)
			print("	%4d delmov\n", ostats.ndelmov);
		if(ostats.nvar)
			print("	%4d var\n", ostats.nvar);
		if(ostats.naddr)
			print("	%4d addr\n", ostats.naddr);

		memset(&ostats, 0, sizeof(ostats));
	}
}
Exemple #12
0
void
regopt(Prog *p)
{
	Reg *r, *r1, *r2;
	Prog *p1;
	int i, z;
	int32_t initpc, val, npc;
	uint32_t vreg;
	Bits bit;
	struct
	{
		int32_t	m;
		int32_t	c;
		Reg*	p;
	} log5[6], *lp;

	firstr = R;
	lastr = R;
	nvar = 0;
	regbits = RtoB(D_SP) | RtoB(D_AX);
	for(z=0; z<BITS; z++) {
		externs.b[z] = 0;
		params.b[z] = 0;
		consts.b[z] = 0;
		addrs.b[z] = 0;
	}

	/*
	 * pass 1
	 * build aux data structure
	 * allocate pcs
	 * find use and set of variables
	 */
	val = 5L * 5L * 5L * 5L * 5L;
	lp = log5;
	for(i=0; i<5; i++) {
		lp->m = val;
		lp->c = 0;
		lp->p = R;
		val /= 5L;
		lp++;
	}
	val = 0;
	for(; p != P; p = p->link) {
		switch(p->as) {
		case ADATA:
		case AGLOBL:
		case ANAME:
		case ASIGNAME:
			continue;
		}
		r = rega();
		if(firstr == R) {
			firstr = r;
			lastr = r;
		} else {
			lastr->link = r;
			r->p1 = lastr;
			lastr->s1 = r;
			lastr = r;
		}
		r->prog = p;
		r->pc = val;
		val++;

		lp = log5;
		for(i=0; i<5; i++) {
			lp->c--;
			if(lp->c <= 0) {
				lp->c = lp->m;
				if(lp->p != R)
					lp->p->log5 = r;
				lp->p = r;
				(lp+1)->c = 0;
				break;
			}
			lp++;
		}

		r1 = r->p1;
		if(r1 != R)
		switch(r1->prog->as) {
		case ARET:
		case AJMP:
		case AIRETL:
			r->p1 = R;
			r1->s1 = R;
		}

		bit = mkvar(r, &p->from, p->as==AMOVL);
		if(bany(&bit))
		switch(p->as) {
		/*
		 * funny
		 */
		case ALEAL:
			for(z=0; z<BITS; z++)
				addrs.b[z] |= bit.b[z];
			break;

		/*
		 * left side read
		 */
		default:
			for(z=0; z<BITS; z++)
				r->use1.b[z] |= bit.b[z];
			break;
		}

		bit = mkvar(r, &p->to, 0);
		if(bany(&bit))
		switch(p->as) {
		default:
			diag(Z, "reg: unknown op: %A", p->as);
			break;

		/*
		 * right side read
		 */
		case ACMPB:
		case ACMPL:
		case ACMPW:
			for(z=0; z<BITS; z++)
				r->use2.b[z] |= bit.b[z];
			break;

		/*
		 * right side write
		 */
		case ANOP:
		case AMOVL:
		case AMOVB:
		case AMOVW:
		case AMOVBLSX:
		case AMOVBLZX:
		case AMOVWLSX:
		case AMOVWLZX:
			for(z=0; z<BITS; z++)
				r->set.b[z] |= bit.b[z];
			break;

		/*
		 * right side read+write
		 */
		case AADDB:
		case AADDL:
		case AADDW:
		case AANDB:
		case AANDL:
		case AANDW:
		case ASUBB:
		case ASUBL:
		case ASUBW:
		case AORB:
		case AORL:
		case AORW:
		case AXORB:
		case AXORL:
		case AXORW:
		case ASALB:
		case ASALL:
		case ASALW:
		case ASARB:
		case ASARL:
		case ASARW:
		case AROLB:
		case AROLL:
		case AROLW:
		case ARORB:
		case ARORL:
		case ARORW:
		case ASHLB:
		case ASHLL:
		case ASHLW:
		case ASHRB:
		case ASHRL:
		case ASHRW:
		case AIMULL:
		case AIMULW:
		case ANEGL:
		case ANOTL:
		case AADCL:
		case ASBBL:
			for(z=0; z<BITS; z++) {
				r->set.b[z] |= bit.b[z];
				r->use2.b[z] |= bit.b[z];
			}
			break;

		/*
		 * funny
		 */
		case AFMOVDP:
		case AFMOVFP:
		case AFMOVLP:
		case AFMOVVP:
		case AFMOVWP:
		case ACALL:
			for(z=0; z<BITS; z++)
				addrs.b[z] |= bit.b[z];
			break;
		}

		switch(p->as) {
		case AIMULL:
		case AIMULW:
			if(p->to.type != D_NONE)
				break;

		case AIDIVB:
		case AIDIVL:
		case AIDIVW:
		case AIMULB:
		case ADIVB:
		case ADIVL:
		case ADIVW:
		case AMULB:
		case AMULL:
		case AMULW:

		case ACWD:
		case ACDQ:
			r->regu |= RtoB(D_AX) | RtoB(D_DX);
			break;

		case AREP:
		case AREPN:
		case ALOOP:
		case ALOOPEQ:
		case ALOOPNE:
			r->regu |= RtoB(D_CX);
			break;

		case AMOVSB:
		case AMOVSL:
		case AMOVSW:
		case ACMPSB:
		case ACMPSL:
		case ACMPSW:
			r->regu |= RtoB(D_SI) | RtoB(D_DI);
			break;

		case ASTOSB:
		case ASTOSL:
		case ASTOSW:
		case ASCASB:
		case ASCASL:
		case ASCASW:
			r->regu |= RtoB(D_AX) | RtoB(D_DI);
			break;

		case AINSB:
		case AINSL:
		case AINSW:
		case AOUTSB:
		case AOUTSL:
		case AOUTSW:
			r->regu |= RtoB(D_DI) | RtoB(D_DX);
			break;

		case AFSTSW:
		case ASAHF:
			r->regu |= RtoB(D_AX);
			break;
		}
	}
	if(firstr == R)
		return;
	initpc = pc - val;
	npc = val;

	/*
	 * pass 2
	 * turn branch references to pointers
	 * build back pointers
	 */
	for(r = firstr; r != R; r = r->link) {
		p = r->prog;
		if(p->to.type == D_BRANCH) {
			val = p->to.offset - initpc;
			r1 = firstr;
			while(r1 != R) {
				r2 = r1->log5;
				if(r2 != R && val >= r2->pc) {
					r1 = r2;
					continue;
				}
				if(r1->pc == val)
					break;
				r1 = r1->link;
			}
			if(r1 == R) {
				nearln = p->lineno;
				diag(Z, "ref not found\n%P", p);
				continue;
			}
			if(r1 == r) {
				nearln = p->lineno;
				diag(Z, "ref to self\n%P", p);
				continue;
			}
			r->s2 = r1;
			r->p2link = r1->p2;
			r1->p2 = r;
		}
	}
	if(debug['R']) {
		p = firstr->prog;
		print("\n%L %D\n", p->lineno, &p->from);
	}

	/*
	 * pass 2.5
	 * find looping structure
	 */
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	change = 0;
	loopit(firstr, npc);
	if(debug['R'] && debug['v']) {
		print("\nlooping structure:\n");
		for(r = firstr; r != R; r = r->link) {
			print("%ld:%P", r->loop, r->prog);
			for(z=0; z<BITS; z++)
				bit.b[z] = r->use1.b[z] |
					   r->use2.b[z] |
					   r->set.b[z];
			if(bany(&bit)) {
				print("\t");
				if(bany(&r->use1))
					print(" u1=%B", r->use1);
				if(bany(&r->use2))
					print(" u2=%B", r->use2);
				if(bany(&r->set))
					print(" st=%B", r->set);
			}
			print("\n");
		}
	}

	/*
	 * pass 3
	 * iterate propagating usage
	 * 	back until flow graph is complete
	 */
loop1:
	change = 0;
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	for(r = firstr; r != R; r = r->link)
		if(r->prog->as == ARET)
			prop(r, zbits, zbits);
loop11:
	/* pick up unreachable code */
	i = 0;
	for(r = firstr; r != R; r = r1) {
		r1 = r->link;
		if(r1 && r1->active && !r->active) {
			prop(r, zbits, zbits);
			i = 1;
		}
	}
	if(i)
		goto loop11;
	if(change)
		goto loop1;


	/*
	 * pass 4
	 * iterate propagating register/variable synchrony
	 * 	forward until graph is complete
	 */
loop2:
	change = 0;
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	synch(firstr, zbits);
	if(change)
		goto loop2;


	/*
	 * pass 5
	 * isolate regions
	 * calculate costs (paint1)
	 */
	r = firstr;
	if(r) {
		for(z=0; z<BITS; z++)
			bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
			  ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
		if(bany(&bit)) {
			nearln = r->prog->lineno;
			warn(Z, "used and not set: %B", bit);
			if(debug['R'] && !debug['w'])
				print("used and not set: %B\n", bit);
		}
	}
	if(debug['R'] && debug['v'])
		print("\nprop structure:\n");
	for(r = firstr; r != R; r = r->link)
		r->act = zbits;
	rgp = region;
	nregion = 0;
	for(r = firstr; r != R; r = r->link) {
		if(debug['R'] && debug['v']) {
			print("%P\t", r->prog);
			if(bany(&r->set))
				print("s:%B ", r->set);
			if(bany(&r->refahead))
				print("ra:%B ", r->refahead);
			if(bany(&r->calahead))
				print("ca:%B ", r->calahead);
			print("\n");
		}
		for(z=0; z<BITS; z++)
			bit.b[z] = r->set.b[z] &
			  ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
		if(bany(&bit)) {
			nearln = r->prog->lineno;
			warn(Z, "set and not used: %B", bit);
			if(debug['R'])
				print("set and not used: %B\n", bit);
			excise(r);
		}
		for(z=0; z<BITS; z++)
			bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
		while(bany(&bit)) {
			i = bnum(bit);
			rgp->enter = r;
			rgp->varno = i;
			change = 0;
			if(debug['R'] && debug['v'])
				print("\n");
			paint1(r, i);
			bit.b[i/32] &= ~(1L<<(i%32));
			if(change <= 0) {
				if(debug['R'])
					print("%L$%d: %B\n",
						r->prog->lineno, change, blsh(i));
				continue;
			}
			rgp->cost = change;
			nregion++;
			if(nregion >= NRGN) {
				warn(Z, "too many regions");
				goto brk;
			}
			rgp++;
		}
	}
brk:
	qsort(region, nregion, sizeof(region[0]), rcmp);

	/*
	 * pass 6
	 * determine used registers (paint2)
	 * replace code (paint3)
	 */
	rgp = region;
	for(i=0; i<nregion; i++) {
		bit = blsh(rgp->varno);
		vreg = paint2(rgp->enter, rgp->varno);
		vreg = allreg(vreg, rgp);
		if(debug['R']) {
			print("%L$%d %R: %B\n",
				rgp->enter->prog->lineno,
				rgp->cost,
				rgp->regno,
				bit);
		}
		if(rgp->regno != 0)
			paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
		rgp++;
	}
	/*
	 * pass 7
	 * peep-hole on basic block
	 */
	if(!debug['R'] || debug['P'])
		peep();

	/*
	 * pass 8
	 * recalculate pc
	 */
	val = initpc;
	for(r = firstr; r != R; r = r1) {
		r->pc = val;
		p = r->prog;
		p1 = P;
		r1 = r->link;
		if(r1 != R)
			p1 = r1->prog;
		for(; p != p1; p = p->link) {
			switch(p->as) {
			default:
				val++;
				break;

			case ANOP:
			case ADATA:
			case AGLOBL:
			case ANAME:
			case ASIGNAME:
				break;
			}
		}
	}
	pc = val;

	/*
	 * fix up branches
	 */
	if(debug['R'])
		if(bany(&addrs))
			print("addrs: %B\n", addrs);

	r1 = 0; /* set */
	for(r = firstr; r != R; r = r->link) {
		p = r->prog;
		if(p->to.type == D_BRANCH)
			p->to.offset = r->s2->pc;
		r1 = r;
	}

	/*
	 * last pass
	 * eliminate nops
	 * free aux structures
	 */
	for(p = firstr->prog; p != P; p = p->link){
		while(p->link && p->link->as == ANOP)
			p->link = p->link->link;
	}
	if(r1 != R) {
		r1->link = freer;
		freer = firstr;
	}
}
Exemple #13
0
void goq_load(uint4 begin, uint4 end, struct FAB *infab)
{
	int		status;
	msgtype		msg;
	unsigned char	*in_buff, *b;
	unsigned int	n;
	bool		is_begin;
	uint4		rec_count;
	unsigned short	goq_blk_size;
	short		iosb[4];

	error_def(ERR_INVMVXSZ);
	error_def(ERR_MUPIPINFO);
	error_def(ERR_PREMATEOF);
	error_def(ERR_LDGOQFMT);
	error_def(ERR_BEGINST);

	rec_count = 0;
	if (begin > 0)
		is_begin = TRUE;
	else
		is_begin = FALSE;
	goq_blk_size = MVX_BLK_SIZE;
	infab->fab$w_mrs = goq_blk_size;
	in_buff = malloc(goq_blk_size + 8);
	if (is_begin)
	{
		status = sys$qio(efn_bg_qio_read, infab->fab$l_stv, IO$_READVBLK, &iosb[0],
				0, 0, in_buff, goq_blk_size,
				(rec_count * goq_blk_size / 512) + 1, 0, 0, 0);
		if (SS$_NORMAL != status)		/* get header block */
			rts_error(VARLSTCNT(1) status);
		sys$synch(efn_bg_qio_read, &iosb[0]);
		if (SS$_NORMAL != iosb[0])
			rts_error(VARLSTCNT(1) iosb[0]);
		if (iosb[1] != goq_blk_size)
		{
			if (M11_BLK_SIZE != iosb[1])
				rts_error(VARLSTCNT(1) ERR_INVMVXSZ);
			goq_blk_size = M11_BLK_SIZE;
		}
		while ((SS$_ENDOFFILE != iosb[0]) && (rec_count < begin))
		{
			rec_count++;
			status = sys$qio(efn_bg_qio_read, infab->fab$l_stv, IO$_READVBLK, &iosb[0],
					0, 0, in_buff, goq_blk_size,
					(rec_count * goq_blk_size / 512) + 1, 0, 0, 0);
			if (SS$_NORMAL != status)
				rts_error(VARLSTCNT(1) status);
			sys$synch(efn_bg_qio_read, &iosb[0]);
			if ((SS$_NORMAL != iosb[0]) && (SS$_ENDOFFILE != iosb[0]))
			{
				rts_error(VARLSTCNT(1) iosb[0]);
				mupip_exit(iosb[0]);
			}
		}
		for (;rec_count < begin;)
		{
			status = sys$qio(efn_bg_qio_read, infab->fab$l_stv, IO$_READVBLK, &iosb[0],
					0, 0, in_buff, goq_blk_size,
					(rec_count * goq_blk_size / 512) + 1, 0, 0, 0);
			if (SS$_NORMAL != status)
				rts_error(VARLSTCNT(1) status);
			sys$synch(efn_bg_qio_read, &iosb[0]);
			if (SS$_ENDOFFILE == iosb[0])
				rts_error(VARLSTCNT(1) ERR_PREMATEOF);
			if (SS$_NORMAL != iosb[0])
				rts_error(VARLSTCNT(1) iosb[0]);
			rec_count++;
		}
		msg.msg_number = ERR_BEGINST;
		msg.arg_cnt = 3;
		msg.new_opts = msg.def_opts = 1;
		msg.fp_cnt = 1;
		msg.fp[0].n = rec_count;
		sys$putmsg(&msg, 0, 0, 0);
	} else
	{
		status = sys$qio(efn_bg_qio_read, infab->fab$l_stv, IO$_READVBLK, &iosb[0],
				0, 0, in_buff, goq_blk_size,
				(rec_count * goq_blk_size / 512) + 1, 0, 0, 0);
		if (SS$_NORMAL != status)
			rts_error(VARLSTCNT(1) status);
		sys$synch(efn_bg_qio_read, &iosb[0]);
		if (SS$_NORMAL != iosb[0])
		{
			rts_error(VARLSTCNT(1) iosb[0]);
			mupip_exit(iosb[0]);
		}
		if (iosb[1] != goq_blk_size)
		{
			if (M11_BLK_SIZE != iosb[1])
				rts_error(VARLSTCNT(1) ERR_INVMVXSZ);
			goq_blk_size = M11_BLK_SIZE;
		}
		b = in_buff;
		while ((13 != *b++) && (b - in_buff < goq_blk_size - 28))
			;
		if (memcmp(b - SIZEOF("~%GOQ"), LIT_AND_LEN("~%GOQ")) || (10 != *b))
		{
			rts_error(VARLSTCNT(1) ERR_LDGOQFMT);
			mupip_exit(ERR_LDGOQFMT);
		}
		for (n = 0;  n < 3;  n++)
		{
			while ((13 != *b++) && b - in_buff < goq_blk_size)
				;
			if (10 != *b++)
			{
				rts_error(VARLSTCNT(1) ERR_LDGOQFMT);
				mupip_exit(ERR_LDGOQFMT);
			}
		}
		msg.msg_number = ERR_MUPIPINFO;
		msg.arg_cnt = 4;
		msg.new_opts = msg.def_opts = 1;
		msg.fp_cnt = 2;
		msg.fp[0].n = b - in_buff - 1;
		msg.fp[1].cp = in_buff;
		sys$putmsg(&msg, 0, 0, 0);
		while (SS$_ENDOFFILE != iosb[0])
		{
			rec_count++;
			status = sys$qio(efn_bg_qio_read, infab->fab$l_stv, IO$_READVBLK, &iosb[0],
					0, 0, in_buff, goq_blk_size,
					(rec_count * goq_blk_size / 512) + 1, 0, 0, 0);
			if (SS$_NORMAL != status)
			{
				rts_error(VARLSTCNT(1) status);
				mupip_exit(status);
			}
			sys$synch(efn_bg_qio_read, &iosb[0]);
			if ((SS$_NORMAL != iosb[0]) && (SS$_ENDOFFILE != iosb[0]))
			{
				rts_error(VARLSTCNT(1) iosb[0]);
				mupip_exit(iosb[0]);
			}
		}
	}
	if (MVX_BLK_SIZE == goq_blk_size)
		goq_mvx_load(infab, in_buff, rec_count, end);
	else
		goq_m11_load(infab, in_buff, rec_count, end);
	/***********************************************************************************************/
	/*					Shut Down                                              */
	/***********************************************************************************************/
CLOSE:
	free(in_buff);
	gv_cur_region = NULL;
	status = sys$dassgn(infab->fab$l_stv);
	if (SS$_NORMAL != status)
	{
		rts_error(VARLSTCNT(1) status);
		mupip_exit(status);
	}
	return;
}
Exemple #14
0
asmlinkage int exe$enqw(unsigned int efn, unsigned int lkmode, struct _lksb *lksb, unsigned int flags, void *resnam, unsigned int parid, void (*astadr)(), unsigned long astprm, void (*blkastadr)(), unsigned int acmode, unsigned int rsdm_id) {
  int status=exe$enq(efn,lkmode,lksb,flags,resnam,parid,astadr,astprm,blkastadr,acmode,rsdm_id);
  printk("\n\nremember to do like qiow\n\n");
  if ((status&1)==0) return status;
  return exe$synch(efn,lksb);
}
Exemple #15
0
master()
{
	int ind;
	long pollingtime;
	struct timeval wait;
	struct timeval time;
	struct timezone tzone;
	struct tsp *msg, to;
	struct sockaddr_in saveaddr;
	int findhost();
	char *date();
	struct tsp *readmsg();
	struct tsp *answer, *acksend();
	char olddate[32];
	struct sockaddr_in server;
	register struct netinfo *ntp;

#ifdef MEASURE
	if (fp == NULL) {
		fp = fopen(_PATH_MASTERLOG, "w");
		setlinebuf(fp);
	}
#endif

	syslog(LOG_INFO, "This machine is master");
	if (trace)
		fprintf(fd, "THIS MACHINE IS MASTER\n");

	for (ntp = nettab; ntp != NULL; ntp = ntp->next)
		if (ntp->status == MASTER)
			masterup(ntp);
	pollingtime = 0;

loop:
	(void)gettimeofday(&time, (struct timezone *)0);
	if (time.tv_sec >= pollingtime) {
		pollingtime = time.tv_sec + SAMPLEINTVL;
		synch(0L);

		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
			to.tsp_type = TSP_LOOP;
			to.tsp_vers = TSPVERSION;
			to.tsp_seq = sequence++;
			to.tsp_hopcnt = 10;
			(void)strcpy(to.tsp_name, hostname);
			bytenetorder(&to);
			if (sendto(sock, (char *)&to, sizeof(struct tsp), 0,
			    (struct sockaddr *)&ntp->dest_addr,
			    sizeof(struct sockaddr_in)) < 0) {
				syslog(LOG_ERR, "sendto: %m");
				exit(1);
			}
		}
	}

	wait.tv_sec = pollingtime - time.tv_sec;
	wait.tv_usec = 0;
	msg = readmsg(TSP_ANY, (char *)ANYADDR, &wait, (struct netinfo *)NULL);
	if (msg != NULL) {
		switch (msg->tsp_type) {

		case TSP_MASTERREQ:
			break;
		case TSP_SLAVEUP:
			ind = addmach(msg->tsp_name, &from);
			newslave(ind, msg->tsp_seq);
			break;
		case TSP_SETDATE:
			saveaddr = from;
			/*
			 * the following line is necessary due to syslog
			 * calling ctime() which clobbers the static buffer
			 */
			(void)strcpy(olddate, date());
			(void)gettimeofday(&time, &tzone);
			time.tv_sec = msg->tsp_time.tv_sec;
			time.tv_usec = msg->tsp_time.tv_usec;
			logwtmp("|", "date", "");
			(void)settimeofday(&time, &tzone);
			logwtmp("}", "date", "");
			syslog(LOG_NOTICE, "date changed from: %s", olddate);
			msg->tsp_type = TSP_DATEACK;
			msg->tsp_vers = TSPVERSION;
			(void)strcpy(msg->tsp_name, hostname);
			bytenetorder(msg);
			if (sendto(sock, (char *)msg, sizeof(struct tsp), 0,
			    (struct sockaddr *)&saveaddr,
			    sizeof(struct sockaddr_in)) < 0) {
				syslog(LOG_ERR, "sendto: %m");
				exit(1);
			}
			spreadtime();
			pollingtime = 0;
			break;
		case TSP_SETDATEREQ:
			ind = findhost(msg->tsp_name);
			if (ind < 0) { 
			    syslog(LOG_WARNING,
				"DATEREQ from uncontrolled machine");
			    break;
			}
			if (hp[ind].seq !=  msg->tsp_seq) {
				hp[ind].seq = msg->tsp_seq;
				/*
				 * the following line is necessary due to syslog
				 * calling ctime() which clobbers the static buffer
				 */
				(void)strcpy(olddate, date());
				(void)gettimeofday(&time, &tzone);
				time.tv_sec = msg->tsp_time.tv_sec;
				time.tv_usec = msg->tsp_time.tv_usec;
				logwtmp("|", "date", "");
				(void)settimeofday(&time, &tzone);
				logwtmp("{", "date", "");
				syslog(LOG_NOTICE,
				    "date changed by %s from: %s",
				    msg->tsp_name, olddate);
				spreadtime();
				pollingtime = 0;
			}
			break;
		case TSP_MSITE:
		case TSP_MSITEREQ:
			break;
		case TSP_TRACEON:
			if (!(trace)) {
				fd = fopen(tracefile, "w");
				setlinebuf(fd);
				fprintf(fd, "Tracing started on: %s\n\n", 
							date());
			}
			trace = ON;
			break;
		case TSP_TRACEOFF:
			if (trace) {
				fprintf(fd, "Tracing ended on: %s\n", date());
				(void)fclose(fd);
			}
#ifdef GPROF
			moncontrol(0);
			_mcleanup();
			moncontrol(1);
#endif
			trace = OFF;
			break;
		case TSP_ELECTION:
			to.tsp_type = TSP_QUIT;
			(void)strcpy(to.tsp_name, hostname);
			server = from;
			answer = acksend(&to, &server, msg->tsp_name, TSP_ACK,
			    (struct netinfo *)NULL);
			if (answer == NULL) {
				syslog(LOG_ERR, "election error");
			} else {
				(void) addmach(msg->tsp_name, &from);
			}
			pollingtime = 0;
			break;
		case TSP_CONFLICT:
			/*
			 * After a network partition, there can be 
			 * more than one master: the first slave to 
			 * come up will notify here the situation.
			 */

			(void)strcpy(to.tsp_name, hostname);

			if (fromnet == NULL)
				break;
			for(;;) {
				to.tsp_type = TSP_RESOLVE;
				answer = acksend(&to, &fromnet->dest_addr,
				    (char *)ANYADDR, TSP_MASTERACK, fromnet);
				if (answer == NULL)
					break;
				to.tsp_type = TSP_QUIT;
				server = from;
				msg = acksend(&to, &server, answer->tsp_name,
				    TSP_ACK, (struct netinfo *)NULL);
				if (msg == NULL) {
					syslog(LOG_ERR, "error on sending QUIT");
				} else {
					(void) addmach(answer->tsp_name, &from);
				}
			}
			masterup(fromnet);
			pollingtime = 0;
			break;
		case TSP_RESOLVE:
			/*
			 * do not want to call synch() while waiting
			 * to be killed!
			 */
			(void)gettimeofday(&time, (struct timezone *)0);
			pollingtime = time.tv_sec + SAMPLEINTVL;
			break;
		case TSP_QUIT:
			/* become slave */
#ifdef MEASURE
			if (fp != NULL) {
				(void)fclose(fp);
				fp = NULL;
			}
#endif
			longjmp(jmpenv, 2);
			break;
		case TSP_LOOP:
			/*
			 * We should not have received this from a net
			 * we are master on.  There must be two masters
			 * in this case.
			 */
			to.tsp_type = TSP_QUIT;
			(void)strcpy(to.tsp_name, hostname);
			server = from;
			answer = acksend(&to, &server, msg->tsp_name, TSP_ACK,
				(struct netinfo *)NULL);
			if (answer == NULL) {
				syslog(LOG_WARNING,
				    "loop breakage: no reply to QUIT");
			} else {
				(void)addmach(msg->tsp_name, &from);
			}
		default:
			if (trace) {
				fprintf(fd, "garbage: ");
				print(msg, &from);
			}
			break;
		}
	}
	goto loop;
}
int main(int argc, char *argv[]) {
	int check, k, i;
	int number;
	char command[10];
	pthread_t p_rc, *p_pass;
	
	k = 0;
	
	synch(main);
	
	synch(roll);
	
	synch(pass);
	
	check = pthread_create(&p_rc, NULL, &roller_coaster, NULL);
	if(check!=0) {
		printf("Problem to create roller_coaster thread\n");
		
		return(7);
    }
    
    while(1) {
		printf("For new passengers press 'new' and the number of passengers\n");
		printf("Else for exit press 'exit'\n");
		printf("wait_pas: %d\n",wait_pas);
		scanf(" %9s",command);
		
		if(strcmp(command,"new")==0){
			scanf("%d",&number);
			wait_pas = wait_pas + number;
			
			p_pass = (pthread_t *)malloc(sizeof(pthread_t)*number);
			if(p_pass==NULL){                                        
				printf("Problem with memory allocation\n");

				return(2);
			}
			for(i=0;i<number;i++){
				
				synch_begin(main);
				
				k++;
				
				check = pthread_create(&p_pass[i], NULL, &passenger, &k);
				if(check!=0) {
					printf("Problem to create %d thread\n", i);
					free(p_pass);
					
					return(7);
				}
	
				synch_wait();
				
				synch_end(main);
			}
			free(p_pass);
		}
		else if(strcmp(command,"exit")==0){
			printf("Roller coaster has closed for today!\n");
			break;
		}
		else{ 
			printf("Try again!\n");
			continue;
		}
		printf("wait_pas: %d\n",wait_pas);
		
		synch_begin(roll);
		
		synch_notify();
		
		synch_end(roll);
		
		synch_begin(main);
		
		synch_wait();
		
		synch_end(main);
	}
    
    return (0);
}
unsigned char mu_cre_file(void)
{
	unsigned char		*inadr[2], *c, exit_stat;
	enum db_acc_method	temp_acc_meth;
	uint4			lcnt, retadr[2];
	int4			blk_init_size, initial_alq, free_blocks;
	gtm_uint64_t		free_blocks_ll, blocks_for_extension;
	char			buff[GLO_NAME_MAXLEN], fn_buff[MAX_FN_LEN];
	unsigned int		status;
	int			free_space;
	struct FAB		*fcb;
	struct NAM		nam;
	gds_file_id		new_id;
	io_status_block_disk	iosb;
	char			node[16];
	short			len;
	struct {
		short	blen;
		short	code;
		char	*buf;
		short	*len;
		int4	terminator;
	} item = {15, SYI$_NODENAME, &node, &len, 0};
	$DESCRIPTOR(desc, buff);

	exit_stat = EXIT_NRM;
/* The following calculations should duplicate the BT_SIZE macro from GDSBT and the LOCK_BLOCK macro from GDSFHEAD.H,
 * but without using a sgmnt_data which is not yet set up at this point
 */

#ifdef GT_CX_DEF
	/* This section needs serious chnages for the fileheader changes in V5 if it is ever resurrected */
	over_head = DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT
			+ (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS) + 1) * SIZEOF(bt_rec), DISK_BLOCK_SIZE);
	if (gv_cur_region->dyn.addr->acc_meth == dba_bg)
	{
		free_space = over_head - DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT
			+ (gv_cur_region->dyn.addr->global_buffers + getprime(gv_cur_region->dyn.addr->global_buffers) + 1)
				* SIZEOF(bt_rec), DISK_BLOCK_SIZE);
		over_head += gv_cur_region->dyn.addr->lock_space ? gv_cur_region->dyn.addr->lock_space
								 : DEF_LOCK_SIZE / OS_PAGELET_SIZE;
	} else if (gv_cur_region->dyn.addr->acc_meth == dba_mm)
	{
		free_space = over_head - DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT, DISK_BLOCK_SIZE);
		if (gv_cur_region->dyn.addr->lock_space)
		{
			over_head += gv_cur_region->dyn.addr->lock_space;
			free_space += gv_cur_region->dyn.addr->lock_space;
		} else
		{
			over_head += DEF_LOCK_SIZE / OS_PAGELET_SIZE;
			free_space += DEF_LOCK_SIZE / OS_PAGELET_SIZE;
		}
	}
	free_space *= DISK_BLOCK_SIZE;
#else
	assert(START_VBN_CURRENT > DIVIDE_ROUND_UP(SIZEOF_FILE_HDR_DFLT, DISK_BLOCK_SIZE));
	free_space = ((START_VBN_CURRENT - 1) * DISK_BLOCK_SIZE) - SIZEOF_FILE_HDR_DFLT;
#endif
	switch (gv_cur_region->dyn.addr->acc_meth)
	{
		case dba_bg:
		case dba_mm:
			mu_cre_vms_structs(gv_cur_region);
			fcb = ((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->fab;
			cs_addrs = &((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->s_addrs;

			fcb->fab$b_shr &= FAB$M_NIL;	/* No access to this file while it is created */
			fcb->fab$l_nam = &nam;
			nam = cc$rms_nam;
			/* There are (bplmap - 1) non-bitmap blocks per bitmap, so add (bplmap - 2) to number of non-bitmap blocks
			 * and divide by (bplmap - 1) to get total number of bitmaps for expanded database. (must round up in this
			 * manner as every non-bitmap block must have an associated bitmap)
			*/
			fcb->fab$l_alq += DIVIDE_ROUND_UP(fcb->fab$l_alq, BLKS_PER_LMAP - 1);	/* Bitmaps */
			blk_init_size = fcb->fab$l_alq;
			fcb->fab$l_alq *= BLK_SIZE / DISK_BLOCK_SIZE;
			fcb->fab$l_alq += START_VBN_CURRENT - 1;
			initial_alq = fcb->fab$l_alq;
			fcb->fab$w_mrs = 512;				/* no longer a relevent field to us */
			break;
		case dba_usr:
			util_out_print("Database file for region !AD not created; access method is not GDS.", TRUE,
				REG_LEN_STR(gv_cur_region));
			return EXIT_WRN;
		default:
			gtm_putmsg(VARLSTCNT(1) ERR_BADACCMTHD);
			return EXIT_ERR;
	}
	nam.nam$b_ess = SIZEOF(fn_buff);
	nam.nam$l_esa = fn_buff;
	nam.nam$b_nop |= NAM$M_SYNCHK;
	status = sys$parse(fcb, 0, 0);
	if (RMS$_NORMAL != status)
	{
		gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna, status, 0, fcb->fab$l_stv, 0);
		return EXIT_ERR;
	}
	if (nam.nam$b_node != 0)
	{
		status = sys$getsyiw(EFN$C_ENF, 0, 0, &item, &iosb, 0, 0);
		if (SS$_NORMAL == status)
			status = iosb.cond;
		if (SS$_NORMAL == status)
		{
			if (len == nam.nam$b_node-2 && !memcmp(nam.nam$l_esa, node, len))
			{
				fcb->fab$l_fna = nam.nam$l_esa + nam.nam$b_node;
				fcb->fab$b_fns = nam.nam$b_esl - nam.nam$b_node;
			}
		} else
		{
			util_out_print("Could not get node for !AD.", TRUE, REG_LEN_STR(gv_cur_region));
			exit_stat = EXIT_WRN;
		}
	}
	assert(gv_cur_region->dyn.addr->acc_meth == dba_bg || gv_cur_region->dyn.addr->acc_meth == dba_mm);
	nam.nam$l_esa = NULL;
	nam.nam$b_esl = 0;
	status = sys$create(fcb);
	if (status != RMS$_CREATED && status != RMS$_FILEPURGED)
	{
		switch(status)
		{
			case RMS$_FLK:
		 		util_out_print("Database file for region !AD not created; currently locked by another user.", TRUE,
					REG_LEN_STR(gv_cur_region));
				exit_stat = EXIT_INF;
				break;
			case RMS$_NORMAL:
		 		util_out_print("Database file for region !AD not created; already exists.", TRUE,
					REG_LEN_STR(gv_cur_region));
				exit_stat = EXIT_INF;
				break;
			case RMS$_SUPPORT:
				util_out_print("Database file for region !AD not created; cannot create across network.", TRUE,
					REG_LEN_STR(gv_cur_region));
				exit_stat = EXIT_WRN;
				break;
			case RMS$_FUL:
				send_msg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna,
					status, 0, fcb->fab$l_stv, 0);
				/* intentionally falling through */
			default:
				gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna,
					status, 0, fcb->fab$l_stv, 0);
				exit_stat = EXIT_ERR;
		}
		sys$dassgn(fcb->fab$l_stv);
		return exit_stat;
	}

	memcpy(new_id.dvi, nam.nam$t_dvi, SIZEOF(nam.nam$t_dvi));
	memcpy(new_id.did, nam.nam$w_did, SIZEOF(nam.nam$w_did));
	memcpy(new_id.fid, nam.nam$w_fid, SIZEOF(nam.nam$w_fid));
	global_name("GT$S", &new_id, buff);		/* 2nd parm is actually a gds_file_id * in global_name */
	desc.dsc$w_length = buff[0];			/* By definition, a gds_file_id is dvi,fid,did from nam */
	desc.dsc$a_pointer = &buff[1];
	cs_addrs->db_addrs[0] = cs_addrs->db_addrs[1] = inadr[0] = inadr[1] = inadr;	/* used to determine p0 or p1 allocation */
	status = init_sec(cs_addrs->db_addrs, &desc, fcb->fab$l_stv, (START_VBN_CURRENT - 1),
			  SEC$M_DZRO|SEC$M_GBL|SEC$M_WRT|SEC$M_EXPREG);
	if ((SS$_CREATED != status) && (SS$_NORMAL != status))
	{
		gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna, status, 0, fcb->fab$l_stv, 0);
		sys$dassgn(fcb->fab$l_stv);
		return EXIT_ERR;
	}
	cs_data = (sgmnt_data *)cs_addrs->db_addrs[0];
	memset(cs_data, 0, SIZEOF_FILE_HDR_DFLT);
	cs_data->createinprogress = TRUE;
	cs_data->trans_hist.total_blks = (initial_alq - (START_VBN_CURRENT - 1)) / (BLK_SIZE / DISK_BLOCK_SIZE);
	/* assert that total_blks stored in file-header = non-bitmap blocks (initial allocation) + bitmap blocks */
	assert(cs_data->trans_hist.total_blks == gv_cur_region->dyn.addr->allocation +
				DIVIDE_ROUND_UP(gv_cur_region->dyn.addr->allocation, BLKS_PER_LMAP - 1));
	cs_data->start_vbn = START_VBN_CURRENT;
	temp_acc_meth = gv_cur_region->dyn.addr->acc_meth;
	cs_data->acc_meth = gv_cur_region->dyn.addr->acc_meth = dba_bg;
	cs_data->extension_size = gv_cur_region->dyn.addr->ext_blk_count;
	mucregini(blk_init_size);
	cs_addrs->hdr->free_space = free_space;
#ifndef GT_CX_DEF
	cs_addrs->hdr->unbacked_cache = TRUE;
#endif
	cs_data->acc_meth = gv_cur_region->dyn.addr->acc_meth = temp_acc_meth;
	cs_data->createinprogress = FALSE;
	if (SS$_NORMAL == (status = disk_block_available(fcb->fab$l_stv, &free_blocks)))
	{
		blocks_for_extension = (cs_data->blk_size / DISK_BLOCK_SIZE *
				  (DIVIDE_ROUND_UP(EXTEND_WARNING_FACTOR * (gtm_uint64_t)cs_data->extension_size, BLKS_PER_LMAP - 1)
					 + EXTEND_WARNING_FACTOR * (gtm_uint64_t)cs_data->extension_size));
		if ((gtm_uint64_t)free_blocks < blocks_for_extension)
		{
			free_blocks_ll = (gtm_uint64_t)free_blocks;
			gtm_putmsg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, fcb->fab$b_fns, fcb->fab$l_fna, EXTEND_WARNING_FACTOR,
					&blocks_for_extension, DISK_BLOCK_SIZE, &free_blocks_ll);
			send_msg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, fcb->fab$b_fns, fcb->fab$l_fna, EXTEND_WARNING_FACTOR,
					&blocks_for_extension, DISK_BLOCK_SIZE, &free_blocks_ll);
		}
	}
	if (SS$_NORMAL == (status = sys$updsec(((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->s_addrs.db_addrs,
			NULL, PSL$C_USER, 0, efn_immed_wait, &iosb, NULL, 0)))
	{
		status = sys$synch(efn_immed_wait, &iosb);
		if (SS$_NORMAL == status)
			status = iosb.cond;
	} else  if (SS$_NOTMODIFIED == status)
		status = SS$_NORMAL;
	if (SS$_NORMAL == status)
		status = del_sec(SEC$M_GBL, &desc, 0);
	if (SS$_NORMAL == status)
		status = sys$deltva(cs_addrs->db_addrs, retadr, PSL$C_USER);
	if (SS$_NORMAL == status)
		status = sys$dassgn(fcb->fab$l_stv);
	if (SS$_NORMAL == status)
	{
	 	util_out_print("Database file for region !AD created.", TRUE, REG_LEN_STR(gv_cur_region));
		/* the open and close are an attempt to ensure that the file is available, not under the control of an ACP,
		 * before MUPIP exits */
		fcb->fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_UPI;
		fcb->fab$l_fop = 0;
		for (lcnt = 1;  (60 * MAX_OPEN_RETRY) >= lcnt;  lcnt++)
		{	/* per VMS engineering a delay is expected.  We will wait up to an hour as a
			 * Delete Global Section operation is essentially and inherently asynchronous in nature
			 * and could take an arbitrary amount of time.
			 */
			if (RMS$_FLK != (status = sys$open(fcb, NULL, NULL)))
				break;
			wcs_sleep(lcnt);
		}
		assert(RMS$_NORMAL == status);
		if (RMS$_NORMAL == status)
		{
			status = sys$close(fcb);
			assert(RMS$_NORMAL == status);
		}
		if (RMS$_NORMAL != status)
			exit_stat = EXIT_WRN;
	} else
		exit_stat = EXIT_ERR;
	if (RMS$_NORMAL != status)
		gtm_putmsg(VARLSTCNT(8) ERR_DBFILERR, 2, fcb->fab$b_fns, fcb->fab$l_fna, status, 0, fcb->fab$l_stv, 0);
	if ((MAX_RMS_RECORDSIZE - SIZEOF(shmpool_blk_hdr)) < cs_data->blk_size)
		gtm_putmsg(VARLSTCNT(5) ERR_MUNOSTRMBKUP, 3, fcb->fab$b_fns, fcb->fab$l_fna, 32 * 1024 - DISK_BLOCK_SIZE);
	return exit_stat;
}
Exemple #18
0
glob_t * io_loadEv(defs *d) {
	// If data is loaded free it up
	if (d->nfiles != 0) {
		tffree(d->files, d->nfiles);
		d->files = NULL;
		d->nfiles = 0;
		d->has3 = 0;
	}

	// Prepare the pathname for the current event
	char *path = d->glb->gl_pathv[d->currentdir];

	// Prepare a new glob
	glob_t *glb = filelist(path, getConfigAsString(config, NAME_Z, DEFAULT_Z));
	glob_t *glbt =filelist(path, getConfigAsString(config, NAME_T, DEFAULT_T));

	// Set HAS to 0
	d->has = findHas(glb);

	// Load the Z components
	int nfiles = 0;
	tf *files = io_loadZ(glb, &nfiles);

	if (getConfigAsBoolean(config, NAME_LOAD, DEFAULT_LOAD)) {
		// Load N components
		glob_t *glbn = filelist(path, getConfigAsString(config, NAME_N, DEFAULT_N));
		io_loadN(glbn, files, nfiles);
		killGlob(glbn);
		
		// Load E
		glob_t *glbe = filelist(path, getConfigAsString(config, NAME_E, DEFAULT_E));
		io_loadE(glbe, files, nfiles);
		killGlob(glbe);

		// Load R components
		glob_t *glbr = filelist(path, getConfigAsString(config, NAME_R, DEFAULT_R));
		io_loadR(glbr, files, nfiles);
		killGlob(glbr);
			
		// Load T
		glob_t *glbt = filelist(path, getConfigAsString(config, NAME_T, DEFAULT_T));
		io_loadT(glbt, files, nfiles);
		
		d->has3 = 1;
	}

	// Find the filters in use for this event
	if (getConfigAsNumber(config, NAME_PICK, DEFAULT_PICK) == P) 
		d->filter = findFilters(glb, &d->lp, &d->hp);

	else if (getConfigAsNumber(config, NAME_PICK, DEFAULT_PICK) == S)
		d->filter = findFilters(glbt, &d->lp, &d->hp);

	else {
		sprintf(message, " filters used couldn't be loaded ");
		alert(WARNING);
	}

	//kill globs
	killGlob(glb);
	killGlob(glbt);


	// Check the files
	if (nfiles != 0) {
		// Check that we have picks
		checkTREF(files, nfiles);
		
		// Sort the files 
		qsort(files, nfiles, sizeof(tf), sortDist);
		
		// Synch Time
		synch(files, nfiles);
	}

	// Set Aligmenmode
	d->alig = (d->has) ? ALIGF : ALIGA;

	// Set the filterneed if needed
	if (d->filter)
		d->needfilter = 1;

	// Set offset to 0
	d->offset = 0;

	// Prepare to return
	d->files  = files;
	d->nfiles = nfiles;

	// Adjust the curent pointer
	io_AdjustCurrent(d);

	// Done
	return NULL;
}
Exemple #19
0
void
regopt(Prog *firstp)
{
	Reg *r, *r1;
	Prog *p;
	int i, z, nr;
	uint32 vreg;
	Bits bit;

	if(first) {
		fmtinstall('Q', Qconv);
		exregoffset = D_DI;	// no externals
		first = 0;
	}
	
	fixjmp(firstp);

	// count instructions
	nr = 0;
	for(p=firstp; p!=P; p=p->link)
		nr++;
	// if too big dont bother
	if(nr >= 10000) {
//		print("********** %S is too big (%d)\n", curfn->nname->sym, nr);
		return;
	}

	r1 = R;
	firstr = R;
	lastr = R;
	
	/*
	 * control flow is more complicated in generated go code
	 * than in generated c code.  define pseudo-variables for
	 * registers, so we have complete register usage information.
	 */
	nvar = NREGVAR;
	memset(var, 0, NREGVAR*sizeof var[0]);
	for(i=0; i<NREGVAR; i++)
		var[i].node = newname(lookup(regname[i]));

	regbits = RtoB(D_SP);
	for(z=0; z<BITS; z++) {
		externs.b[z] = 0;
		params.b[z] = 0;
		consts.b[z] = 0;
		addrs.b[z] = 0;
		ovar.b[z] = 0;
	}

	// build list of return variables
	setoutvar();

	/*
	 * pass 1
	 * build aux data structure
	 * allocate pcs
	 * find use and set of variables
	 */
	nr = 0;
	for(p=firstp; p!=P; p=p->link) {
		switch(p->as) {
		case ADATA:
		case AGLOBL:
		case ANAME:
		case ASIGNAME:
			continue;
		}
		r = rega();
		nr++;
		if(firstr == R) {
			firstr = r;
			lastr = r;
		} else {
			lastr->link = r;
			r->p1 = lastr;
			lastr->s1 = r;
			lastr = r;
		}
		r->prog = p;
		p->reg = r;

		r1 = r->p1;
		if(r1 != R) {
			switch(r1->prog->as) {
			case ARET:
			case AJMP:
			case AIRETL:
				r->p1 = R;
				r1->s1 = R;
			}
		}

		bit = mkvar(r, &p->from);
		if(bany(&bit))
		switch(p->as) {
		/*
		 * funny
		 */
		case ALEAL:
		case AFMOVL: 
		case AFMOVW:
		case AFMOVV:
			setaddrs(bit);
			break;

		/*
		 * left side read
		 */
		default:
			for(z=0; z<BITS; z++)
				r->use1.b[z] |= bit.b[z];
			break;

		/*
		 * left side read+write
		 */
		case AXCHGB:
		case AXCHGW:
		case AXCHGL:
			for(z=0; z<BITS; z++) {
				r->use1.b[z] |= bit.b[z];
				r->set.b[z] |= bit.b[z];
			}
			break;
		}

		bit = mkvar(r, &p->to);
		if(bany(&bit))
		switch(p->as) {
		default:
			yyerror("reg: unknown op: %A", p->as);
			break;

		/*
		 * right side read
		 */
		case ACMPB:
		case ACMPL:
		case ACMPW:
		case ATESTB:
		case ATESTL:
		case ATESTW:
			for(z=0; z<BITS; z++)
				r->use2.b[z] |= bit.b[z];
			break;

		/*
		 * right side write
		 */
		case AFSTSW:
		case ALEAL:
		case ANOP:
		case AMOVL:
		case AMOVB:
		case AMOVW:
		case AMOVBLSX:
		case AMOVBLZX:
		case AMOVBWSX:
		case AMOVBWZX:
		case AMOVWLSX:
		case AMOVWLZX:
		case APOPL:
			for(z=0; z<BITS; z++)
				r->set.b[z] |= bit.b[z];
			break;

		/*
		 * right side read+write
		 */
		case AINCB:
		case AINCL:
		case AINCW:
		case ADECB:
		case ADECL:
		case ADECW:

		case AADDB:
		case AADDL:
		case AADDW:
		case AANDB:
		case AANDL:
		case AANDW:
		case ASUBB:
		case ASUBL:
		case ASUBW:
		case AORB:
		case AORL:
		case AORW:
		case AXORB:
		case AXORL:
		case AXORW:
		case ASALB:
		case ASALL:
		case ASALW:
		case ASARB:
		case ASARL:
		case ASARW:
		case ARCLB:
		case ARCLL:
		case ARCLW:
		case ARCRB:
		case ARCRL:
		case ARCRW:
		case AROLB:
		case AROLL:
		case AROLW:
		case ARORB:
		case ARORL:
		case ARORW:
		case ASHLB:
		case ASHLL:
		case ASHLW:
		case ASHRB:
		case ASHRL:
		case ASHRW:
		case AIMULL:
		case AIMULW:
		case ANEGB:
		case ANEGL:
		case ANEGW:
		case ANOTB:
		case ANOTL:
		case ANOTW:
		case AADCL:
		case ASBBL:

		case ASETCC:
		case ASETCS:
		case ASETEQ:
		case ASETGE:
		case ASETGT:
		case ASETHI:
		case ASETLE:
		case ASETLS:
		case ASETLT:
		case ASETMI:
		case ASETNE:
		case ASETOC:
		case ASETOS:
		case ASETPC:
		case ASETPL:
		case ASETPS:

		case AXCHGB:
		case AXCHGW:
		case AXCHGL:
			for(z=0; z<BITS; z++) {
				r->set.b[z] |= bit.b[z];
				r->use2.b[z] |= bit.b[z];
			}
			break;

		/*
		 * funny
		 */
		case AFMOVDP:
		case AFMOVFP:
		case AFMOVLP:
		case AFMOVVP:
		case AFMOVWP:
		case ACALL:
			setaddrs(bit);
			break;
		}

		switch(p->as) {
		case AIMULL:
		case AIMULW:
			if(p->to.type != D_NONE)
				break;

		case AIDIVL:
		case AIDIVW:
		case ADIVL:
		case ADIVW:
		case AMULL:
		case AMULW:
			r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX);
			r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DX);
			break;

		case AIDIVB:
		case AIMULB:
		case ADIVB:
		case AMULB:
			r->set.b[0] |= RtoB(D_AX);
			r->use1.b[0] |= RtoB(D_AX);
			break;

		case ACWD:
			r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX);
			r->use1.b[0] |= RtoB(D_AX);
			break;

		case ACDQ:
			r->set.b[0] |= RtoB(D_DX);
			r->use1.b[0] |= RtoB(D_AX);
			break;

		case AREP:
		case AREPN:
		case ALOOP:
		case ALOOPEQ:
		case ALOOPNE:
			r->set.b[0] |= RtoB(D_CX);
			r->use1.b[0] |= RtoB(D_CX);
			break;

		case AMOVSB:
		case AMOVSL:
		case AMOVSW:
		case ACMPSB:
		case ACMPSL:
		case ACMPSW:
			r->set.b[0] |= RtoB(D_SI) | RtoB(D_DI);
			r->use1.b[0] |= RtoB(D_SI) | RtoB(D_DI);
			break;

		case ASTOSB:
		case ASTOSL:
		case ASTOSW:
		case ASCASB:
		case ASCASL:
		case ASCASW:
			r->set.b[0] |= RtoB(D_DI);
			r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DI);
			break;

		case AINSB:
		case AINSL:
		case AINSW:
			r->set.b[0] |= RtoB(D_DX) | RtoB(D_DI);
			r->use1.b[0] |= RtoB(D_DI);
			break;

		case AOUTSB:
		case AOUTSL:
		case AOUTSW:
			r->set.b[0] |= RtoB(D_DI);
			r->use1.b[0] |= RtoB(D_DX) | RtoB(D_DI);
			break;
		}
	}
	if(firstr == R)
		return;

	for(i=0; i<nvar; i++) {
		Var *v = var+i;
		if(v->addr) {
			bit = blsh(i);
			for(z=0; z<BITS; z++)
				addrs.b[z] |= bit.b[z];
		}

//		print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n",
//			i, v->addr, v->etype, v->width, v->sym, v->offset);
	}

	if(debug['R'] && debug['v'])
		dumpit("pass1", firstr);

	/*
	 * pass 2
	 * turn branch references to pointers
	 * build back pointers
	 */
	for(r=firstr; r!=R; r=r->link) {
		p = r->prog;
		if(p->to.type == D_BRANCH) {
			if(p->to.branch == P)
				fatal("pnil %P", p);
			r1 = p->to.branch->reg;
			if(r1 == R)
				fatal("rnil %P", p);
			if(r1 == r) {
				//fatal("ref to self %P", p);
				continue;
			}
			r->s2 = r1;
			r->p2link = r1->p2;
			r1->p2 = r;
		}
	}

	if(debug['R'] && debug['v'])
		dumpit("pass2", firstr);

	/*
	 * pass 2.5
	 * find looping structure
	 */
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	change = 0;
	loopit(firstr, nr);

	if(debug['R'] && debug['v'])
		dumpit("pass2.5", firstr);

	/*
	 * pass 3
	 * iterate propagating usage
	 * 	back until flow graph is complete
	 */
loop1:
	change = 0;
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	for(r = firstr; r != R; r = r->link)
		if(r->prog->as == ARET)
			prop(r, zbits, zbits);
loop11:
	/* pick up unreachable code */
	i = 0;
	for(r = firstr; r != R; r = r1) {
		r1 = r->link;
		if(r1 && r1->active && !r->active) {
			prop(r, zbits, zbits);
			i = 1;
		}
	}
	if(i)
		goto loop11;
	if(change)
		goto loop1;

	if(debug['R'] && debug['v'])
		dumpit("pass3", firstr);

	/*
	 * pass 4
	 * iterate propagating register/variable synchrony
	 * 	forward until graph is complete
	 */
loop2:
	change = 0;
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	synch(firstr, zbits);
	if(change)
		goto loop2;

	if(debug['R'] && debug['v'])
		dumpit("pass4", firstr);

	/*
	 * pass 4.5
	 * move register pseudo-variables into regu.
	 */
	for(r = firstr; r != R; r = r->link) {
		r->regu = (r->refbehind.b[0] | r->set.b[0]) & REGBITS;

		r->set.b[0] &= ~REGBITS;
		r->use1.b[0] &= ~REGBITS;
		r->use2.b[0] &= ~REGBITS;
		r->refbehind.b[0] &= ~REGBITS;
		r->refahead.b[0] &= ~REGBITS;
		r->calbehind.b[0] &= ~REGBITS;
		r->calahead.b[0] &= ~REGBITS;
		r->regdiff.b[0] &= ~REGBITS;
		r->act.b[0] &= ~REGBITS;
	}

	/*
	 * pass 5
	 * isolate regions
	 * calculate costs (paint1)
	 */
	r = firstr;
	if(r) {
		for(z=0; z<BITS; z++)
			bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
			  ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
		if(bany(&bit) && !r->refset) {
			// should never happen - all variables are preset
			if(debug['w'])
				print("%L: used and not set: %Q\n", r->prog->lineno, bit);
			r->refset = 1;
		}
	}
	for(r = firstr; r != R; r = r->link)
		r->act = zbits;
	rgp = region;
	nregion = 0;
	for(r = firstr; r != R; r = r->link) {
		for(z=0; z<BITS; z++)
			bit.b[z] = r->set.b[z] &
			  ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
		if(bany(&bit) && !r->refset) {
			if(debug['w'])
				print("%L: set and not used: %Q\n", r->prog->lineno, bit);
			r->refset = 1;
			excise(r);
		}
		for(z=0; z<BITS; z++)
			bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
		while(bany(&bit)) {
			i = bnum(bit);
			rgp->enter = r;
			rgp->varno = i;
			change = 0;
			paint1(r, i);
			bit.b[i/32] &= ~(1L<<(i%32));
			if(change <= 0)
				continue;
			rgp->cost = change;
			nregion++;
			if(nregion >= NRGN) {
				if(debug['R'] && debug['v'])
					print("too many regions\n");
				goto brk;
			}
			rgp++;
		}
	}
brk:
	qsort(region, nregion, sizeof(region[0]), rcmp);

	/*
	 * pass 6
	 * determine used registers (paint2)
	 * replace code (paint3)
	 */
	rgp = region;
	for(i=0; i<nregion; i++) {
		bit = blsh(rgp->varno);
		vreg = paint2(rgp->enter, rgp->varno);
		vreg = allreg(vreg, rgp);
		if(rgp->regno != 0)
			paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
		rgp++;
	}

	if(debug['R'] && debug['v'])
		dumpit("pass6", firstr);

	/*
	 * pass 7
	 * peep-hole on basic block
	 */
	if(!debug['R'] || debug['P']) {
		peep();
	}

	/*
	 * eliminate nops
	 * free aux structures
	 */
	for(p=firstp; p!=P; p=p->link) {
		while(p->link != P && p->link->as == ANOP)
			p->link = p->link->link;
		if(p->to.type == D_BRANCH)
			while(p->to.branch != P && p->to.branch->as == ANOP)
				p->to.branch = p->to.branch->link;
	}

	if(r1 != R) {
		r1->link = freer;
		freer = firstr;
	}

	if(debug['R']) {
		if(ostats.ncvtreg ||
		   ostats.nspill ||
		   ostats.nreload ||
		   ostats.ndelmov ||
		   ostats.nvar ||
		   ostats.naddr ||
		   0)
			print("\nstats\n");

		if(ostats.ncvtreg)
			print("	%4d cvtreg\n", ostats.ncvtreg);
		if(ostats.nspill)
			print("	%4d spill\n", ostats.nspill);
		if(ostats.nreload)
			print("	%4d reload\n", ostats.nreload);
		if(ostats.ndelmov)
			print("	%4d delmov\n", ostats.ndelmov);
		if(ostats.nvar)
			print("	%4d var\n", ostats.nvar);
		if(ostats.naddr)
			print("	%4d addr\n", ostats.naddr);

		memset(&ostats, 0, sizeof(ostats));
	}
}
Exemple #20
0
int
slave()
{
	int tries;
	long electiontime, refusetime, looktime, looptime, adjtime;
	u_short seq;
	long fastelection;
#define FASTTOUT 3
	struct in_addr cadr;
	struct timeval otime;
	struct sockaddr_in taddr;
	char tname[MAXHOSTNAMELEN];
	struct tsp *msg, to;
	struct timeval ntime, wait, tmptv;
	time_t tsp_time_sec;
	struct tsp *answer;
	int timeout();
	char olddate[32];
	char newdate[32];
	struct netinfo *ntp;
	struct hosttbl *htp;
	struct utmpx utx;


	old_slavenet = 0;
	seq = 0;
	refusetime = 0;
	adjtime = 0;

	(void)gettimeofday(&ntime, NULL);
	electiontime = ntime.tv_sec + delay2;
	fastelection = ntime.tv_sec + FASTTOUT;
	if (justquit)
		looktime = electiontime;
	else
		looktime = fastelection;
	looptime = fastelection;

	if (slavenet)
		xmit(TSP_SLAVEUP, 0, &slavenet->dest_addr);
	if (status & MASTER) {
		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
			if (ntp->status == MASTER)
				masterup(ntp);
		}
	}

loop:
	get_goodgroup(0);
	(void)gettimeofday(&ntime, NULL);
	if (ntime.tv_sec > electiontime) {
		if (trace)
			fprintf(fd, "election timer expired\n");
		longjmp(jmpenv, 1);
	}

	if (ntime.tv_sec >= looktime) {
		if (trace)
			fprintf(fd, "Looking for nets to master\n");

		if (Mflag && nignorednets > 0) {
			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
				if (ntp->status == IGNORE
				    || ntp->status == NOMASTER) {
					lookformaster(ntp);
					if (ntp->status == MASTER) {
						masterup(ntp);
					} else if (ntp->status == MASTER) {
						ntp->status = NOMASTER;
					}
				}
				if (ntp->status == MASTER
				    && --ntp->quit_count < 0)
					ntp->quit_count = 0;
			}
			makeslave(slavenet);	/* prune extras */
			setstatus();
		}
		(void)gettimeofday(&ntime, NULL);
		looktime = ntime.tv_sec + delay2;
	}
	if (ntime.tv_sec >= looptime) {
		if (trace)
			fprintf(fd, "Looking for loops\n");
		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
		    if (ntp->status == MASTER) {
			to.tsp_type = TSP_LOOP;
			to.tsp_vers = TSPVERSION;
			to.tsp_seq = sequence++;
			to.tsp_hopcnt = MAX_HOPCNT;
			(void)strcpy(to.tsp_name, hostname);
			bytenetorder(&to);
			if (sendto(sock, (char *)&to, sizeof(struct tsp), 0,
				   (struct sockaddr*)&ntp->dest_addr,
				   sizeof(ntp->dest_addr)) < 0) {
				trace_sendto_err(ntp->dest_addr.sin_addr);
			}
		    }
		}
		(void)gettimeofday(&ntime, NULL);
		looptime = ntime.tv_sec + delay2;
	}

	wait.tv_sec = min(electiontime,min(looktime,looptime)) - ntime.tv_sec;
	if (wait.tv_sec < 0)
		wait.tv_sec = 0;
	wait.tv_sec += FASTTOUT;
	wait.tv_usec = 0;
	msg = readmsg(TSP_ANY, ANYADDR, &wait, 0);

	if (msg != NULL) {
		/*
		 * filter stuff not for us
		 */
		switch (msg->tsp_type) {
		case TSP_SETDATE:
		case TSP_TRACEOFF:
		case TSP_TRACEON:
			/*
			 * XXX check to see they are from ourself
			 */
			break;

		case TSP_TEST:
		case TSP_MSITE:
			break;

		case TSP_MASTERUP:
			if (!fromnet) {
				if (trace) {
					fprintf(fd, "slave ignored: ");
					print(msg, &from);
				}
				goto loop;
			}
			break;

		default:
			if (!fromnet
			    || fromnet->status == IGNORE
			    || fromnet->status == NOMASTER) {
				if (trace) {
					fprintf(fd, "slave ignored: ");
					print(msg, &from);
				}
				goto loop;
			}
			break;
		}


		/*
		 * now process the message
		 */
		switch (msg->tsp_type) {

		case TSP_ADJTIME:
			if (fromnet != slavenet)
				break;
			if (!good_host_name(msg->tsp_name)) {
				syslog(LOG_NOTICE,
				   "attempted time adjustment by %s",
				       msg->tsp_name);
				suppress(&from, msg->tsp_name, fromnet);
				break;
			}
			/*
			 * Speed up loop detection in case we have a loop.
			 * Otherwise the clocks can race until the loop
			 * is found.
			 */
			(void)gettimeofday(&otime, NULL);
			if (adjtime < otime.tv_sec)
				looptime -= (looptime-otime.tv_sec)/2 + 1;

			setmaster(msg);
			if (seq != msg->tsp_seq) {
				seq = msg->tsp_seq;
				synch(tvtomsround(msg->tsp_time));
			}
			(void)gettimeofday(&ntime, NULL);
			electiontime = ntime.tv_sec + delay2;
			fastelection = ntime.tv_sec + FASTTOUT;
			adjtime = ntime.tv_sec + SAMPLEINTVL*2;
			break;

		case TSP_SETTIME:
			if (fromnet != slavenet)
				break;
			if (seq == msg->tsp_seq)
				break;
			seq = msg->tsp_seq;

			/* adjust time for residence on the queue */
			(void)gettimeofday(&otime, NULL);
			adj_msg_time(msg,&otime);
			/*
			 * the following line is necessary due to syslog
			 * calling ctime() which clobbers the static buffer
			 */
			(void)strcpy(olddate, date());
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));

			if (!good_host_name(msg->tsp_name)) {
				syslog(LOG_NOTICE,
			    "attempted time setting by untrusted %s to %s",
				       msg->tsp_name, newdate);
				suppress(&from, msg->tsp_name, fromnet);
				break;
			}

			setmaster(msg);
 			tmptv.tv_sec = msg->tsp_time.tv_sec;
 			tmptv.tv_usec = msg->tsp_time.tv_usec;
			timevalsub(&ntime, &tmptv, &otime);
			if (ntime.tv_sec < MAXADJ && ntime.tv_sec > -MAXADJ) {
				/*
				 * do not change the clock if we can adjust it
				 */
				synch(tvtomsround(ntime));
			} else {
				utx.ut_type = OLD_TIME;
				gettimeofday(&utx.ut_tv, NULL);
				pututxline(&utx);
				(void)settimeofday(&tmptv, 0);
				utx.ut_type = NEW_TIME;
				gettimeofday(&utx.ut_tv, NULL);
				pututxline(&utx);
				syslog(LOG_NOTICE,
				       "date changed by %s from %s",
					msg->tsp_name, olddate);
				if (status & MASTER)
					spreadtime();
			}
			(void)gettimeofday(&ntime, NULL);
			electiontime = ntime.tv_sec + delay2;
			fastelection = ntime.tv_sec + FASTTOUT;

/* This patches a bad protocol bug.  Imagine a system with several networks,
 * where there are a pair of redundant gateways between a pair of networks,
 * each running timed.  Assume that we start with a third machine mastering
 * one of the networks, and one of the gateways mastering the other.
 * Imagine that the third machine goes away and the non-master gateway
 * decides to replace it.  If things are timed just 'right,' we will have
 * each gateway mastering one network for a little while.  If a SETTIME
 * message gets into the network at that time, perhaps from the newly
 * masterful gateway as it was taking control, the SETTIME will loop
 * forever.  Each time a gateway receives it on its slave side, it will
 * call spreadtime to forward it on its mastered network.  We are now in
 * a permanent loop, since the SETTIME msgs will keep any clock
 * in the network from advancing.  Normally, the 'LOOP' stuff will detect
 * and correct the situation.  However, with the clocks stopped, the
 * 'looptime' timer cannot expire.  While they are in this state, the
 * masters will try to saturate the network with SETTIME packets.
 */
			looptime = ntime.tv_sec + (looptime-otime.tv_sec)/2-1;
			break;

		case TSP_MASTERUP:
			if (slavenet && fromnet != slavenet)
				break;
			if (!good_host_name(msg->tsp_name)) {
				suppress(&from, msg->tsp_name, fromnet);
				if (electiontime > fastelection)
					electiontime = fastelection;
				break;
			}
			makeslave(fromnet);
			setmaster(msg);
			setstatus();
			answerdelay();
			xmit(TSP_SLAVEUP, 0, &from);
			(void)gettimeofday(&ntime, NULL);
			electiontime = ntime.tv_sec + delay2;
			fastelection = ntime.tv_sec + FASTTOUT;
			refusetime = 0;
			break;

		case TSP_MASTERREQ:
			if (fromnet->status != SLAVE)
				break;
			(void)gettimeofday(&ntime, NULL);
			electiontime = ntime.tv_sec + delay2;
			break;

		case TSP_SETDATE:
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));
			schgdate(msg, newdate);
			break;

		case TSP_SETDATEREQ:
			if (fromnet->status != MASTER)
				break;
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));
			htp = findhost(msg->tsp_name);
			if (0 == htp) {
				syslog(LOG_WARNING,
				       "DATEREQ from uncontrolled machine");
				break;
			}
			if (!htp->good) {
				syslog(LOG_WARNING,
				"attempted date change by untrusted %s to %s",
				       htp->name, newdate);
				spreadtime();
				break;
			}
			schgdate(msg, newdate);
			break;

		case TSP_TRACEON:
			traceon();
			break;

		case TSP_TRACEOFF:
			traceoff("Tracing ended at %s\n");
			break;

		case TSP_SLAVEUP:
			newslave(msg);
			break;

		case TSP_ELECTION:
			if (fromnet->status == SLAVE) {
				(void)gettimeofday(&ntime, NULL);
				electiontime = ntime.tv_sec + delay2;
				fastelection = ntime.tv_sec + FASTTOUT;
				seq = 0;
				if (!good_host_name(msg->tsp_name)) {
					syslog(LOG_NOTICE,
					       "suppress election of %s",
					       msg->tsp_name);
					to.tsp_type = TSP_QUIT;
					electiontime = fastelection;
				} else if (cadr.s_addr != from.sin_addr.s_addr
					   && ntime.tv_sec < refusetime) {
/* if the candidate has to repeat itself, the old code would refuse it
 * the second time.  That would prevent elections.
 */
					to.tsp_type = TSP_REFUSE;
				} else {
					cadr.s_addr = from.sin_addr.s_addr;
					to.tsp_type = TSP_ACCEPT;
					refusetime = ntime.tv_sec + 30;
				}
				taddr = from;
				(void)strcpy(tname, msg->tsp_name);
				(void)strcpy(to.tsp_name, hostname);
				answerdelay();
				if (!acksend(&to, &taddr, tname,
					     TSP_ACK, 0, 0))
					syslog(LOG_WARNING,
					     "no answer from candidate %s\n",
					       tname);

			} else {	/* fromnet->status == MASTER */
				htp = addmach(msg->tsp_name, &from,fromnet);
				to.tsp_type = TSP_QUIT;
				(void)strcpy(to.tsp_name, hostname);
				if (!acksend(&to, &htp->addr, htp->name,
					     TSP_ACK, 0, htp->noanswer)) {
					syslog(LOG_ERR,
					  "no reply from %s to ELECTION-QUIT",
					       htp->name);
					(void)remmach(htp);
				}
			}
			break;

		case TSP_CONFLICT:
			if (fromnet->status != MASTER)
				break;
			/*
			 * After a network partition, there can be
			 * more than one master: the first slave to
			 * come up will notify here the situation.
			 */
			(void)strcpy(to.tsp_name, hostname);

			/* The other master often gets into the same state,
			 * with boring results.
			 */
			ntp = fromnet;	/* (acksend() can leave fromnet=0 */
			for (tries = 0; tries < 3; tries++) {
				to.tsp_type = TSP_RESOLVE;
				answer = acksend(&to, &ntp->dest_addr,
						 ANYADDR, TSP_MASTERACK,
						 ntp, 0);
				if (answer == NULL)
					break;
				htp = addmach(answer->tsp_name,&from,ntp);
				to.tsp_type = TSP_QUIT;
				answer = acksend(&to, &htp->addr, htp->name,
						 TSP_ACK, 0, htp->noanswer);
				if (!answer) {
					syslog(LOG_WARNING,
				  "conflict error: no reply from %s to QUIT",
						htp->name);
					(void)remmach(htp);
				}
			}
			masterup(ntp);
			break;

		case TSP_MSITE:
			if (!slavenet)
				break;
			taddr = from;
			to.tsp_type = TSP_MSITEREQ;
			to.tsp_vers = TSPVERSION;
			to.tsp_seq = 0;
			(void)strcpy(to.tsp_name, hostname);
			answer = acksend(&to, &slavenet->dest_addr,
					 ANYADDR, TSP_ACK,
					 slavenet, 0);
			if (answer != NULL
			    && good_host_name(answer->tsp_name)) {
				setmaster(answer);
				to.tsp_type = TSP_ACK;
				(void)strcpy(to.tsp_name, answer->tsp_name);
				bytenetorder(&to);
				if (sendto(sock, (char *)&to,
					   sizeof(struct tsp), 0,
					   (struct sockaddr*)&taddr,
					   sizeof(taddr)) < 0) {
					trace_sendto_err(taddr.sin_addr);
				}
			}
			break;

		case TSP_MSITEREQ:
			break;

		case TSP_ACCEPT:
		case TSP_REFUSE:
		case TSP_RESOLVE:
			break;

		case TSP_QUIT:
			doquit(msg);		/* become a slave */
			break;

		case TSP_TEST:
			electiontime = 0;
			break;

		case TSP_LOOP:
			/* looking for loops of masters */
			if (!(status & MASTER))
				break;
			if (fromnet->status == SLAVE) {
			    if (!strcmp(msg->tsp_name, hostname)) {
				/*
				 * Someone forwarded our message back to
				 * us.  There must be a loop.  Tell the
				 * master of this network to quit.
				 *
				 * The other master often gets into
				 * the same state, with boring results.
				 */
				ntp = fromnet;
				for (tries = 0; tries < 3; tries++) {
				    to.tsp_type = TSP_RESOLVE;
				    answer = acksend(&to, &ntp->dest_addr,
						     ANYADDR, TSP_MASTERACK,
						     ntp,0);
				    if (answer == NULL)
					break;
				    taddr = from;
				    (void)strcpy(tname, answer->tsp_name);
				    to.tsp_type = TSP_QUIT;
				    (void)strcpy(to.tsp_name, hostname);
				    if (!acksend(&to, &taddr, tname,
						 TSP_ACK, 0, 1)) {
					syslog(LOG_ERR,
					"no reply from %s to slave LOOP-QUIT",
						 tname);
				    } else {
					electiontime = 0;
				    }
				}
				(void)gettimeofday(&ntime, NULL);
				looptime = ntime.tv_sec + FASTTOUT;
			    } else {
				if (msg->tsp_hopcnt-- < 1)
				    break;
				bytenetorder(msg);
				for (ntp = nettab; ntp != 0; ntp = ntp->next) {
				    if (ntp->status == MASTER
					&& 0 > sendto(sock, (char *)msg,
						      sizeof(struct tsp), 0,
					      (struct sockaddr*)&ntp->dest_addr,
						      sizeof(ntp->dest_addr)))
				    trace_sendto_err(ntp->dest_addr.sin_addr);
				}
			    }
			} else {	/* fromnet->status == MASTER */
			    /*
			     * We should not have received this from a net
			     * we are master on.  There must be two masters,
			     * unless the packet was really from us.
			     */
			    if (from.sin_addr.s_addr
				== fromnet->my_addr.s_addr) {
				if (trace)
				    fprintf(fd,"discarding forwarded LOOP\n");
				break;
			    }

			    /*
			     * The other master often gets into the same
			     * state, with boring results.
			     */
			    ntp = fromnet;
			    for (tries = 0; tries < 3; tries++) {
				to.tsp_type = TSP_RESOLVE;
				answer = acksend(&to, &ntp->dest_addr,
						 ANYADDR, TSP_MASTERACK,
						ntp,0);
				if (!answer)
					break;
				htp = addmach(answer->tsp_name,
					      &from,ntp);
				to.tsp_type = TSP_QUIT;
				(void)strcpy(to.tsp_name, hostname);
				if (!acksend(&to,&htp->addr,htp->name,
					     TSP_ACK, 0, htp->noanswer)) {
					syslog(LOG_ERR,
				    "no reply from %s to master LOOP-QUIT",
					       htp->name);
					(void)remmach(htp);
				}
			    }
			    (void)gettimeofday(&ntime, NULL);
			    looptime = ntime.tv_sec + FASTTOUT;
			}
			break;
		default:
			if (trace) {
				fprintf(fd, "garbage message: ");
				print(msg, &from);
			}
			break;
		}
	}
	goto loop;
}
void op_fngetdvi(mval *device, mval *keyword, mval *ret)
{
	itmlist_struct	item_list;
	short 		out_len, iosb[4];
	uint4 	status;
	char 		index, slot, last_slot;
	int4 		item_code, out_value;
	unsigned char 	buff[MAX_KEY_LENGTH], *upper_case;
	bool		want_secondary;
	$DESCRIPTOR(device_name,"");
	error_def(ERR_DVIKEYBAD);
	error_def(ERR_INVSTRLEN);

	MV_FORCE_STR(device);
	MV_FORCE_STR(keyword);

	if (MAX_DEV_LENGTH < device->str.len)
		rts_error(VARLSTCNT(1) SS$_IVLOGNAM);
	if (keyword->str.len > MAX_KEY_LENGTH)
		rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, keyword->str.len, MAX_KEY_LENGTH);
	if (!keyword->str.len)
	{	rts_error(VARLSTCNT(6) ERR_DVIKEYBAD, 4, device->str.len, device->str.addr, 4, "NULL");
	}

	lower_to_upper(&buff[0], keyword->str.addr, keyword->str.len);
	upper_case = buff;
	if ( device->str.len == 0 || (device->str.len == 1 && *device->str.addr == '0'))
	{	device_name.dsc$a_pointer = "SYS$INPUT";
		device_name.dsc$w_length = SIZEOF("SYS$INPUT")-1;
	}
	else
	{	device_name.dsc$a_pointer = device->str.addr;
		device_name.dsc$w_length = device->str.len;
	}
	item_list.bufflen = VAL_LENGTH;
	item_list.itmcode = SPL_CODE;
	item_list.buffaddr = &out_value;
	item_list.retlen = &out_len;
	item_list.end = NULL;
	status = sys$getdvi( efn_immed_wait, 0, &device_name, &item_list, &iosb[0], 0, 0, 0 );
	if (status != SS$_NORMAL && status != SS$_NONLOCAL)
	{	rts_error(VARLSTCNT(1)  status ) ;
	}
	sys$synch(efn_immed_wait, &iosb[0]);
	if (iosb[0] != SS$_NORMAL && iosb[0] != SS$_NONLOCAL)
	{	rts_error(VARLSTCNT(1)  iosb[0] );
	}
	if (out_value != NULL)
	{	want_secondary = TRUE;
	}
	else
	{	want_secondary = FALSE;
	}

	if ((index = *upper_case - 'A') < MIN_INDEX || index > MAX_INDEX)
	{	rts_error(VARLSTCNT(6) ERR_DVIKEYBAD, 4, device->str.len, device->str.addr, keyword->str.len, keyword->str.addr);
	}
	item_code = 0;
	if ( dvi_index[ index ].len)
	{
		slot = dvi_index[ index ].index;
		last_slot = dvi_index[ index ].len;
		for ( ; slot < last_slot ; slot++ )
		{	if (keyword->str.len == dvi_table[ slot ].len &&
				!memcmp(dvi_table[ slot ].name, upper_case, keyword->str.len))
			{	item_code = dvi_table[ slot ].item_code;
				break;
			}
		}
	}
	if (!item_code)
	{	rts_error(VARLSTCNT(6) ERR_DVIKEYBAD, 4, device->str.len, device->str.addr, keyword->str.len, keyword->str.addr);
	}

	switch( item_code )
	{
	/* **** the following item codes require a string be returned **** */
	case DVI$_ALLDEVNAM:
	case DVI$_DEVLOCKNAM:
	case DVI$_DEVNAM:
	case DVI$_FULLDEVNAM:
	case DVI$_LOGVOLNAM:
	case DVI$_NEXTDEVNAM:
	case DVI$_ROOTDEVNAM:
	case DVI$_TT_ACCPORNAM:
	case DVI$_TT_PHYDEVNAM:
	case DVI$_VOLNAM:
		if (want_secondary)
		{
			if (!((item_code == DVI$_DEVNAM) && (keyword->str.len == 9)))
			{	item_code |= DVI$C_SECONDARY;
			}
		}
		assert(stringpool.free >= stringpool.base);
		assert(stringpool.top >= stringpool.free);
		ENSURE_STP_FREE_SPACE(MAX_DVI_STRLEN);
		item_list.bufflen = MAX_DVI_STRLEN;
		item_list.itmcode = item_code;
		item_list.buffaddr = stringpool.free;
		item_list.retlen = &out_len;
		item_list.end = NULL;
		status = sys$getdvi( efn_immed_wait, 0, &device_name, &item_list, &iosb[0], 0, 0, 0 );
		if (status != SS$_NORMAL && status != SS$_NONLOCAL)
		{		rts_error(VARLSTCNT(1)  status );
		}
		sys$synch(efn_immed_wait, &iosb[0]);
		if (iosb[0] != SS$_NORMAL && iosb[0] != SS$_NONLOCAL)
		{		rts_error(VARLSTCNT(1)  iosb[0] ) ;
		}
		ret->str.addr = stringpool.free;
		ret->str.len = out_len;
		ret->mvtype = MV_STR;
		stringpool.free += out_len;
		assert(stringpool.free >= stringpool.base);
		assert(stringpool.top >= stringpool.free);
		return;

	default:
		if (want_secondary)
			item_code |= DVI$C_SECONDARY;
		item_list.itmcode = item_code;
		item_list.bufflen = VAL_LENGTH;
		item_list.buffaddr = &out_value;
		item_list.retlen = &out_len;
		item_list.end = NULL;
		status = sys$getdvi( efn_immed_wait, 0, &device_name, &item_list, &iosb[0], 0, 0, 0 );
		if (status != SS$_NORMAL && status != SS$_NONLOCAL)
			rts_error(VARLSTCNT(1)  status );
		sys$synch(efn_immed_wait, &iosb[0]);
		if (iosb[0] != SS$_NORMAL && iosb[0] != SS$_NONLOCAL)
			rts_error(VARLSTCNT(1)  iosb[0] );
		if (want_secondary)
			item_code = item_code - 1;
		switch(item_code)
		{	case DVI$_LOCKID:
			case DVI$_ACPPID:
			case DVI$_OWNUIC:
			if (out_value)
			{	assert(stringpool.free >= stringpool.base);
				assert(stringpool.top >= stringpool.free);
				ENSURE_STP_FREE_SPACE(HEX_LEN);
				i2hex(out_value, stringpool.free, HEX_LEN);
				ret->str.addr = stringpool.free;
				ret->str.len = HEX_LEN;
				stringpool.free += HEX_LEN;
				assert(stringpool.free >= stringpool.base);
				assert(stringpool.top >= stringpool.free);
			}
			else
			{	ret->str.addr = "";
				ret->str.len = 0;
			}
			ret->mvtype = MV_STR;
			break;
		case DVI$_ACPTYPE:
			switch(out_value)
			{
			case 0: ret->str.addr = "ILLEGAL";
				ret->str.len = 7;
				break;
			case 1: ret->str.addr = "F11V1";
				ret->str.len = 5;
				break;
			case 2: ret->str.addr = "F11V2";
				ret->str.len = 5;
				break;
			case 3: ret->str.addr = "MTA";
				ret->str.len = 3;
				break;
			case 4: ret->str.addr = "NET";
				ret->str.len = 3;
				break;
			case 5: ret->str.addr = "REM";
				ret->str.len = 3;
			}
			ret->mvtype = MV_STR;
			break;
		default:
			i2mval(ret,out_value) ;
		}
		return;
	}
}
int main(int argc, char *argv[]){
	char c;
	int i;
	int check;
	int *array_r, *array_b;
	pthread_t *p_red, *p_blue;
	
	synch(main);
	
	synch(red);
	
	synch(blue);
	
	synch(mtx);
	
	while(1) {
		i_blue = 0;
		i_red = 0;
		count_b = 0;
		count_r = 0;
		un_count_b = 0;
		un_count_r = 0;
		check_blue = 0;
		check_red = 0;
		
		printf("Press 0 to insert a red car, 1 for blue car or 'q' to exit\n");
		do{
			c = getchar();
			if(c=='0'){
				//red
				i_red++;
			}
			else if(c=='1'){
				//blue
				i_blue++;
			}
			else if(c=='q') {
				return(0);
			}
		}while(c!='\n');
		
		if(i_red==0 && i_blue==0){
			return(0);
		}
		printf("Α new day dawned\n");
		
		p_red = (pthread_t*)malloc(sizeof(pthread_t)*i_red);
		if(p_red==NULL){
			printf("Problem with memory allocation\n");
			return(2);
		}
		p_blue = (pthread_t*)malloc(sizeof(pthread_t)*i_blue);
		if(p_blue==NULL){
			printf("Problem with memory allocation\n");
			return(2);
		}
		array_r = (int*)malloc(sizeof(int)*i_red);
		if(array_r==NULL){
			printf("Problem with memory allocation\n");
			return(2);
		}
		array_b = (int*)malloc(sizeof(int)*i_blue);
		if(array_b==NULL){
			printf("Problem with memory allocation\n");
			return(2);
		}
		
		printf("red %d, blue %d\n",i_red, i_blue);
		
		for(i=0; i<i_red; i++){
			array_r[i] = i + 1;
			check = pthread_create(&p_red[i], NULL, &red, &array_r[i]);
			if(check!=0) {
				printf("Problem to create %d thread\n", i);
				return(7);
			}
		}
		
		for(i=0; i<i_blue; i++){
			array_b[i] = i + 1;
			check = pthread_create(&p_blue[i], NULL, &blue, &array_b[i]);
			if(check!=0) {
				printf("Problem to create %d thread\n", i);
				return(7);
			}
		}
		
		synch_begin(main);
		
		synch_wait();
		
		synch_end(main);
		
		printf("End of the day\n");
	}
	
	return(0);
}
Exemple #23
0
slave()
{
	int length;
	int senddateack;
	long electiontime, refusetime, looktime;
	u_short seq;
	char candidate[MAXHOSTNAMELEN];
	struct tsp *msg, to, *readmsg();
	struct sockaddr_in saveaddr, msaveaddr;
	struct timeval wait;
	struct timeval time, otime;
	struct tsp *answer, *acksend();
	int timeout();
	char *date();
	long casual();
	int bytenetorder();
	char olddate[32];
	struct sockaddr_in server;
	register struct netinfo *ntp;
	int ind;
	struct tsp resp;
	extern int Mflag;
	extern int justquit;
#ifdef MEASURE
	extern FILE *fp;
#endif
	if (slavenet) {
		resp.tsp_type = TSP_SLAVEUP;
		resp.tsp_vers = TSPVERSION;
		(void)strcpy(resp.tsp_name, hostname);
		bytenetorder(&resp);
		if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0,
		    &slavenet->dest_addr, sizeof(struct sockaddr_in)) < 0) {
			syslog(LOG_ERR, "sendto: %m");
			exit(1);
		}
	}

	if (status & MASTER) {
#ifdef MEASURE
		if (fp == NULL) {
			fp = fopen("/usr/adm/timed.masterlog", "w");
			setlinebuf(fp);
		}
#endif
		syslog(LOG_INFO, "THIS MACHINE IS A SUBMASTER");
		if (trace) {
			fprintf(fd, "THIS MACHINE IS A SUBMASTER\n");
		}
		for (ntp = nettab; ntp != NULL; ntp = ntp->next)
			if (ntp->status == MASTER)
				masterup(ntp);

	} else {
		syslog(LOG_INFO, "THIS MACHINE IS A SLAVE");
		if (trace) {
			fprintf(fd, "THIS MACHINE IS A SLAVE\n");
		}
	}

	seq = 0;
	senddateack = OFF;
	refusetime = 0;

	(void)gettimeofday(&time, (struct timezone *)0);
	electiontime = time.tv_sec + delay2;
	if (Mflag)
		if (justquit)
			looktime = time.tv_sec + delay2;
		else 
			looktime = 1;
	else
		looktime = 0;

loop:
	length = sizeof(struct sockaddr_in);
	(void)gettimeofday(&time, (struct timezone *)0);
	if (time.tv_sec > electiontime) {
		if (trace) 
			fprintf(fd, "election timer expired\n");
		longjmp(jmpenv, 1);
	}
	if (looktime && time.tv_sec > looktime) {
		if (trace) 
			fprintf(fd, "Looking for nets to master and loops\n");
		
		if (nignorednets > 0) {
			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
				if (ntp->status == IGNORE) {
					lookformaster(ntp);
					if (ntp->status == MASTER)
						masterup(ntp);
					else
						ntp->status = IGNORE;
				}
			}
			setstatus();
#ifdef MEASURE
			/*
			 * Check to see if we just became master
			 * (file not open)
			 */
			if (fp == NULL) {
				fp = fopen("/usr/adm/timed.masterlog", "w");
				setlinebuf(fp);
			}
#endif
		}

		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
		    if (ntp->status == MASTER) {
			to.tsp_type = TSP_LOOP;
			to.tsp_vers = TSPVERSION;
			to.tsp_seq = sequence++;
			to.tsp_hopcnt = 10;
			(void)strcpy(to.tsp_name, hostname);
			bytenetorder(&to);
			if (sendto(sock, (char *)&to, sizeof(struct tsp), 0,
			    &ntp->dest_addr, sizeof(struct sockaddr_in)) < 0) {
				syslog(LOG_ERR, "sendto: %m");
				exit(1);
			}
		    }
		}
		(void)gettimeofday(&time, (struct timezone *)0);
		looktime = time.tv_sec + delay2;
	}
	wait.tv_sec = electiontime - time.tv_sec + 10;
	wait.tv_usec = 0;
	msg = readmsg(TSP_ANY, (char *)ANYADDR, &wait, (struct netinfo *)NULL);
	if (msg != NULL) {
		switch (msg->tsp_type) {
		case TSP_SETDATE:
#ifdef TESTING
		case TSP_TEST:
#endif
		case TSP_MSITE:
		case TSP_TRACEOFF:
		case TSP_TRACEON:
			break;
		case TSP_MASTERUP:
			if (fromnet == NULL) {
				if (trace) {
					fprintf(fd, "slave ignored: ");
					print(msg, &from);
				}
				goto loop;
			}
			break;
		default:
			if (fromnet == NULL || fromnet->status == IGNORE) {
				if (trace) {
					fprintf(fd, "slave ignored: ");
					print(msg, &from);
				}
				goto loop;
			}
			break;
		}

		switch (msg->tsp_type) {

		case TSP_ADJTIME:
			if (fromnet->status != SLAVE)
				break;
			(void)gettimeofday(&time, (struct timezone *)0);
			electiontime = time.tv_sec + delay2;
			if (seq != msg->tsp_seq) {
				seq = msg->tsp_seq;
				if ((status & SUBMASTER) == SUBMASTER) {
					synch((msg->tsp_time.tv_sec * 1000) + 
					    (msg->tsp_time.tv_usec / 1000));
				} else {
					adjclock(&(msg->tsp_time));
				}
			}
			break;
		case TSP_SETTIME:
			if (fromnet->status != SLAVE)
				break;
			if (seq == msg->tsp_seq)
				break;

			seq = msg->tsp_seq;

			(void)strcpy(olddate, date());
			(void)gettimeofday(&otime, (struct timezone *)0);
			(void)settimeofday(&msg->tsp_time,
				(struct timezone *)0);
			syslog(LOG_NOTICE, "date changed by %s from: %s",
				msg->tsp_name, olddate);
			logwtmp(otime, msg->tsp_time);
			if ((status & SUBMASTER) == SUBMASTER)
				spreadtime();
			(void)gettimeofday(&time, (struct timezone *)0);
			electiontime = time.tv_sec + delay2;

			if (senddateack == ON) {
				senddateack = OFF;
				msg->tsp_type = TSP_DATEACK;
				(void)strcpy(msg->tsp_name, hostname);
				bytenetorder(msg);
				length = sizeof(struct sockaddr_in);
				if (sendto(sock, (char *)msg, 
						sizeof(struct tsp), 0,
						&saveaddr, length) < 0) {
					syslog(LOG_ERR, "sendto: %m");
					exit(1);
				}
			}
			break;
		case TSP_MASTERUP:
			if (slavenet && fromnet != slavenet)
				break;
			makeslave(fromnet);
			setstatus();
			msg->tsp_type = TSP_SLAVEUP;
			msg->tsp_vers = TSPVERSION;
			(void)strcpy(msg->tsp_name, hostname);
			bytenetorder(msg);
			answerdelay();
			length = sizeof(struct sockaddr_in);
			if (sendto(sock, (char *)msg, sizeof(struct tsp), 0, 
						&from, length) < 0) {
				syslog(LOG_ERR, "sendto: %m");
				exit(1);
			}
			backoff = 1;
			delay2 = casual((long)MINTOUT, (long)MAXTOUT);
			(void)gettimeofday(&time, (struct timezone *)0);
			electiontime = time.tv_sec + delay2;
			refusetime = 0;
			break;
		case TSP_MASTERREQ:
			if (fromnet->status != SLAVE)
				break;
			(void)gettimeofday(&time, (struct timezone *)0);
			electiontime = time.tv_sec + delay2;
			break;
		case TSP_SETDATE:
			saveaddr = from;
			msg->tsp_type = TSP_SETDATEREQ;
			msg->tsp_vers = TSPVERSION;
			(void)strcpy(msg->tsp_name, hostname);
			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
				if (ntp->status == SLAVE)
					break;
			}
			if (ntp == NULL)
				break;
			answer = acksend(msg, &ntp->dest_addr, (char *)ANYADDR,
			    TSP_DATEACK, ntp);
			if (answer != NULL) {
				msg->tsp_type = TSP_ACK;
				bytenetorder(msg);
				length = sizeof(struct sockaddr_in);
				if (sendto(sock, (char *)msg,
				    sizeof(struct tsp), 0, &saveaddr,
				    length) < 0) {
					syslog(LOG_ERR, "sendto: %m");
					exit(1);
				}
				senddateack = ON;
			}
			break;
		case TSP_SETDATEREQ:
			saveaddr = from;
			if (status != SUBMASTER || fromnet->status != MASTER)
				break;
			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
				if (ntp->status == SLAVE)
					break;
			}
			ind = findhost(msg->tsp_name);
			if (ind < 0) {
			    syslog(LOG_WARNING,
				"DATEREQ from uncontrolled machine");
			    break;
			}
			syslog(LOG_DEBUG,
			    "forwarding date change request for %s",
			    msg->tsp_name);
			(void)strcpy(msg->tsp_name, hostname);
			answer = acksend(msg, &ntp->dest_addr, (char *)ANYADDR,
			    TSP_DATEACK, ntp);
			if (answer != NULL) {
				msg->tsp_type = TSP_DATEACK;
				bytenetorder(msg);
				length = sizeof(struct sockaddr_in);
				if (sendto(sock, (char *)msg,
				    sizeof(struct tsp), 0, &saveaddr,
				    length) < 0) {
					syslog(LOG_ERR, "sendto: %m");
					exit(1);
				}
			}
			break;
		case TSP_TRACEON:
			if (!(trace)) {
				fd = fopen(tracefile, "w");
				setlinebuf(fd);
				fprintf(fd, "Tracing started on: %s\n\n", 
								date());
			}
			trace = ON;
			break;
		case TSP_TRACEOFF:
			if (trace) {
				fprintf(fd, "Tracing ended on: %s\n", date());
				(void)fclose(fd);
			}
#ifdef GPROF
			moncontrol(0);
			_mcleanup();
			moncontrol(1);
#endif
			trace = OFF;
			break;
		case TSP_SLAVEUP:
			if ((status & MASTER) && fromnet->status == MASTER) {
				ind = addmach(msg->tsp_name, &from);
				newslave(ind, msg->tsp_seq);
			}
			break;
		case TSP_ELECTION:
			if (fromnet->status == SLAVE) {
				(void)gettimeofday(&time, (struct timezone *)0);
				electiontime = time.tv_sec + delay2;
				seq = 0;            /* reset sequence number */
				if (time.tv_sec < refusetime)
					msg->tsp_type = TSP_REFUSE;
				else {
					msg->tsp_type = TSP_ACCEPT;
					refusetime = time.tv_sec + 30;
				}
				(void)strcpy(candidate, msg->tsp_name);
				(void)strcpy(msg->tsp_name, hostname);
				answerdelay();
				server = from;
				answer = acksend(msg, &server, candidate, TSP_ACK,
				    (struct netinfo *)NULL);
				if (answer == NULL)
					syslog(LOG_WARNING,
					   "no answer from master candidate\n");
			} else {	/* fromnet->status == MASTER */
				to.tsp_type = TSP_QUIT;
				(void)strcpy(to.tsp_name, hostname);
				server = from;
				answer = acksend(&to, &server, msg->tsp_name,
				    TSP_ACK, (struct netinfo *)NULL);
				if (answer == NULL) {
					syslog(LOG_WARNING,
					    "election error: no reply to QUIT");
				} else {
					(void) addmach(msg->tsp_name, &from);
				}
			}
			break;
                case TSP_CONFLICT:
			if (fromnet->status != MASTER)
				break;
                        /*
                         * After a network partition, there can be
                         * more than one master: the first slave to
                         * come up will notify here the situation.
                         */
                        (void)strcpy(to.tsp_name, hostname);

                        if (fromnet == NULL)
                                break;
                        for(;;) {
                                to.tsp_type = TSP_RESOLVE;
                                answer = acksend(&to, &fromnet->dest_addr,
                                    (char *)ANYADDR, TSP_MASTERACK, fromnet);
                                if (answer == NULL)
                                        break;
                                to.tsp_type = TSP_QUIT;
                                server = from;
                                msg = acksend(&to, &server, answer->tsp_name,
                                    TSP_ACK, (struct netinfo *)NULL);
                                if (msg == NULL) {
                                        syslog(LOG_WARNING,
					    "conflict error: no reply to QUIT");
				} else {
                                        (void) addmach(answer->tsp_name, &from);
				}
                        }
                        masterup(fromnet);
                        break;
		case TSP_MSITE:
			if (!slavenet)
				break;
			msaveaddr = from;
			msg->tsp_type = TSP_MSITEREQ;
			msg->tsp_vers = TSPVERSION;
			(void)strcpy(msg->tsp_name, hostname);
			answer = acksend(msg, &slavenet->dest_addr,
					 (char *)ANYADDR, TSP_ACK, slavenet);
			if (answer != NULL) {
				msg->tsp_type = TSP_ACK;
				length = sizeof(struct sockaddr_in);
				bytenetorder(msg);
				if (sendto(sock, (char *)msg, 
						sizeof(struct tsp), 0,
						&msaveaddr, length) < 0) {
					syslog(LOG_ERR, "sendto: %m");
					exit(1);
				}
			}
			break;
		case TSP_ACCEPT:
		case TSP_REFUSE:
			break;
		case TSP_RESOLVE:
			break;
		case TSP_QUIT:
			/* become slave */
#ifdef MEASURE
			if (fp != NULL) {
				(void)fclose(fp);
				fp = NULL;
			}
#endif
			longjmp(jmpenv, 2);
			break;
#ifdef TESTING
		case TSP_TEST:
			electiontime = 0;
			break;
#endif
		case TSP_MSITEREQ:
			if (status & MASTER)
				break;
			if (trace) {
				fprintf(fd, "garbage: ");
				print(msg, &from);
			}
			break;

		case TSP_LOOP:
			/* looking for loops of masters */
			if ( !(status & MASTER))
				break;
			if (fromnet->status == SLAVE) {
			    if ( !strcmp(msg->tsp_name, hostname)) {
				  for(;;) {
				    to.tsp_type = TSP_RESOLVE;
				    answer = acksend(&to, &fromnet->dest_addr,
					(char *)ANYADDR, TSP_MASTERACK,
					fromnet);
				    if (answer == NULL)
					    break;
				    to.tsp_type = TSP_QUIT;
				    (void)strcpy(to.tsp_name, hostname);
				    server = from;
				    answer = acksend(&to, &server,
					answer->tsp_name, TSP_ACK,
					(struct netinfo *)NULL);
				    if (answer == NULL) {
					syslog(LOG_ERR, "loop kill error");
				    } else {
					electiontime = 0;
				    }
				  }
			    } else {
				if (msg->tsp_hopcnt-- <= 0)
				    break;
				bytenetorder(msg);
				ntp = nettab;
				for (; ntp != NULL; ntp = ntp->next)
				    if (ntp->status == MASTER)
					if (sendto(sock, (char *)msg, 
					    sizeof(struct tsp), 0,
					    &ntp->dest_addr, length) < 0) {
						syslog(LOG_ERR, "sendto: %m");
						exit(1);
					}
			    }
			} else {
			    /*
			     * We should not have received this from a net
			     * we are master on.  There must be two masters
			     * in this case.
			     */
			    if (fromnet->my_addr.s_addr == from.sin_addr.s_addr)
				break;
			    for (;;) {
				to.tsp_type = TSP_RESOLVE;
				answer = acksend(&to, &fromnet->dest_addr,
				    (char *)ANYADDR, TSP_MASTERACK,
				    fromnet);
				if (answer == NULL)
					break;
				to.tsp_type = TSP_QUIT;
				(void)strcpy(to.tsp_name, hostname);
				server = from;
				answer = acksend(&to, &server, answer->tsp_name,
				    TSP_ACK, (struct netinfo *)NULL);
				if (answer == NULL) {
					syslog(LOG_ERR, "loop kill error2");
				} else {
					(void)addmach(msg->tsp_name, &from);
				}
			    }
			}
			break;
		default:
			if (trace) {
				fprintf(fd, "garbage: ");
				print(msg, &from);
			}
			break;
		}
	}
	goto loop;
}
Exemple #24
0
int main()
{
int i,ctr=0;
Lattice newlatt[2];
float cov,COV=1,T=0.001;
while(cov<=COV)
{
newlatt[0].time=0;
newlatt[1].time=0;

newlatt[0].nevent=0;
newlatt[1].nevent=0;

newlatt[0].randgen();
newlatt[1].randgen();

newlatt[0].iran=0;
newlatt[1].iran=0;

newlatt[0].saveconfig();
newlatt[1].saveconfig();



newlatt[1].bdyleftcrec=0;
newlatt[0].bdyleftcrec=0;

while(newlatt[0].time<T || newlatt[1].time<T )
    {
      for(i=0;i<2;i++)
      {
        if(newlatt[i].time<=T)
	{
	  newlatt[i].doKMC();
	  newlatt[i].calctime();
	}
      }
       //sendmsgs(newlatt);

       for(i=0;i<2;i++)
         newlatt[i].savebdylist();
    }

 for(i=0;i<2;i++)
     newlatt[i].savebdylist();

sendmsgs(newlatt);
synch(newlatt);
cov=((float) newlatt[0].ndep +(float)newlatt[1].ndep)/(float)(2*size*size);
cout<<"iran=***************************************************************************"<<newlatt[0].iran<<endl;
cout<<"iran="<<newlatt[0].iran<<endl;
cout<<"cov="<<cov<<endl;
ctr++;
}


//newlatt[0].savebdylist();
//newlatt[0].comparebdylist();
cout<<"latzero*******************"<<endl;
cout<<"redoflag="<<newlatt[0].redoflag<<endl;
newlatt[0].p();

cout<<"latone*******************"<<endl;
newlatt[1].p();

return 0;
}
void
regopt(Prog *firstp)
{
	Reg *r, *r1;
	Prog *p;
	Graph *g;
	int i, z;
	uint32 vreg;
	Bits bit;
	ProgInfo info;

	if(first) {
		fmtinstall('Q', Qconv);
		first = 0;
	}
	
	fixjmp(firstp);
	mergetemp(firstp);

	/*
	 * control flow is more complicated in generated go code
	 * than in generated c code.  define pseudo-variables for
	 * registers, so we have complete register usage information.
	 */
	nvar = NREGVAR;
	memset(var, 0, NREGVAR*sizeof var[0]);
	for(i=0; i<NREGVAR; i++) {
		if(regnodes[i] == N)
			regnodes[i] = newname(lookup(regname[i]));
		var[i].node = regnodes[i];
	}

	regbits = RtoB(REGSP)|RtoB(REGLINK)|RtoB(REGPC);
	for(z=0; z<BITS; z++) {
		externs.b[z] = 0;
		params.b[z] = 0;
		consts.b[z] = 0;
		addrs.b[z] = 0;
		ovar.b[z] = 0;
	}

	// build list of return variables
	setoutvar();

	/*
	 * pass 1
	 * build aux data structure
	 * allocate pcs
	 * find use and set of variables
	 */
	g = flowstart(firstp, sizeof(Reg));
	if(g == nil)
		return;
	firstr = (Reg*)g->start;

	for(r = firstr; r != R; r = (Reg*)r->f.link) {
		p = r->f.prog;
		proginfo(&info, p);

		// Avoid making variables for direct-called functions.
		if(p->as == ABL && p->to.type == D_EXTERN)
			continue;

		bit = mkvar(r, &p->from);
		if(info.flags & LeftRead)
			for(z=0; z<BITS; z++)
				r->use1.b[z] |= bit.b[z];
		if(info.flags & LeftAddr)
			setaddrs(bit);

		if(info.flags & RegRead) {	
			if(p->from.type != D_FREG)
				r->use1.b[0] |= RtoB(p->reg);
			else
				r->use1.b[0] |= FtoB(p->reg);
		}

		if(info.flags & (RightAddr | RightRead | RightWrite)) {
			bit = mkvar(r, &p->to);
			if(info.flags & RightAddr)
				setaddrs(bit);
			if(info.flags & RightRead)
				for(z=0; z<BITS; z++)
					r->use2.b[z] |= bit.b[z];
			if(info.flags & RightWrite)
				for(z=0; z<BITS; z++)
					r->set.b[z] |= bit.b[z];
		}
	}
	if(firstr == R)
		return;

	for(i=0; i<nvar; i++) {
		Var *v = var+i;
		if(v->addr) {
			bit = blsh(i);
			for(z=0; z<BITS; z++)
				addrs.b[z] |= bit.b[z];
		}

		if(debug['R'] && debug['v'])
			print("bit=%2d addr=%d et=%-6E w=%-2d s=%N + %lld\n",
				i, v->addr, v->etype, v->width, v->node, v->offset);
	}

	if(debug['R'] && debug['v'])
		dumpit("pass1", &firstr->f, 1);

	/*
	 * pass 2
	 * find looping structure
	 */
	flowrpo(g);

	if(debug['R'] && debug['v'])
		dumpit("pass2", &firstr->f, 1);

	/*
	 * pass 3
	 * iterate propagating usage
	 * 	back until flow graph is complete
	 */
loop1:
	change = 0;
	for(r = firstr; r != R; r = (Reg*)r->f.link)
		r->f.active = 0;
	for(r = firstr; r != R; r = (Reg*)r->f.link)
		if(r->f.prog->as == ARET)
			prop(r, zbits, zbits);
loop11:
	/* pick up unreachable code */
	i = 0;
	for(r = firstr; r != R; r = r1) {
		r1 = (Reg*)r->f.link;
		if(r1 && r1->f.active && !r->f.active) {
			prop(r, zbits, zbits);
			i = 1;
		}
	}
	if(i)
		goto loop11;
	if(change)
		goto loop1;

	if(debug['R'] && debug['v'])
		dumpit("pass3", &firstr->f, 1);


	/*
	 * pass 4
	 * iterate propagating register/variable synchrony
	 * 	forward until graph is complete
	 */
loop2:
	change = 0;
	for(r = firstr; r != R; r = (Reg*)r->f.link)
		r->f.active = 0;
	synch(firstr, zbits);
	if(change)
		goto loop2;

	addsplits();

	if(debug['R'] && debug['v'])
		dumpit("pass4", &firstr->f, 1);

	if(debug['R'] > 1) {
		print("\nprop structure:\n");
		for(r = firstr; r != R; r = (Reg*)r->f.link) {
			print("%d:%P", r->f.loop, r->f.prog);
			for(z=0; z<BITS; z++) {
				bit.b[z] = r->set.b[z] |
					r->refahead.b[z] | r->calahead.b[z] |
					r->refbehind.b[z] | r->calbehind.b[z] |
					r->use1.b[z] | r->use2.b[z];
				bit.b[z] &= ~addrs.b[z];
			}

			if(bany(&bit)) {
				print("\t");
				if(bany(&r->use1))
					print(" u1=%Q", r->use1);
				if(bany(&r->use2))
					print(" u2=%Q", r->use2);
				if(bany(&r->set))
					print(" st=%Q", r->set);
				if(bany(&r->refahead))
					print(" ra=%Q", r->refahead);
				if(bany(&r->calahead))
					print(" ca=%Q", r->calahead);
				if(bany(&r->refbehind))
					print(" rb=%Q", r->refbehind);
				if(bany(&r->calbehind))
					print(" cb=%Q", r->calbehind);
			}
			print("\n");
		}
	}

	/*
	 * pass 4.5
	 * move register pseudo-variables into regu.
	 */
	for(r = firstr; r != R; r = (Reg*)r->f.link) {
		r->regu = (r->refbehind.b[0] | r->set.b[0]) & REGBITS;

		r->set.b[0] &= ~REGBITS;
		r->use1.b[0] &= ~REGBITS;
		r->use2.b[0] &= ~REGBITS;
		r->refbehind.b[0] &= ~REGBITS;
		r->refahead.b[0] &= ~REGBITS;
		r->calbehind.b[0] &= ~REGBITS;
		r->calahead.b[0] &= ~REGBITS;
		r->regdiff.b[0] &= ~REGBITS;
		r->act.b[0] &= ~REGBITS;
	}

	if(debug['R'] && debug['v'])
		dumpit("pass4.5", &firstr->f, 1);

	/*
	 * pass 5
	 * isolate regions
	 * calculate costs (paint1)
	 */
	r = firstr;
	if(r) {
		for(z=0; z<BITS; z++)
			bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
			  ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
		if(bany(&bit) & !r->f.refset) {
			// should never happen - all variables are preset
			if(debug['w'])
				print("%L: used and not set: %Q\n", r->f.prog->lineno, bit);
			r->f.refset = 1;
		}
	}

	for(r = firstr; r != R; r = (Reg*)r->f.link)
		r->act = zbits;
	rgp = region;
	nregion = 0;
	for(r = firstr; r != R; r = (Reg*)r->f.link) {
		for(z=0; z<BITS; z++)
			bit.b[z] = r->set.b[z] &
			  ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
		if(bany(&bit) && !r->f.refset) {
			if(debug['w'])
				print("%L: set and not used: %Q\n", r->f.prog->lineno, bit);
			r->f.refset = 1;
			excise(&r->f);
		}
		for(z=0; z<BITS; z++)
			bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
		while(bany(&bit)) {
			i = bnum(bit);
			rgp->enter = r;
			rgp->varno = i;
			change = 0;
			if(debug['R'] > 1)
				print("\n");
			paint1(r, i);
			bit.b[i/32] &= ~(1L<<(i%32));
			if(change <= 0) {
				if(debug['R'])
					print("%L $%d: %Q\n",
						r->f.prog->lineno, change, blsh(i));
				continue;
			}
			rgp->cost = change;
			nregion++;
			if(nregion >= NRGN) {
				if(debug['R'] > 1)
					print("too many regions\n");
				goto brk;
			}
			rgp++;
		}
	}
brk:
	qsort(region, nregion, sizeof(region[0]), rcmp);

	if(debug['R'] && debug['v'])
		dumpit("pass5", &firstr->f, 1);

	/*
	 * pass 6
	 * determine used registers (paint2)
	 * replace code (paint3)
	 */
	rgp = region;
	for(i=0; i<nregion; i++) {
		bit = blsh(rgp->varno);
		vreg = paint2(rgp->enter, rgp->varno);
		vreg = allreg(vreg, rgp);
		if(debug['R']) {
			if(rgp->regno >= NREG)
				print("%L $%d F%d: %Q\n",
					rgp->enter->f.prog->lineno,
					rgp->cost,
					rgp->regno-NREG,
					bit);
			else
				print("%L $%d R%d: %Q\n",
					rgp->enter->f.prog->lineno,
					rgp->cost,
					rgp->regno,
					bit);
		}
		if(rgp->regno != 0)
			paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
		rgp++;
	}

	if(debug['R'] && debug['v'])
		dumpit("pass6", &firstr->f, 1);

	/*
	 * pass 7
	 * peep-hole on basic block
	 */
	if(!debug['R'] || debug['P']) {
		peep(firstp);
	}

	if(debug['R'] && debug['v'])
		dumpit("pass7", &firstr->f, 1);

	/*
	 * last pass
	 * eliminate nops
	 * free aux structures
	 * adjust the stack pointer
	 *	MOVW.W 	R1,-12(R13)			<<- start
	 *	MOVW   	R0,R1
	 *	MOVW   	R1,8(R13)
	 *	MOVW   	$0,R1
	 *	MOVW   	R1,4(R13)
	 *	BL     	,runtime.newproc+0(SB)
	 *	MOVW   	&ft+-32(SP),R7			<<- adjust
	 *	MOVW   	&j+-40(SP),R6			<<- adjust
	 *	MOVW   	autotmp_0003+-24(SP),R5		<<- adjust
	 *	MOVW   	$12(R13),R13			<<- finish
	 */
	vreg = 0;
	for(p = firstp; p != P; p = p->link) {
		while(p->link != P && p->link->as == ANOP)
			p->link = p->link->link;
		if(p->to.type == D_BRANCH)
			while(p->to.u.branch != P && p->to.u.branch->as == ANOP)
				p->to.u.branch = p->to.u.branch->link;
		if(p->as == AMOVW && p->to.reg == 13) {
			if(p->scond & C_WBIT) {
				vreg = -p->to.offset;		// in adjust region
//				print("%P adjusting %d\n", p, vreg);
				continue;
			}
			if(p->from.type == D_CONST && p->to.type == D_REG) {
				if(p->from.offset != vreg)
					print("in and out different\n");
//				print("%P finish %d\n", p, vreg);
				vreg = 0;	// done adjust region
				continue;
			}

//			print("%P %d %d from type\n", p, p->from.type, D_CONST);
//			print("%P %d %d to type\n\n", p, p->to.type, D_REG);
		}

		if(p->as == AMOVW && vreg != 0) {
			if(p->from.sym != S)
			if(p->from.name == D_AUTO || p->from.name == D_PARAM) {
				p->from.offset += vreg;
//				print("%P adjusting from %d %d\n", p, vreg, p->from.type);
			}
			if(p->to.sym != S)
			if(p->to.name == D_AUTO || p->to.name == D_PARAM) {
				p->to.offset += vreg;
//				print("%P adjusting to %d %d\n", p, vreg, p->from.type);
			}
		}
	}

	flowend(g);
}
Exemple #26
0
/*
 * The main function of `master' is to periodically compute the differences
 * (deltas) between its clock and the clocks of the slaves, to compute the
 * network average delta, and to send to the slaves the differences between
 * their individual deltas and the network delta.
 * While waiting, it receives messages from the slaves (i.e. requests for
 * master's name, remote requests to set the network time, ...), and
 * takes the appropriate action.
 */
int
master()
{
	struct hosttbl *htp;
	long pollingtime;
#define POLLRATE 4
	int polls;
	struct timeval wait, ntime;
	time_t tsp_time_sec;
	struct tsp *msg, *answer, to;
	char newdate[32];
	struct sockaddr_in taddr;
	char tname[MAXHOSTNAMELEN];
	struct netinfo *ntp;
	int i;

	syslog(LOG_NOTICE, "This machine is master");
	if (trace)
		fprintf(fd, "This machine is master\n");
	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
		if (ntp->status == MASTER)
			masterup(ntp);
	}
	(void)gettimeofday(&ntime, 0);
	pollingtime = ntime.tv_sec+3;
	if (justquit)
		polls = 0;
	else
		polls = POLLRATE-1;

/* Process all outstanding messages before spending the long time necessary
 *	to update all timers.
 */
loop:
	(void)gettimeofday(&ntime, 0);
	wait.tv_sec = pollingtime - ntime.tv_sec;
	if (wait.tv_sec < 0)
		wait.tv_sec = 0;
	wait.tv_usec = 0;
	msg = readmsg(TSP_ANY, ANYADDR, &wait, 0);
	if (!msg) {
		(void)gettimeofday(&ntime, 0);
		if (ntime.tv_sec >= pollingtime) {
			pollingtime = ntime.tv_sec + SAMPLEINTVL;
			get_goodgroup(0);

/* If a bogus master told us to quit, we can have decided to ignore a
 * network.  Therefore, periodically try to take over everything.
 */
			polls = (polls + 1) % POLLRATE;
			if (0 == polls && nignorednets > 0) {
				trace_msg("Looking for nets to re-master\n");
				for (ntp = nettab; ntp; ntp = ntp->next) {
					if (ntp->status == IGNORE
					    || ntp->status == NOMASTER) {
						lookformaster(ntp);
						if (ntp->status == MASTER) {
							masterup(ntp);
							polls = POLLRATE-1;
						}
					}
					if (ntp->status == MASTER
					    && --ntp->quit_count < 0)
						ntp->quit_count = 0;
				}
				if (polls != 0)
					setstatus();
			}

			synch(0L);

			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
				to.tsp_type = TSP_LOOP;
				to.tsp_vers = TSPVERSION;
				to.tsp_seq = sequence++;
				to.tsp_hopcnt = MAX_HOPCNT;
				(void)strcpy(to.tsp_name, hostname);
				bytenetorder(&to);
				if (sendto(sock, (char *)&to,
					   sizeof(struct tsp), 0,
					   (struct sockaddr*)&ntp->dest_addr,
					   sizeof(ntp->dest_addr)) < 0) {
				   trace_sendto_err(ntp->dest_addr.sin_addr);
				}
			}
		}


	} else {
		switch (msg->tsp_type) {

		case TSP_MASTERREQ:
			break;

		case TSP_SLAVEUP:
			newslave(msg);
			break;

		case TSP_SETDATE:
			/*
			 * XXX check to see it is from ourself
			 */
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));
			if (!good_host_name(msg->tsp_name)) {
				syslog(LOG_NOTICE,
				       "attempted date change by %s to %s",
				       msg->tsp_name, newdate);
				spreadtime();
				break;
			}

			mchgdate(msg);
			(void)gettimeofday(&ntime, 0);
			pollingtime = ntime.tv_sec + SAMPLEINTVL;
			break;

		case TSP_SETDATEREQ:
			if (!fromnet || fromnet->status != MASTER)
				break;
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));
			htp = findhost(msg->tsp_name);
			if (htp == 0) {
				syslog(LOG_ERR,
				       "attempted SET DATEREQ by uncontrolled %s to %s",
				       msg->tsp_name, newdate);
				break;
			}
			if (htp->seq == msg->tsp_seq)
				break;
			htp->seq = msg->tsp_seq;
			if (!htp->good) {
				syslog(LOG_NOTICE,
				"attempted SET DATEREQ by untrusted %s to %s",
				       msg->tsp_name, newdate);
				spreadtime();
				break;
			}

			mchgdate(msg);
			(void)gettimeofday(&ntime, 0);
			pollingtime = ntime.tv_sec + SAMPLEINTVL;
			break;

		case TSP_MSITE:
			xmit(TSP_ACK, msg->tsp_seq, &from);
			break;

		case TSP_MSITEREQ:
			break;

		case TSP_TRACEON:
			traceon();
			break;

		case TSP_TRACEOFF:
			traceoff("Tracing ended at %s\n");
			break;

		case TSP_ELECTION:
			if (!fromnet)
				break;
			if (fromnet->status == MASTER) {
				pollingtime = 0;
				(void)addmach(msg->tsp_name, &from,fromnet);
			}
			taddr = from;
			(void)strcpy(tname, msg->tsp_name);
			to.tsp_type = TSP_QUIT;
			(void)strcpy(to.tsp_name, hostname);
			answer = acksend(&to, &taddr, tname,
					 TSP_ACK, 0, 1);
			if (answer == NULL) {
				syslog(LOG_ERR, "election error by %s",
				       tname);
			}
			break;

		case TSP_CONFLICT:
			/*
			 * After a network partition, there can be
			 * more than one master: the first slave to
			 * come up will notify here the situation.
			 */
			if (!fromnet || fromnet->status != MASTER)
				break;
			(void)strcpy(to.tsp_name, hostname);

			/* The other master often gets into the same state,
			 * with boring results if we stay at it forever.
			 */
			ntp = fromnet;	/* (acksend() can leave fromnet=0 */
			for (i = 0; i < 3; i++) {
				to.tsp_type = TSP_RESOLVE;
				(void)strcpy(to.tsp_name, hostname);
				answer = acksend(&to, &ntp->dest_addr,
						 ANYADDR, TSP_MASTERACK,
						 ntp, 0);
				if (!answer)
					break;
				htp = addmach(answer->tsp_name,&from,ntp);
				to.tsp_type = TSP_QUIT;
				msg = acksend(&to, &htp->addr, htp->name,
					      TSP_ACK, 0, htp->noanswer);
				if (msg == NULL) {
					syslog(LOG_ERR,
				    "no response from %s to CONFLICT-QUIT",
					       htp->name);
				}
			}
			masterup(ntp);
			pollingtime = 0;
			break;

		case TSP_RESOLVE:
			if (!fromnet || fromnet->status != MASTER)
				break;
			/*
			 * do not want to call synch() while waiting
			 * to be killed!
			 */
			(void)gettimeofday(&ntime, (struct timezone *)0);
			pollingtime = ntime.tv_sec + SAMPLEINTVL;
			break;

		case TSP_QUIT:
			doquit(msg);		/* become a slave */
			break;

		case TSP_LOOP:
			if (!fromnet || fromnet->status != MASTER
			    || !strcmp(msg->tsp_name, hostname))
				break;
			/*
			 * We should not have received this from a net
			 * we are master on.  There must be two masters.
			 */
			htp = addmach(msg->tsp_name, &from,fromnet);
			to.tsp_type = TSP_QUIT;
			(void)strcpy(to.tsp_name, hostname);
			answer = acksend(&to, &htp->addr, htp->name,
					 TSP_ACK, 0, 1);
			if (!answer) {
				syslog(LOG_WARNING,
				"loop breakage: no reply from %s=%s to QUIT",
				    htp->name, inet_ntoa(htp->addr.sin_addr));
				(void)remmach(htp);
			}

		case TSP_TEST:
			if (trace) {
				fprintf(fd,
		"\tnets = %d, masters = %d, slaves = %d, ignored = %d\n",
		nnets, nmasternets, nslavenets, nignorednets);
				setstatus();
			}
			pollingtime = 0;
			polls = POLLRATE-1;
			break;

		default:
			if (trace) {
				fprintf(fd, "garbage message: ");
				print(msg, &from);
			}
			break;
		}
	}
	goto loop;
}
Exemple #27
0
void
regopt(Prog *p)
{
	Reg *r, *r1, *r2;
	Prog *p1;
	int i, z;
	long initpc, val, npc;
	ulong vreg;
	Bits bit;
	struct
	{
		long	m;
		long	c;
		Reg*	p;
	} log5[6], *lp;

	firstr = R;
	lastr = R;
	nvar = 0;
	regbits = 0;
	for(z=0; z<BITS; z++) {
		externs.b[z] = 0;
		params.b[z] = 0;
		consts.b[z] = 0;
		addrs.b[z] = 0;
	}

	/*
	 * pass 1
	 * build aux data structure
	 * allocate pcs
	 * find use and set of variables
	 */
	val = 5L * 5L * 5L * 5L * 5L;
	lp = log5;
	for(i=0; i<5; i++) {
		lp->m = val;
		lp->c = 0;
		lp->p = R;
		val /= 5L;
		lp++;
	}
	val = 0;
	for(; p != P; p = p->link) {
		switch(p->as) {
		case ADATA:
		case AGLOBL:
		case ANAME:
		case ASIGNAME:
			continue;
		}
		r = rega();
		if(firstr == R) {
			firstr = r;
			lastr = r;
		} else {
			lastr->link = r;
			r->p1 = lastr;
			lastr->s1 = r;
			lastr = r;
		}
		r->prog = p;
		r->pc = val;
		val++;

		lp = log5;
		for(i=0; i<5; i++) {
			lp->c--;
			if(lp->c <= 0) {
				lp->c = lp->m;
				if(lp->p != R)
					lp->p->log5 = r;
				lp->p = r;
				(lp+1)->c = 0;
				break;
			}
			lp++;
		}

		r1 = r->p1;
		if(r1 != R)
		switch(r1->prog->as) {
		case ARETURN:
		case ABR:
		case ARFI:
		case ARFCI:
		case ARFID:
			r->p1 = R;
			r1->s1 = R;
		}

		/*
		 * left side always read
		 */
		bit = mkvar(&p->from, p->as==AMOVW || p->as == AMOVWZ || p->as == AMOVD);
		for(z=0; z<BITS; z++)
			r->use1.b[z] |= bit.b[z];

		/*
		 * right side depends on opcode
		 */
		bit = mkvar(&p->to, 0);
		if(bany(&bit))
		switch(p->as) {
		default:
			diag(Z, "reg: unknown asop: %A", p->as);
			break;

		/*
		 * right side write
		 */
		case ANOP:
		case AMOVB:
		case AMOVBU:
		case AMOVBZ:
		case AMOVBZU:
		case AMOVH:
		case AMOVHBR:
		case AMOVWBR:
		case AMOVHU:
		case AMOVHZ:
		case AMOVHZU:
		case AMOVW:
		case AMOVWU:
		case AMOVWZ:
		case AMOVWZU:
		case AMOVD:
		case AMOVDU:
		case AFMOVD:
		case AFMOVDCC:
		case AFMOVDU:
		case AFMOVS:
		case AFMOVSU:
		case AFRSP:
			for(z=0; z<BITS; z++)
				r->set.b[z] |= bit.b[z];
			break;

		/*
		 * funny
		 */
		case ABL:
			for(z=0; z<BITS; z++)
				addrs.b[z] |= bit.b[z];
			break;
		}
	}
	if(firstr == R)
		return;
	initpc = pc - val;
	npc = val;

	/*
	 * pass 2
	 * turn branch references to pointers
	 * build back pointers
	 */
	for(r = firstr; r != R; r = r->link) {
		p = r->prog;
		if(p->to.type == D_BRANCH) {
			val = p->to.offset - initpc;
			r1 = firstr;
			while(r1 != R) {
				r2 = r1->log5;
				if(r2 != R && val >= r2->pc) {
					r1 = r2;
					continue;
				}
				if(r1->pc == val)
					break;
				r1 = r1->link;
			}
			if(r1 == R) {
				nearln = p->lineno;
				diag(Z, "ref not found\n%P", p);
				continue;
			}
			if(r1 == r) {
				nearln = p->lineno;
				diag(Z, "ref to self\n%P", p);
				continue;
			}
			r->s2 = r1;
			r->p2link = r1->p2;
			r1->p2 = r;
		}
	}
	if(debug['R']) {
		p = firstr->prog;
		print("\n%L %D\n", p->lineno, &p->from);
	}

	/*
	 * pass 2.5
	 * find looping structure
	 */
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	change = 0;
	loopit(firstr, npc);
	if(debug['R'] && debug['v']) {
		print("\nlooping structure:\n");
		for(r = firstr; r != R; r = r->link) {
			print("%ld:%P", r->loop, r->prog);
			for(z=0; z<BITS; z++)
				bit.b[z] = r->use1.b[z] |
					r->use2.b[z] | r->set.b[z];
			if(bany(&bit)) {
				print("\t");
				if(bany(&r->use1))
					print(" u1=%B", r->use1);
				if(bany(&r->use2))
					print(" u2=%B", r->use2);
				if(bany(&r->set))
					print(" st=%B", r->set);
			}
			print("\n");
		}
	}

	/*
	 * pass 3
	 * iterate propagating usage
	 * 	back until flow graph is complete
	 */
loop1:
	change = 0;
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	for(r = firstr; r != R; r = r->link)
		if(r->prog->as == ARETURN)
			prop(r, zbits, zbits);
loop11:
	/* pick up unreachable code */
	i = 0;
	for(r = firstr; r != R; r = r1) {
		r1 = r->link;
		if(r1 && r1->active && !r->active) {
			prop(r, zbits, zbits);
			i = 1;
		}
	}
	if(i)
		goto loop11;
	if(change)
		goto loop1;


	/*
	 * pass 4
	 * iterate propagating register/variable synchrony
	 * 	forward until graph is complete
	 */
loop2:
	change = 0;
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	synch(firstr, zbits);
	if(change)
		goto loop2;


	/*
	 * pass 5
	 * isolate regions
	 * calculate costs (paint1)
	 */
	r = firstr;
	if(r) {
		for(z=0; z<BITS; z++)
			bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
			  ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
		if(bany(&bit)) {
			nearln = r->prog->lineno;
			warn(Z, "used and not set: %B", bit);
			if(debug['R'] && !debug['w'])
				print("used and not set: %B\n", bit);
		}
	}
	if(debug['R'] && debug['v'])
		print("\nprop structure:\n");
	for(r = firstr; r != R; r = r->link)
		r->act = zbits;
	rgp = region;
	nregion = 0;
	for(r = firstr; r != R; r = r->link) {
		if(debug['R'] && debug['v'])
			print("%P\n	set = %B; rah = %B; cal = %B\n",
				r->prog, r->set, r->refahead, r->calahead);
		for(z=0; z<BITS; z++)
			bit.b[z] = r->set.b[z] &
			  ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
		if(bany(&bit)) {
			nearln = r->prog->lineno;
			warn(Z, "set and not used: %B", bit);
			if(debug['R'])
				print("set an not used: %B\n", bit);
			excise(r);
		}
		for(z=0; z<BITS; z++)
			bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
		while(bany(&bit)) {
			i = bnum(bit);
			rgp->enter = r;
			rgp->varno = i;
			change = 0;
			if(debug['R'] && debug['v'])
				print("\n");
			paint1(r, i);
			bit.b[i/32] &= ~(1L<<(i%32));
			if(change <= 0) {
				if(debug['R'])
					print("%L$%d: %B\n",
						r->prog->lineno, change, blsh(i));
				continue;
			}
			rgp->cost = change;
			nregion++;
			if(nregion >= NRGN) {
				warn(Z, "too many regions");
				goto brk;
			}
			rgp++;
		}
	}
brk:
	qsort(region, nregion, sizeof(region[0]), rcmp);

	/*
	 * pass 6
	 * determine used registers (paint2)
	 * replace code (paint3)
	 */
	rgp = region;
	for(i=0; i<nregion; i++) {
		bit = blsh(rgp->varno);
		vreg = paint2(rgp->enter, rgp->varno);
		vreg = allreg(vreg, rgp);
		if(debug['R']) {
			if(rgp->regno >= NREG)
				print("%L$%d F%d: %B\n",
					rgp->enter->prog->lineno,
					rgp->cost,
					rgp->regno-NREG,
					bit);
			else
				print("%L$%d R%d: %B\n",
					rgp->enter->prog->lineno,
					rgp->cost,
					rgp->regno,
					bit);
		}
		if(rgp->regno != 0)
			paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
		rgp++;
	}
	/*
	 * pass 7
	 * peep-hole on basic block
	 */
	if(!debug['R'] || debug['P'])
		peep();

	/*
	 * pass 8
	 * recalculate pc
	 */
	val = initpc;
	for(r = firstr; r != R; r = r1) {
		r->pc = val;
		p = r->prog;
		p1 = P;
		r1 = r->link;
		if(r1 != R)
			p1 = r1->prog;
		for(; p != p1; p = p->link) {
			switch(p->as) {
			default:
				val++;
				break;

			case ANOP:
			case ADATA:
			case AGLOBL:
			case ANAME:
			case ASIGNAME:
				break;
			}
		}
	}
	pc = val;

	/*
	 * fix up branches
	 */
	if(debug['R'])
		if(bany(&addrs))
			print("addrs: %B\n", addrs);

	r1 = 0; /* set */
	for(r = firstr; r != R; r = r->link) {
		p = r->prog;
		if(p->to.type == D_BRANCH)
			p->to.offset = r->s2->pc;
		r1 = r;
	}

	/*
	 * last pass
	 * eliminate nops
	 * free aux structures
	 */
	for(p = firstr->prog; p != P; p = p->link){
		while(p->link && p->link->as == ANOP)
			p->link = p->link->link;
	}
	if(r1 != R) {
		r1->link = freer;
		freer = firstr;
	}
}