Example #1
0
int getFrame(int notme)
{
	int UPTClock;						// clock for UPT
	int frame;
	frame = getAvailableFrame();
	if (frame >=0) return frame;

	if(RPTClock == 0){
		RPTClock = LC3_RPT;
	}


	int RPTBegin = RPTClock;
	int first = 1;
	int rptCount = 0;

	//iterate the first time through the tables
	while(first || RPTClock != RPTBegin){
		rptCount++;
		first = 0;
		//Check and make sure the notme condition holds
		if(DEFINED(memory[RPTClock])){
			UPTClock = (FRAME(memory[RPTClock])<<6);
			int UPTBegin = UPTClock;
			int uFirst = 1;

			int hadDefined = 0;
			int uptcount = 0;
			while(uFirst || UPTClock != UPTBegin){
				uptcount++;

				uFirst = 0;
				if(DEFINED(memory[UPTClock])){
					hadDefined = 1;
				}
				if(notme != UPTClock && DEFINED(memory[UPTClock])){
					//swap out if not referenced
					if(!REFERENCED(memory[UPTClock])){
						//if it's dirty, write it to memory
						int swapPage = 0;
						if (DIRTY(memory[UPTClock])){
							if(PAGED(memory[UPTClock + 1])) swapPage = accessPage(SWAPPAGE(memory[UPTClock + 1]), FRAME(memory[UPTClock]), PAGE_OLD_WRITE);
							else swapPage = accessPage(0, FRAME(memory[UPTClock]), PAGE_NEW_WRITE);
							memory[UPTClock] = CLEAR_DIRTY(memory[UPTClock]);
							memory[UPTClock+1] = SET_PAGED(swapPage);
							pageWrites++;
						}

						//no longer in main memory--it's swapped!
						memory[UPTClock] = CLEAR_DEFINED(memory[UPTClock]);
						//increment the clock
						if(RPTClock + 2 < LC3_RPT_END)
									RPTClock += 2;
								else
									RPTClock = LC3_RPT;
						return FRAME(memory[UPTClock]);
					}
					memory[UPTClock] = CLEAR_REF(memory[UPTClock]);
				}

				//sanity check
				assert(UPTClock >= 0x3000);
				if(UPTClock + 2 < UPTBegin + LC3_FRAME_SIZE)
					UPTClock += 2;
				else
					UPTClock = UPTBegin;
			}

			if(!REFERENCED(memory[RPTClock]) && !hadDefined && notme != RPTClock){
				int swapPage;
				if(PAGED(memory[RPTClock + 1])) swapPage = accessPage(SWAPPAGE(memory[RPTClock + 1]), FRAME(memory[RPTClock]), PAGE_OLD_WRITE);
				else swapPage = accessPage(0, FRAME(memory[RPTClock]), PAGE_NEW_WRITE);

				memory[RPTClock] = CLEAR_DIRTY(memory[RPTClock]);
				memory[RPTClock+1] = SET_PAGED(swapPage);
				pageWrites++;

				memory[RPTClock] = CLEAR_DEFINED(memory[RPTClock]);

				int rE1 = memory[RPTClock];

				if(RPTClock + 2 < LC3_RPT_END)
							RPTClock += 2;
						else
							RPTClock = LC3_RPT;
				return FRAME(rE1);
			}

			//clear the reference bit
			memory[RPTClock] = CLEAR_REF(memory[RPTClock]);
		}

		if(RPTClock + 2 < LC3_RPT_END){
			RPTClock += 2;
		}
		else{
			RPTClock = LC3_RPT;
		}
	}

	RPTBegin = RPTClock;
	first = 1;

	while(first || RPTClock != RPTBegin){
		rptCount++;
		first = 0;
		//Check and make sure the notme condition holds
		if(DEFINED(memory[RPTClock])){
			UPTClock = (FRAME(memory[RPTClock])<<6);
			int UPTBegin = UPTClock;
			int uFirst = 1;

			int hadDefined = 0;
			int uptcount = 0;
			while(uFirst || UPTClock != UPTBegin){
				uptcount++;

				uFirst = 0;
				if(DEFINED(memory[UPTClock])){
					hadDefined = 1;
				}
				if(notme != UPTClock && DEFINED(memory[UPTClock])){
					//swap out if not referenced
					if(!REFERENCED(memory[UPTClock])){
						//if it's dirty, write it to memory
						int swapPage = 0;
						if (DIRTY(memory[UPTClock])){
							if(PAGED(memory[UPTClock + 1])) swapPage = accessPage(SWAPPAGE(memory[UPTClock + 1]), FRAME(memory[UPTClock]), PAGE_OLD_WRITE);
							else swapPage = accessPage(0, FRAME(memory[UPTClock]), PAGE_NEW_WRITE);
							memory[UPTClock] = CLEAR_DIRTY(memory[UPTClock]);
							memory[UPTClock+1] = SET_PAGED(swapPage);
							pageWrites++;
						}

						//no longer in main memory--it's swapped!
						memory[UPTClock] = CLEAR_DEFINED(memory[UPTClock]);
						//increment the clock
						if(RPTClock + 2 < LC3_RPT_END)
									RPTClock += 2;
								else
									RPTClock = LC3_RPT;
						return FRAME(memory[UPTClock]);
					}
					memory[UPTClock] = CLEAR_REF(memory[UPTClock]);
				}

				//sanity check
				assert(UPTClock >= 0x3000);
				if(UPTClock + 2 < UPTBegin + LC3_FRAME_SIZE)
					UPTClock += 2;
				else
					UPTClock = UPTBegin;
			}

			if(!REFERENCED(memory[RPTClock]) && !hadDefined && notme != RPTClock){
				int swapPage;
				if(PAGED(memory[RPTClock + 1])) swapPage = accessPage(SWAPPAGE(memory[RPTClock + 1]), FRAME(memory[RPTClock]), PAGE_OLD_WRITE);
				else swapPage = accessPage(0, FRAME(memory[RPTClock]), PAGE_NEW_WRITE);

				memory[RPTClock] = CLEAR_DIRTY(memory[RPTClock]);
				memory[RPTClock+1] = SET_PAGED(swapPage);
				pageWrites++;

				memory[RPTClock] = CLEAR_DEFINED(memory[RPTClock]);

				int rE1 = memory[RPTClock];

				if(RPTClock + 2 < LC3_RPT_END)
							RPTClock += 2;
						else
							RPTClock = LC3_RPT;
				return FRAME(rE1);
			}

			//clear the reference bit
			memory[RPTClock] = CLEAR_REF(memory[RPTClock]);
		}

		if(RPTClock + 2 < LC3_RPT_END){
			RPTClock += 2;
		}
		else{
			RPTClock = LC3_RPT;
		}
	}




	//we should never ever be here
	assert(0);



	return -1;
}
Example #2
0
unsigned short int *getMemAdr(int va, int rwFlg)
{
	unsigned short int pa;
	int rpta, rpte1, rpte2;
	int upta, upte1, upte2;
	int rptFrame, uptFrame;
	extern TCB tcb[MAX_TASKS];
	extern int curTask;

	//stat
	memAccess++;

	rpta = tcb[curTask].RPT + RPTI(va);	// 0x2400 + RPTI(va);
	rpte1 = memory[rpta];
	rpte2 = memory[rpta+1];

	// turn off virtual addressing for system RAM
	if (va < 0x3000) return &memory[va];
#if MMU_ENABLE
	if (DEFINED(rpte1))
	{
		// defined
		//stat
		memHits++;
		if (rwFlg)
			rpte1 = SET_DIRTY(rpte1);
	}
	else
	{
		// fault
		//stat
		memPageFaults++;

		rptFrame = getFrame(-1);
		rpte1 = SET_DEFINED(rptFrame);
		if (PAGED(rpte2))
		{
			accessPage(SWAPPAGE(rpte2), rptFrame, PAGE_READ);
			//stat
			pageReads++;
			//clean
			if (rwFlg)
				rpte1 = SET_DIRTY(rpte1);
			else
				rpte1 = CLEAR_DIRTY(rpte1);
		}
		else
		{
			memset(&memory[(rptFrame<<6)], 0, 128);
			//dirty
			rpte1 = SET_DIRTY(rpte1);
		}
	}

	
	rpte1 = SET_PINNED(rpte1);
	memory[rpta] = rpte1 = SET_REF(rpte1);
	memory[rpta+1] = rpte2;

	upta = (FRAME(rpte1)<<6) + UPTI(va);
	upte1 = memory[upta];
	upte2 = memory[upta+1];

	//stat
	memAccess++;

	if (DEFINED(upte1))
	{
		// defined
		//stat
		memHits++;
		if (rwFlg)
			upte1 = SET_DIRTY(upte1);
	}
	else
	{
		// fault
		//stat
		memPageFaults++;

		uptFrame = getFrame(FRAME(memory[rpta]));
		upte1 = SET_DEFINED(uptFrame);
		if (PAGED(upte2))
		{
			accessPage(SWAPPAGE(upte2), uptFrame, PAGE_READ);
			//stat
			pageReads++;
			//clean unless being written to
			if (rwFlg)
				upte1 = SET_DIRTY(upte1);
			else
				upte1 = CLEAR_DIRTY(upte1);
		}
		else
		{
			//dirty
			upte1 = SET_DIRTY(upte1);
		}
	}

	rpte1 = SET_PINNED(rpte1);
	memory[rpta] = rpte1;
	memory[upta] = upte1 = SET_REF(upte1);
	memory[upta+1] = upte2;


	return &memory[(FRAME(upte1)<<6) + FRAMEOFFSET(va)];
#else
	return &memory[va];
#endif
} // end getMemAdr