/* 
	Listing 2
*/

#include <stdio.h>
#include "enet_cs.h"

long 	critical_status=NORMAL;

int i, j, node, turn_num, flag_num;

/* Program by Matt Weisfeld */

main(argc,argv)
int argc;
char **argv;
{


	fprintf (stderr,"%sENET_CS%s(1.0)\n", bold,norm);

	if (argc != 2)  {
		printf ("Error: bad number of args.\n");
		exit(0);
	}

	node = atoi(argv[1]);

	intro();	/* print out informational messages */

	i = node;

	/* perform critical function until exit condition exists */

	while (critical_status == NORMAL) {
		perform();
	}

   	return;


}

perform()
{

	/*
	  A do-while (!expression) is the same as
		do-until (expression)
	*/

	do {

		cs_write ( i, WANT_IN);

		turn_num = cs_read ( TURN_LOC);

		j = turn_num;

		while (j != i) {

			flag_num = cs_read ( j);

			if (flag_num != IDLE) {

				turn_num = cs_read ( TURN_LOC);

				j = turn_num;

			} else {
			

				j = (j+1) % PROCESSES;


			}

		}
		
		cs_write ( i, IN_CS);
	
		
		j = 0;

		flag_num = cs_read ( j);

		while ( (j<PROCESSES-1) && (j==i || flag_num!=IN_CS) ) {
	
			j++;

			flag_num = cs_read ( j);

		}

		turn_num = cs_read ( TURN_LOC);

		flag_num = cs_read ( turn_num);

	}while (!((j>=PROCESSES-1) && ((turn_num == i) || flag_num == IDLE)));

	turn_num = i;

	cs_write ( TURN_LOC, turn_num);


	/* enter critical section */

	critical_status = critical_section();

	/* leave critical section */

	turn_num = cs_read ( TURN_LOC);

	j = (turn_num+1) % PROCESSES;

	flag_num = cs_read ( j);

	while (flag_num == IDLE) {

		j = (j+1) % PROCESSES;

		flag_num = cs_read ( j);

	}

	turn_num = j;

	cs_write ( TURN_LOC, turn_num);

	flag_num = IDLE;

	cs_write ( i, flag_num);

}


intro()
{

	switch (node) {

		case NODE0:
			printf ("PROCESSOR NODE0\n");
		break;

		case NODE1:
			printf ("PROCESSOR NODE1\n");
		break;

		case NODE2:
			printf ("PROCESSOR NODE2\n");
		break;

		default:
			printf ("Error: invalid processor\n");
			exit(0);
		break;
			

	}

}

