gnwillix88 0 Newbie Poster

Is there anything wrong with my program,or a better implementation of OPTIMAL. Error returned is as below:
Error restoring the refrence stresm
Error was: invalid urgment

#include "pager_OPTIMAL.h"

/*#define DEBUG 1*/	/*define this and the next one for maximum debugging info*/
/*#define DEBUG2 1*/  	/*difne only this one for minimul debugging */
pt_entry pte[MAX_PAGE];		/* page table */
int mem_size;			/* physical memory size in page frames */
list free_list_head;			/* free list */ 
list res_set_head;					/* resident set */
int total_fault = 0;				/* total number of page faults */
int total_ref = 0;					/* total number of memory references */
FILE *stream;					/* Reference stream, made global to avoid having to pass it all over the place */


/* changed main to return int to remove a warning-EC*/
int main(int argc, char *argv[])
{
//FILE *stream;

	if (argc != 3)
	{
		printf("The format is: pager file_name memory_size.\n");
		exit(1);
	}

	printf("File used %s, resident set size %d\n", argv[1], atoi(argv[2]));

	if ((stream = fopen(argv[1], "r")) == NULL)
	{
		perror("File open failed");
		exit(1);
	}

	if( MAX_PAGE >= (mem_size = atoi(argv[2])) )
	{
		/* everything is fine we can go ahead */
		start_simulation();
	}
	else
	{
		printf("\n\n\a\a\a***************************************************\n");
		printf("***************************************************\n");
		printf("**                                               **\n");
		printf("** Error:                                        **\n");
		printf("**                                               **\n");
		printf("** You are attempting to use a resident set size **\n");
		printf("** that is larger than the address space!        **\n");
		printf("**                                               **\n");
		printf("** The maximum address space size is: %-4d       **\n",MAX_PAGE);
		printf("**                                               **\n");
		printf("***************************************************\n");
		printf("***************************************************\n\n\n");

	}
	fclose(stream);
	
	return 0;
}


void start_simulation(/*FILE * stream*/void)
{
	/*char *addr_buf;not used so removed --EC*/
	int address;
	int i, n;
	list new_entry, current;

/* initialise the page table */

for(i=0; i<MAX_PAGE;i++)
	{
		pte[i].frame = -1;
		pte[i].valid = 0;
		pte[i].dirty = 0;
		pte[i].in_mem = 0;
 		pte[i].next_ref=-1;

	}	
/* initialise the resident set - empty*/

	res_set_head = (list)malloc(sizeof(struct list_item));
	res_set_head->next = res_set_head;
	res_set_head->prev = res_set_head;
	
/* initialise free list - all physical pages*/

	free_list_head = (list)malloc(sizeof(struct list_item));
	free_list_head->next = free_list_head;
	free_list_head->prev = free_list_head;
	current = free_list_head;
	
	for(i=0; i<mem_size;i++)
	{
		new_entry = (list)malloc(sizeof(struct list_item));
		current->next = new_entry;
		new_entry->prev = current;
		new_entry->next = free_list_head;
		new_entry->frame = i;
		current = new_entry;
		free_list_head->prev = current;
	}

/* main simulation loop */
while((n = fscanf(stream, "%x", &address)) != -1)
	{
#ifdef DEBUG2
		printf("Reference %i -------------\n",total_ref);
#endif

		resolve(address);
		total_ref++; 
	}

	free_mem(free_list_head);
	free_mem(res_set_head);
	display_stats();
	
	return; 
}


void resolve(int address)
{
	unsigned short frame_alloc;
	int virt_page,i;
	/*static int disp_counter = 0;not used so removed -EC*/
	virt_page = address >> 8;
	if (pte[virt_page].valid == 1)
	{
		pte[virt_page].next_ref=distance_to_next_ref(virt_page);
#ifdef DEBUG2
		printf("Page %i is valid, next reference is: %i\n",virt_page,pte[virt_page].next_ref);
#endif
	}
	else
	{
		frame_alloc = find_frame();
		pte[virt_page].valid = 1;
		pte[virt_page].frame = frame_alloc;
		total_fault++;
		pte[virt_page].next_ref=distance_to_next_ref(virt_page);
#ifdef DEBUG2
		printf("Page %i is being loaded, next reference is: %i\n",virt_page,pte[virt_page].next_ref);
#endif
	}
	for(i=0;i<MAX_PAGE;i++)
       	{
		if(pte[i].valid) pte[i].next_ref--;
		//if(pte[i].next_ref<=0) pte[i].next_ref = distance_to_next_ref(i);
		/* if the page is valid update the next ref time */
       	}
}

unsigned short find_frame()
{
	unsigned short frame;
	list current, new_tail;

	if (free_list_head == free_list_head->prev)   /* free list empty */
	{
#ifdef DEBUG
		printf("Free list empty finding frame\n");
#endif	
		frame = find_victim();
	}
	else
	{
#ifdef DEBUG
		printf("Free list not empty grabbing frame\n");
#endif
		new_tail = free_list_head->prev->prev;
		new_tail->next = free_list_head;
		current = free_list_head->prev;
		free_list_head->prev = new_tail;
		
		to_resident_set(current);
		frame = current->frame;
	}
	return frame;
}

void to_resident_set(list current)
{
	list tail;
	
	tail = res_set_head->prev;
	tail->next = current;
	current->next = res_set_head;
	current->prev = tail;
	res_set_head->prev = current;
}
	

unsigned short find_victim()
{
	int candidate,frame=-1,most_far=0,page;
	for(candidate=0;candidate<MAX_PAGE;candidate++)
	{
		if(pte[candidate].valid==1)
		{
#ifdef DEBUG
			printf("\tValid Page %i is being examined, next reference is: %i\n",candidate,pte[candidate].next_ref);
			printf("Pt entry:\n\t\tFrame: %d\n\t\tValid: %d\n\t\tin_mem %d\n\t\tDirty: %d\n\t\tNext ref %d\n",pte[candidate].frame,pte[candidate].valid,pte[candidate].in_mem,pte[candidate].dirty,pte[candidate].next_ref);
#endif
			if(  (pte[candidate].next_ref) < 0 ) 
			{
#ifdef DEBUG
				printf("\t\t< 0 Page %i is being examined, next reference is: %i\n",candidate,pte[candidate].next_ref);
#endif

				pte[candidate].valid=0;
				frame = pte[candidate].frame;
				pte[candidate].frame=-1;
				return frame;
			}
#ifdef DEBUG
		printf("Middle for page %i\n",candidate);
#endif
			if(most_far < (pte[candidate].next_ref) )
			{
#ifdef DEBUG
				printf("\t\t> mf Page %i is being examined, next reference is: %i\n",candidate,pte[candidate].next_ref);
#endif
				frame=pte[candidate].frame;
				most_far=pte[candidate].next_ref;
			}
#ifdef DEBUG
		printf("Ending for page %i\n",candidate);
#endif
		}	
	}
	invalidate(frame);

	return frame;
}


void invalidate(unsigned short frame)
{
	int i;

	for(i=0;i<MAX_PAGE;i++)
	{
		if (pte[i].frame == frame && pte[i].valid == 1)
		{
			pte[i].valid = 0;
			pte[i].frame = -1;
#ifdef DEBUG
			printf("Page %i is being evicted next ref is: %i\n",i,pte[i].next_ref);
#endif
			break;
		}	
	}
}

void display_stats()
{
	printf("\nProcess issued %d memory references\n", total_ref);
	printf("Process triggered %d page faults\n", total_fault);
	printf("Page fault rate is %d percent\n",((total_fault*100)/total_ref));
}
/* free_mem:
** free memory allocated to the list
*/
void free_mem(list head)
{

	list current,tail;
	
	tail = head->prev;
	current = head;
	
	while (current->prev != tail)
	{
		current = current->next;
		free(current->prev);
	}
}

/* finds the distance to the next ref, returns -1 if never referenced again */


int distance_to_next_ref(int frame)
{
   long pos;
   int n,count;
   int address,page;  
   
	if((pos=ftell(stream))==-1)
	{
		printf("Error saving reference stream position\n");
		perror("Error was");
		fclose(stream);
		exit(1);
	}
 	count=0;
	while( (n = fscanf(stream, "%x", &address)) != -1)
   	{
                count++;	
		page=address>>8;
		if(page==frame)
		{
			if((fseek(stream,pos,SEEK_SET))==-1)
			{
				printf("Error restoring the reference stream position\n");
				perror("Error was:");
				fclose(stream);
			}

			return count;
		}
	}
	if((fseek(stream,pos,SEEK_SET))==-1)
	{
		printf("Error restoring the reference stream position\n");
		perror("Error was:");
		fclose(stream);
	}
	
	return -1;
}