I'm suppose to translate a virtual address to a physical address with the use of a fully-associative page table.


It compiles but it won't run. Can anyone help me and point out the errors :P THANK YOU!

# include<stdio.h>
# include<stdlib.h>
/* Declare global vars */
int ms;
int ps;
int rep;
int ne;

/* Create page table */
struct node{
	int vp;
	int pf;
} *pt = NULL;
typedef struct node entry;

void enter_params() { /* Op1 */
	/* Local vars */
	int i; 
	
	ne = (ms / ps);
	/* Prompt memory size, page size, replacement policy */
	printf("Enter main memory size (words): ");
	scanf("%d", &ms);
	printf("Enter page size (words/page): ");
	scanf("%d", &ps);
	printf("Enter replacement policy (0=LRU, 1=FIFO): ");
	scanf("%d", &rep);
	
	/* Build page table */
	pt = (entry*) malloc (ne * sizeof (entry));
	
	/* Initialize pt */
	/* for-loop: i = 0 to ne - 1 */
	for(i = 0; i <= ne - 1; i++) {
		pt[i].vp = -1;
	}
}


void mapping_addr() { /* Op2 */
	/* local vars */
	int va;
	int pf;
	int vp;
	int offset;
	int pa;
	int i;
	int k;
	int rep;
	

	/* prompt va */
	printf("Enter virtual memory address to access: ");
	scanf("&d", &va);
	
	/* calculate vp & offset */
	vp = (va / ps);
	offset = (va % ps);
	va = ((vp * ps) + offset);

	/* check if mapping in pt */
	/* case 1: page hit! */
	if(pt[i].vp == vp) {
		pa = ((pf *ps) + offset);
		/* apply replacement policy: MRU */
		printf("Virtual address %d maps to physical address %d", &va, &vp);

	}
	
	/* case 2: page fault! find empty, add vp there */
	if(pt[i].vp == -1) {
		/* insert vp into pt */
		pt[i].vp = vp;
		/* insert pf into pt */
		pt[i].pf = i;
		printf("Page fault!");
	}

	/* case 3: page fault! pt is full */
	if(i == ne) {
		pf = pt[0].pf;
		for(i = 0; i <= ne -2; i++) {
			pt[i] = pt[i+1];
		}
		/* insert vp into pt */
		pt[ne -1].vp = vp;
		/* insert pf into pt */
		pt[ne -1].pf = pf;
		printf("Page fault!");
	}	
	
	while((i < ne) && (pt[i].vp != vp) && (pt[i].vp != -1)) { /* not c3, not c1, not c2 */
		i++; /* keep searching */
	}
	
	/* outside while-loop */
	if(i == ne) {
	/* replace entry in pt */
	pf = pt[0].pf;
	/* for-loop: k = 0 to (ne -2) */
		for(k = 0; k <= (ne - 2); k++) {
			pt[k].vp = pt[k + 1].vp;
			pt[k].vp = pt[k + 1].pf;	
		}
		/* outside for-loop */
		pt[ne -1].vp = vp;
		pt[ne -1].pf = pf;
		printf("Page fault!");
	} /* end if-loop: i == ne */

	else if(pt[i].vp == -1) {
		/* insert vp into pt */
		pt[i].vp = vp;
		pt[i].pf = i;
		printf("Page fault!");
	} /* end-if: if empty entry */

	else { /* if pt[i].vp == vp; */
		/* calc pa */
		pa = (pt[i].pf * ps) + (offset);
		printf("Virtual address %d maps onto physical address %d", &va, &pa);
		
		if(rep == '0') {
			for(k = i; k <= ne - 1; k++) {
				if(pt[k].vp == -1) {
					k = ne;
				}
				pt[k].vp = pt[k + 1].vp;
				pt[k].vp = pt[k + 1].pf;
			}
		}
	}
}

void print_pt() { /* Op3 */
	/* Local vars */
	int i;
	int vp;
	int pf;
	
	i = 0;
	/* while loop */
	while((i < ne) && (pt[i].vp != -1)) {
		/*print entry*/
		printf("VP %d ---> PF %d;", &vp, &pf);
		i++;
	}
}

void quit_prog() { /* Op4 */
	if(pt != NULL) {
		free(pt);
	}
}

int main() { /* Main menu option */
	int selection;

	while(selection != 4) {
		printf("Virtual memory to Main Memory mapping:\n");
		printf("1) Set parameters\n");
		printf("2) Map virtual address\n");
		printf("3) Print page table\n");
		printf("4) Exit\n\n");
		printf("Enter selection: ");
		scanf("%d", &selection);

		switch(selection) {
			case 1: enter_params();
			break;
									
			case 2: mapping_addr();
			break;
				
			case 3: print_pt();
			break;
		
			case 4: quit_prog();
			break;
						
			default: printf("\nInvalid selection!\n");
		}
	}
}

>> It compiles but it won't run.

It doesn't compile cleanly though, GCC spotted a number of things ..

\main.c:16:6: warning: no previous declaration for 'enter_params'
\main.c:40:6: warning: no previous declaration for 'mapping_addr'
\main.c: In function 'mapping_addr':
\main.c:49:6: warning: declaration of 'rep' shadows a global declaration
\main.c:6:5: warning: shadowed declaration is here
\main.c:54:2: warning: too many arguments for format
\main.c:66:3: warning: format '%d' expects type 'int', but argument 2 has type 'int *'
\main.c:66:3: warning: format '%d' expects type 'int', but argument 3 has type 'int *'
\main.c:121:3: warning: format '%d' expects type 'int', but argument 2 has type 'int *'
\main.c:121:3: warning: format '%d' expects type 'int', but argument 3 has type 'int *'
\main.c: At top level:
\main.c:135:6: warning: no previous declaration for 'print_pt'
\main.c: In function 'print_pt':
\main.c:145:3: warning: format '%d' expects type 'int', but argument 2 has type 'int *'
\main.c:145:3: warning: format '%d' expects type 'int', but argument 3 has type 'int *'
\main.c: At top level:
\main.c:150:6: warning: no previous declaration for 'quit_prog'
\main.c: In function 'main':
\main.c:184:1: warning: control reaches end of non-void function
\main.c: In function 'mapping_addr':
\main.c:63:7: warning: 'i' is used uninitialized in this function
\main.c:64:13: warning: 'pf' may be used uninitialized in this function
\main.c:123:5: warning: 'rep' may be used uninitialized in this function

Really? I tried it again, it compiles and runs. But now when I ask for to input the parameters, it just crashes.

An uninitialized global variable takes the value 0. Doing a 0/0 division will give you an Arithmetic exception. I think this should solve the crashing issue.

How did you compile the program ? I also got the same compilation errors that mitrmkar got

#
ne = (ms / ps);

You're talking about this one right?

jGrasp, -gcc compiler

Okay so I not really sure what I did, I'm able to set my parameters now. But now it crashes when I want to map it.

I think the 3 cases might be the problem, can I leave as all as 'if' or do I have to set them as 'else if' statements?

/* check if mapping in pt */
	/* case 1: page hit! */
	if(pt[i].vp == vp) {
		pa = ((pf *ps) + offset);
		/* apply replacement policy: MRU */
		printf("Virtual address %d maps to physical address %d", &va, &vp);

	}
	
	/* case 2: page fault! find empty, add vp there */
	if(pt[i].vp == -1) {
		pt[i].vp = vp;
		pt[i].pf = i;
		printf("Page fault!");
	}

	/* case 3: page fault! pt is full */
	if(i == ne) {
		pf = pt[0].pf;
		for(i = 0; i <= ne -2; i++) {
			pt[i] = pt[i+1];
		}
		/* insert vp into pt */
		pt[ne -1].vp = vp;
		/* insert pf into pt */
		pt[ne -1].pf = pf;
		printf("Page fault!");
	}

Should this be an 'else if' statement?

This question has already been answered. Start a new discussion instead.