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; }
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