⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pangen4.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/***** spin: pangen4.c *****//* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories.     *//* All Rights Reserved.  This software is for educational purposes only.  *//* No guarantee whatsoever is expressed or implied by the distribution of *//* this code.  Permission is given to distribute this code provided that  *//* this introductory message is not removed and no monies are exchanged.  *//* Software written by Gerard J. Holzmann.  For tool documentation see:   *//*             http://spinroot.com/                                       *//* Send all bug-reports and/or questions to: bugs@spinroot.com            */#include "spin.h"#ifdef PC#include "y_tab.h"#else#include "y.tab.h"#endifextern FILE	*tc, *tb;extern Queue	*qtab;extern Symbol	*Fname;extern int	lineno, m_loss, Pid, eventmapnr, multi_oval;extern short	nocast, has_provided, has_sorted;extern char	*R13[], *R14[], *R15[];static void	check_proc(Lextok *, int);voidundostmnt(Lextok *now, int m){	Lextok *v;	int i, j;	if (!now)	{	fprintf(tb, "0");		return;	}	lineno = now->ln;	Fname  = now->fn;	switch (now->ntyp) {	case CONST:	case '!':	case UMIN:	case '~':	case '/':	case '*':	case '-':	case '+':	case '%':	case LT:	case GT:	case '&':	case '|':	case LE:	case GE:	case NE:	case EQ:	case OR:	case AND:	case LSHIFT:	case RSHIFT:	case TIMEOUT:	case LEN:	case NAME:	case FULL:	case EMPTY:	case 'R':	case NFULL:	case NEMPTY:	case ENABLED:	case '?':	case PC_VAL:	case '^':	case C_EXPR:	case NONPROGRESS:		putstmnt(tb, now, m);		break;	case RUN:		fprintf(tb, "delproc(0, now._nr_pr-1)");		break;	case 's':		if (Pid == eventmapnr) break;		if (m_loss)			fprintf(tb, "if (_m == 2) ");		putname(tb, "_m = unsend(", now->lft, m, ")");		break;	case 'r':		if (Pid == eventmapnr) break;		for (v = now->rgt, i=j=0; v; v = v->rgt, i++)			if (v->lft->ntyp != CONST			&&  v->lft->ntyp != EVAL)				j++;		if (j == 0 && now->val >= 2)			break;	/* poll without side-effect */		{	int ii = 0, jj;			for (v = now->rgt; v; v = v->rgt)				if ((v->lft->ntyp != CONST				&&   v->lft->ntyp != EVAL))					ii++;	/* nr of things bupped */			if (now->val == 1)			{	ii++;				jj = multi_oval - ii - 1;				fprintf(tb, "XX = trpt->bup.oval");				if (multi_oval > 0)				{	fprintf(tb, "s[%d]", jj);					jj++;				}				fprintf(tb, ";\n\t\t");			} else			{	fprintf(tb, "XX = 1;\n\t\t");				jj = multi_oval - ii - 1;			}			if (now->val < 2)	/* not for channel poll */			for (v = now->rgt, i = 0; v; v = v->rgt, i++)			{	switch(v->lft->ntyp) {				case CONST:				case EVAL:					fprintf(tb, "unrecv");					putname(tb, "(", now->lft, m, ", XX-1, ");					fprintf(tb, "%d, ", i);					if (v->lft->ntyp == EVAL)						undostmnt(v->lft->lft, m);					else						undostmnt(v->lft, m);					fprintf(tb, ", %d);\n\t\t", (i==0)?1:0);					break;				default:					fprintf(tb, "unrecv");					putname(tb, "(", now->lft, m, ", XX-1, ");					fprintf(tb, "%d, ", i);					if (v->lft->sym					&& !strcmp(v->lft->sym->name, "_"))					{	fprintf(tb, "trpt->bup.oval");						if (multi_oval > 0)							fprintf(tb, "s[%d]", jj);					} else						putstmnt(tb, v->lft, m);					fprintf(tb, ", %d);\n\t\t", (i==0)?1:0);					if (multi_oval > 0)						jj++;					break;			}	}			jj = multi_oval - ii - 1;			if (now->val == 1 && multi_oval > 0)				jj++;	/* new 3.4.0 */			for (v = now->rgt, i = 0; v; v = v->rgt, i++)			{	switch(v->lft->ntyp) {				case CONST:				case EVAL:					break;				default:					if (!v->lft->sym					||  strcmp(v->lft->sym->name, "_") != 0)					{	nocast=1; putstmnt(tb,v->lft,m);						nocast=0; fprintf(tb, " = trpt->bup.oval");						if (multi_oval > 0)							fprintf(tb, "s[%d]", jj);						fprintf(tb, ";\n\t\t");					}					if (multi_oval > 0)						jj++;					break;			}	}			multi_oval -= ii;		}		break;	case '@':		fprintf(tb, "p_restor(II);\n\t\t");		break;	case ASGN:		nocast=1; putstmnt(tb,now->lft,m);		nocast=0; fprintf(tb, " = trpt->bup.oval");		if (multi_oval > 0)		{	multi_oval--;			fprintf(tb, "s[%d]", multi_oval-1);		}		check_proc(now->rgt, m);		break;	case 'c':		check_proc(now->lft, m);		break;	case '.':	case GOTO:	case ELSE:	case BREAK:		break;	case C_CODE:		fprintf(tb, "sv_restor();\n");		break;	case ASSERT:	case PRINT:		check_proc(now, m);		break;	case PRINTM:		break;	default:		printf("spin: bad node type %d (.b)\n", now->ntyp);		alldone(1);	}}intany_undo(Lextok *now){	/* is there anything to undo on a return move? */	if (!now) return 1;	switch (now->ntyp) {	case 'c':	return any_oper(now->lft, RUN);	case ASSERT:	case PRINT:	return any_oper(now, RUN);	case PRINTM:	case   '.':	case  GOTO:	case  ELSE:	case BREAK:	return 0;	default:	return 1;	}}intany_oper(Lextok *now, int oper){	/* check if an expression contains oper operator */	if (!now) return 0;	if (now->ntyp == oper)		return 1;	return (any_oper(now->lft, oper) || any_oper(now->rgt, oper));}static voidcheck_proc(Lextok *now, int m){	if (!now)		return;	if (now->ntyp == '@' || now->ntyp == RUN)	{	fprintf(tb, ";\n\t\t");		undostmnt(now, m);	}	check_proc(now->lft, m);	check_proc(now->rgt, m);}voidgenunio(void){	char buf1[256];	Queue *q; int i;	ntimes(tc, 0, 1, R13);	for (q = qtab; q; q = q->nxt)	{	fprintf(tc, "\tcase %d:\n", q->qid);		if (has_sorted)		{	sprintf(buf1, "((Q%d *)z)->contents", q->qid);			fprintf(tc, "#ifdef HAS_SORTED\n");			fprintf(tc, "\t\tj = trpt->ipt;\n");	/* ipt was bup.oval */			fprintf(tc, "#endif\n");			fprintf(tc, "\t\tfor (k = j; k < ((Q%d *)z)->Qlen; k++)\n",				q->qid);			fprintf(tc, "\t\t{\n");			for (i = 0; i < q->nflds; i++)			fprintf(tc, "\t\t\t%s[k].fld%d = %s[k+1].fld%d;\n",				buf1, i, buf1, i);			fprintf(tc, "\t\t}\n");			fprintf(tc, "\t\tj = ((Q0 *)z)->Qlen;\n");		}		sprintf(buf1, "((Q%d *)z)->contents[j].fld", q->qid);		for (i = 0; i < q->nflds; i++)			fprintf(tc, "\t\t%s%d = 0;\n", buf1, i);		if (q->nslots==0)		{	/* check if rendezvous succeeded, 1 level down */			fprintf(tc, "\t\t_m = (trpt+1)->o_m;\n");			fprintf(tc, "\t\tif (_m) (trpt-1)->o_pm |= 1;\n");			fprintf(tc, "\t\tUnBlock;\n");		} else			fprintf(tc, "\t\t_m = trpt->o_m;\n");		fprintf(tc, "\t\tbreak;\n");	}	ntimes(tc, 0, 1, R14);	for (q = qtab; q; q = q->nxt)	{	sprintf(buf1, "((Q%d *)z)->contents", q->qid);		fprintf(tc, "	case %d:\n", q->qid);		if (q->nslots == 0)			fprintf(tc, "\t\tif (strt) boq = from+1;\n");		else if (q->nslots > 1)	/* shift */		{	fprintf(tc, "\t\tif (strt && slot<%d)\n",							q->nslots-1);			fprintf(tc, "\t\t{\tfor (j--; j>=slot; j--)\n");			fprintf(tc, "\t\t\t{");			for (i = 0; i < q->nflds; i++)			{	fprintf(tc, "\t%s[j+1].fld%d =\n\t\t\t",							buf1, i);				fprintf(tc, "\t%s[j].fld%d;\n\t\t\t",							buf1, i);			}			fprintf(tc, "}\n\t\t}\n");		}		strcat(buf1, "[slot].fld");		fprintf(tc, "\t\tif (strt) {\n");		for (i = 0; i < q->nflds; i++)			fprintf(tc, "\t\t\t%s%d = 0;\n", buf1, i);		fprintf(tc, "\t\t}\n");		if (q->nflds == 1)	/* set */			fprintf(tc, "\t\tif (fld == 0) %s0 = fldvar;\n",							buf1);		else		{	fprintf(tc, "\t\tswitch (fld) {\n");			for (i = 0; i < q->nflds; i++)			{	fprintf(tc, "\t\tcase %d:\t%s", i, buf1);				fprintf(tc, "%d = fldvar; break;\n", i);			}			fprintf(tc, "\t\t}\n");		}		fprintf(tc, "\t\tbreak;\n");	}	ntimes(tc, 0, 1, R15);}intproper_enabler(Lextok *n){	if (!n) return 1;	switch (n->ntyp) {	case NEMPTY:	case FULL:	case NFULL:	case EMPTY:	case LEN:	case 'R':	case NAME:		has_provided = 1;		if (strcmp(n->sym->name, "_pid") == 0)			return 1;		return (!(n->sym->context));	case CONST:	case TIMEOUT:		has_provided = 1;		return 1;	case ENABLED:	case PC_VAL:		return proper_enabler(n->lft);	case '!': case UMIN: case '~':		return proper_enabler(n->lft);	case '/': case '*': case '-': case '+':	case '%': case LT:  case GT: case '&': case '^':	case '|': case LE:  case GE:  case NE: case '?':	case EQ:  case OR:  case AND: case LSHIFT:	case RSHIFT: case 'c':		return proper_enabler(n->lft) && proper_enabler(n->rgt);	default:		break;	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -