void smartPageIn(PPP* active, int numActive, PPP* comingUp, int numComingUp, PPP* available, int numAvailable, Pentry* q) { int i; PPP cur; int used = 0; //try to pagein the active ones for(i = 0; i < numActive; ++i) { cur = active[i]; if(!q[cur.proc].pages[cur.page]) { if(!pagein(cur.proc, cur.page)) { //if we can't pagein any more pages, and we don't have any more available to pageout, then break if(used >= numAvailable) { break; } pageout(available[used].proc, available[used].page); ++used; } } } for(i = 0; i < numComingUp; ++i) { cur = comingUp[i]; if(!q[cur.proc].pages[cur.page]) { if(!pagein(cur.proc, cur.page)) { if(used >= numAvailable) { //same deal as above - nothing else to do now //not as crutial, since these pages aren't needed yet, and may never be needed break; } pageout(available[used].proc, available[used].page); ++used; } } } }
void pageit(Pentry q[MAXPROCESSES]) { // these are globals that only the subroutine can see static int tick=0; // artificial time static int timestamps[MAXPROCESSES][MAXPROCPAGES]; // these are regular dynamic variables on stack int proc,pc,page,oldpage; // select first active process for (proc=0; proc<MAXPROCESSES; proc++) { // if active, then work on it ONLY if (q[proc].active) { pc=q[proc].pc; // program counter for process page = pc/PAGESIZE; // page the program counter needs timestamps[proc][page]=tick; // last access if (!q[proc].pages[page]) { // if page is not there: if (!pagein(proc,page)) { // try to swap in, if this fails: // look at all old pages, swap out any other pages for (oldpage=0; oldpage<q[proc].npages; oldpage++) { // if I find a page that's not equal to the one I want, // swap it out => 100 ticks later, pagein will succeed. if (oldpage!=page && pageout(proc,oldpage)) break; // ^^^^^^^^^^^^^^^^^^^^^ swapout starts // ^^^^^^^^^^^^^ it's not the page I want } } } break; // no more } } tick++; // advance time for next iteration }
static void pageouttext(int pgszi, int color) { Proc *p; Pgsza *pa; int i, n, np, x; Segment *s; int prepaged; USED(color); pa = &pga.pgsza[pgszi]; n = x = 0; prepaged = 0; /* * Try first to steal text pages from non-prepaged processes, * then from anyone. */ Again: do{ if((p = psincref(x)) == nil) break; np = 0; if(p->prepagemem == 0 || prepaged != 0) if(p->state != Dead && p->noswap == 0 && canqlock(&p->seglock)){ for(i = 0; i < NSEG; i++){ if((s = p->seg[i]) == nil) continue; if((s->type&SG_TYPE) == SG_TEXT) np = pageout(p, s); } qunlock(&p->seglock); } /* * else process dead or locked or changing its segments */ psdecref(p); n += np; if(np > 0) DBG("pager: %d from proc #%d %#p\n", np, x, p); x++; }while(pa->freecount < Minpages); if(pa->freecount < Minpages && prepaged++ == 0) goto Again; }
void pager(Pentry q[MAXPROCESSES]){ int f; int t; int min=INT_MAX; int minI=0; int minIT; int max=0; int maxI=0; for(f=0;f<MAXPROCESSES;f++){ for(t=0;t<MAXPROCPAGES;t++){ if(q[f].pages[t]){//if swapped in if(timestamps[f][t]<min){ min=timestamps[f][t]; minI=t; minIT=f; } if(timestamps[f][t]>max){ max=timestamps[f][t]; maxI=t; } } } if(tick-min>WINDOW){ pageout(f,t); } min=INT_MAX; minI=0; minIT; max=0; maxI=0; } }
void swap_page(Pentry q[MAXPROCESSES], int timestamps[MAXPROCESSES][MAXPROCPAGES], int proc, int page, int current, int hotpage[MAXPROCESSES][MAXPROCPAGES], int prediction[MAXPROCESSES][MAXPROCPAGES]){ int pagetmp, outproc, evictpage, least, hotness; //is page swapped in current++; if(!q[proc].pages[page]){ //page not swapped in if(!pagein(proc,page)){ //failure - select a page to evict //find a default page for(pagetmp = 0; pagetmp < MAXPROCPAGES; pagetmp++){ if(q[proc].pages[pagetmp] && timestamps[proc][pagetmp] > 0){ least = timestamps[proc][pagetmp]; evictpage = pagetmp; outproc = proc; hotness = hotpage[proc][page]; //printf("do have a default\n"); break; } } //look for better - LRU for(pagetmp = 1; pagetmp < MAXPROCPAGES; pagetmp++){ if(!q[proc].pages[pagetmp]) //cant evict page thats not in continue; if(timestamps[proc][pagetmp] > least && !prediction[proc][page]){ least = timestamps[proc][pagetmp]; evictpage = pagetmp; outproc = proc; // hotness = hotpage[proctmp][pagetmp]; // printf("current LRU timestamp = %d\n", least); } if(hotpage[proc][pagetmp] < hotness){ hotness = hotpage[proc][pagetmp]; // evictpage = pagetmp; // outproc = proc; } } //call pageout() if(q[outproc].pages[evictpage]){ //can only evict page thats in pageout(outproc, evictpage); //and if have prediction put it in so its there before needed pagein(proc, page); } } } }
static uchar* pagein(vlong offset, int len) { pageout(); if(offset >= partend){ memset(buf, 0xFB, sizeof buf); return buf; } if(offset+len > partend){ memset(buf, 0xFB, sizeof buf); len = partend - offset; } bufoffset = offset; buflen = len; readdisk(buf, offset, len); memmove(sbuf, buf, len); return buf; }
static void lru_pageit(Pentry q[MAXPROCESSES],int tick) { int proc,pg,evicted; for(proc=0;proc<MAXPROCESSES;proc++) { pg=q[proc].pc/PAGESIZE; timestamps[proc][pg]=tick; if(pagein(proc,pg)) continue; if(pages_alloc(q,proc)<1) continue; lru_page(q,proc,tick,&evicted); pageout(proc,evicted); } }
static void lru_pageit(Pentry q[MAXPROCESSES], uint32_t tick) { int proc, page, state, evicted; for(proc = 0; proc < MAXPROCESSES; proc++) { if(!q[proc].active) /* done if its not active */ continue; page = q[proc].pc/PAGESIZE; /* note this time for future eviction decisions */ timestamps[proc][page] = tick; /* done if the page is already in memory */ if(q[proc].pages[page]) continue; /* the page is not in memory. * if pagein give 1 the page is either * on its way already or we just got it * started, so we are done with this process */ if(pagein(proc, page, &state) ) continue; /* either the page is swapping out or * there are no free physical pages */ if(state == SWAPOUT) continue; /* just have to wait... */ /* there are no free physical pages */ if(pages_alloc(q, proc) < 1) continue; /* must have at least one page to evict */ lru_page(q, proc, tick, &evicted); if(!pageout(proc, evicted) ) { endit(); } } }
void handleLRUSwap(int proc, int timestamps[MAXPROCESSES][MAXPROCPAGES], int tick, Pentry q[MAXPROCESSES]){ /*Local variable*/ int i; int oldest=tick; int oldpage; for(i=0; i<MAXPROCPAGES; i++){ /*If it's swapped in*/ if(q[proc].pages[i]) /*Figure out how old it is*/ if(timestamps[proc][i]<oldest){ oldest=timestamps[proc][i]; //This is our new oldest oldpage=i; //Keep track of the page to remove } } /*If we can't page out this page something went wrong*/ pageout(proc,oldpage); }
void pageit(Pentry q[MAXPROCESSES]) { /* This file contains the stub for an LRU pager */ /* You may need to add/remove/modify any part of this file */ //printf("%ld",processes[0]->pid); /* Static vars */ static int initialized = 0; //static int tick = 1; // artificial time //printf("here\n"); /* Local vars */ int proctmp; int minPageTwo; int secondMinPageOne; int secondMinPageTwo; int pagetmp; int secondMaxPage; int secondsecondMaxPage; int pc; int page; static int procount=0; int min; int pageOne; int predOne; int predTwo; int predThree; int swapRow=0; int swapCol=0; int tmppage; int proc; int pageTwo; int minPage; int i; int minPageOne; /* initialize static vars on first run */ if(!initialized){ for(proctmp=0; proctmp < MAXPROCESSES; proctmp++){ for(pagetmp=0; pagetmp < MAXPROCPAGES; pagetmp++){ timestamps[proctmp][pagetmp] = 0; pageLastRemovedAt[proctmp][pagetmp]=0; numberofpagesout=0; for(i=0; i<2;i++){ betRevlentPage[proctmp][pagetmp][i]=0; } for(i=0;i<MAXPROCPAGES;i++){ revelentPageFreq[proctmp][pagetmp][i]=0; } } lastPageCalled[proctmp]=0; } tick=1; prevtick=0; initialized = 1; } //pager(); for(proc=0; proc <MAXPROCESSES; proc++){ //printf("1\n"); if(q[proc].active){ //printf("2\n"); pc = q[proc].pc; page=pc/PAGESIZE; /*if(procount>=4){ pager(q); }*/ timestamps[proc][page] = tick; tmppage=lastPageCalled[page]; betRevlentPage[proc][tmppage][1]=betRevlentPage[proc][tmppage][0]; betRevlentPage[proc][tmppage][0]=page; predOne=betRevlentPage[proc][page][0]; predTwo=betRevlentPage[proc][predOne][0]; predThree=betRevlentPage[proc][predTwo][0]; revelentPageFreq[proc][tmppage][page]++; lastPageCalled[proc]=page; pageOne=arrayMax(proc,page,&secondMaxPage); pageTwo=arrayMax(proc,pageOne,&secondsecondMaxPage); minPageOne=arrayMin(q,proc,page,&secondMinPageOne); minPageTwo=arrayMin(q,proc,pageOne,&secondMinPageTwo); minPage=lru(q,proc,page); pagein(proc,page); pagein(proc,pageTwo); pagein(proc,pageOne); /*if(secondMaxPage!=-100 && secondMaxPage!=secondMinPageOne){ pagein(proc,secondMaxPage); if(secondMinPageOne!=-100){ pageout(proc, secondMinPageOne); } } if(secondMaxPage!=-100 && secondMaxPage!=secondMinPageTwo){ pagein(proc,secondsecondMaxPage);* if(secondMinPageTwo!=-100){ pageout(proc,secondMinPageTwo); } }*/ //pagein(proc,predThree); //pagein(proc,predTwo); //pagein(proc,predOne); if(!q[proc].pages[page]){ effChecker(proc,page); if(!pagein(proc,page)){ pageout(proc,minPage); pageout(proc,minPageOne); pageout(proc,minPageTwo); if(secondMinPageTwo!=-100){ pageout(proc,secondMinPageTwo); } if(secondMinPageOne!=-100){ pageout(proc, secondMinPageOne); } }else if(!pagein(proc,pageTwo)){ pageout(proc,minPage); pageout(proc,minPageOne); if(secondMinPageTwo!=-100){ pageout(proc,secondMinPageTwo); } if(secondMinPageOne!=-100){ pageout(proc, secondMinPageOne); } }else if(!pagein(proc,pageOne)){ //pageout(proc,minPage); pageout(proc,minPage); pageout(proc,minPageOne); pageout(proc,minPageTwo); //pageout(proc,minPageOne); if(secondMinPageTwo!=-100){ pageout(proc,secondMinPageTwo); } if(secondMinPageOne!=-100){ pageout(proc, secondMinPageOne); } } } }else{//remove all things related to the process if not active for(i=0;i<MAXPROCPAGES;i++){ pageout(proc,i); procount++; } } } /* TODO: Implement LRU Paging */ //pager(q); /* advance time for next pageit iteration */ pager(q); tick++; }
void pageit(Pentry q[MAXPROCESSES]) { /* This file contains the stub for a predictive pager */ /* You may need to add/remove/modify any part of this file */ /* Static vars */ static int initialized = 0; static int tick = 1; // artificial time static int timestamps[MAXPROCESSES][MAXPROCPAGES]; //help with LRU static int hotpage[MAXPROCESSES][MAXPROCPAGES]; //help choosing new page static int repeats[MAXPROCESSES][MAXPROCPAGES]; //predict repeating pages static int repeatset[MAXPROCESSES][MAXPROCPAGES]; //when to update repeats static int preceeds[MAXPROCESSES][MAXPROCPAGES][MAXPROCPAGES]; //frequency of what comes after what static int proc_status[MAXPROCESSES]; static int predictions[MAXPROCESSES][MAXPROCPAGES]; static int goodpredict = 0; static int miss = 0; /* Local vars */ // int hotpage[MAXPROCESSES][MAXPROCPAGES]; //help choosing new page // int repeatset[MAXPROCESSES][MAXPROCPAGES]; //when to update repeats // int repeats[MAXPROCESSES][MAXPROCPAGES]; //predict repeating pages // int preceeds[MAXPROCESSES][MAXPROCPAGES][MAXPROCPAGES]; //frequency of what comes after what // int serieslength = 5; int series[MAXPROCESSES][serieslength]; int seriescount[MAXPROCESSES] = { 0 }; int seriesfull[MAXPROCESSES] = { 0 }; int proctmp, pagetmp, proc, pc, page, pagepred, nextpg, lastproc, lastpage; int procactive = 0; //btw none of these are actually static rn int activeq[MAXPROCESSES]; int goodpredictor[MAXPROCESSES][4] = { { 0 } }; //maybe add a proc dimension int bestoption = 0; static int missrate[MAXPROCESSES]; //reset every 10 or so... static int hitrate[MAXPROCESSES]; //same int successrate[MAXPROCESSES]; static int repeatcount[MAXPROCESSES]; static int samepage[MAXPROCESSES]; static int currentpredictor[MAXPROCESSES] = { 1 }; static int prevpredictor[MAXPROCESSES] = { 1 }; int prevpage[MAXPROCESSES] = { -1 }; int prevpred[MAXPROCESSES] = { -1 }; // static int pagelock[MAXPROCESSES][MAXPROCPAGES]; int current; static int prediction[MAXPROCESSES][MAXPROCPAGES]; /* initialize static vars on first run */ if(!initialized){ /* Init complex static vars here */ for(proctmp=0; proctmp < MAXPROCESSES; proctmp++){ missrate[proctmp] = 0; hitrate[proctmp] = 0; repeatcount[proctmp] = 0; samepage[proctmp] = 0; proc_status[proctmp] = 0; for(pagetmp=0; pagetmp < MAXPROCPAGES; pagetmp++){ prediction[proctmp][pagetmp] = 0; timestamps[proctmp][pagetmp] = 0; hotpage[proctmp][pagetmp] = 0; repeats[proctmp][pagetmp] = 0; repeatset[proctmp][pagetmp] = 0; // pagelock[proctmp][pagetmp] = 0; for(nextpg=0; nextpg < MAXPROCPAGES; nextpg++){ preceeds[proctmp][pagetmp][nextpg] = 0; } } } initialized = 1; } /* TODO: Implement Predictive Paging */ //init prediction helpers for(proctmp=0; proctmp < MAXPROCESSES; proctmp++){ for(pagetmp=0; pagetmp < MAXPROCPAGES; pagetmp++){ // hotpage[proctmp][pagetmp] = 0; // repeatset[proctmp][pagetmp] = 0; // repeats[proctmp][pagetmp] = 0; // for(nextpg=0; nextpg < MAXPROCPAGES; nextpg++){ // preceeds[proctmp][pagetmp][nextpg] = 0; // } if(pagetmp < serieslength) series[proctmp][pagetmp] = -1; } } //select process for(proctmp = 0; proctmp < MAXPROCESSES; proctmp++){ //find active processes and update if(q[proctmp].active){ activeq[procactive] = proctmp; procactive++; page = q[proctmp].pc / PAGESIZE; timestamps[proctmp][page] = tick; } else { //swap out any unactive pages for(pagetmp = 0; pagetmp < MAXPROCPAGES; pagetmp++){ if(q[proctmp].pages[pagetmp]) pageout(proctmp,pagetmp); } } } lastproc = 0; lastpage = 0; int i, j; //all active processes for(i = 0; i < procactive; i++){ proc = activeq[i]; pc = q[proc].pc; page = pc / PAGESIZE; //determine current page //printf("previous proccess %d and previous page %d\n", lastproc, lastpage); //printf("current process %d and current page %d\n", proc, page); prediction[proc][page] = 0; if(prevpred[proc] != -1 && page != prevpred[proc]){ //printf("MISS: current page: %d, previously predicted: %d\n", page, prevpred[proc]); miss++; missrate[proc]++; // pagelock[proc][prevpred[proc]] = 0; goodpredictor[proc][prevpredictor[proc]-1]--; } else if(page == prevpred[proc]){ // printf("HIT: current page: %d, previously predicted: %d\n", page, prevpred[proc]); goodpredict++; hitrate[proc]++; goodpredictor[proc][prevpredictor[proc]-1]++; // pagelock[proc][page] = 1; } successrate[proc] = hitrate[proc] - missrate[proc]; // printf("success rate: %d\n", successrate[proc]); //update other pages for LRU for(pagetmp = 0; pagetmp < MAXPROCPAGES; pagetmp++){ timestamps[proc][pagetmp]++; } //and reset the counter for most recent timestamps[proc][page] = 0; //update hotness for choosing a new page /* if(hotpage[proc][page] > 150){ //hot cap for(pagetmp = 0; pagetmp < MAXPROCPAGES; pagetmp++) hotpage[proc][pagetmp] = 0; hotpage[proc][page] = 5; } else hotpage[proc][page]++; */ hotpage[proc][page]++; //update repeats for predicting sequential calls if(page == prevpage[proc]){ if(!repeatset[proc][page]){ samepage[proc]++; repeats[proc][page] = samepage[proc]; } repeatcount[proc]++; } else if(repeats[proc][prevpage[proc]] > 0){ repeatset[proc][prevpage[proc]] = 1; if(repeats[proc][prevpage[proc]] > 6){ repeats[proc][prevpage[proc]] = 0; repeatset[proc][prevpage[proc]] = 0; } samepage[proc] = 0; repeatcount[proc] = 0; } //printf("current page: %d repeats %d times\n", page, repeats[proc][page]); //update preceeds if(prevpage[proc] != -1){ preceeds[proc][prevpage[proc]][page]++; /* if(preceeds[proc][prevpage[proc]][page] > 100){ //reset the frequencies for(pagetmp=0; pagetmp < MAXPROCPAGES; pagetmp++){ for(nextpg=0; nextpg < MAXPROCPAGES; nextpg++){ preceeds[proc][pagetmp][nextpg] = 0; } preceeds[proc][prevpage[proc]][page] = 5; } } */ // printf("page %d preceeds %d with frequency of: %d\n", prevpage[proc], page, preceeds[proc][prevpage[proc]][page]); } //update the series if(seriescount[proc] < serieslength){ series[proc][seriescount[proc]] = page; seriescount[proc]++; if(seriescount[proc] == serieslength){ seriescount[proc] = 0; seriesfull[proc] = 1; } } else{ //series if full, is it working or not... if(successrate[proc] < -1){ //nope - start a new one for(pagetmp = 0; pagetmp < MAXPROCPAGES; pagetmp++){ for(j = 0; j < serieslength; j++){ series[proc][j] = -1; } } seriescount[proc] = 0; seriesfull[proc] = 0; } //or don't change it } //how's the current method doing if(successrate[proc] >= 0){ //good enough //maybe prevpredictor == currentpredictor... if(currentpredictor[proc] == 1) pagepred = predict_hot(proc, hotpage); else if(currentpredictor[proc] == 2) pagepred = predict_repeats(proc, page, repeatcount, repeats); else if(currentpredictor[proc] == 3 && seriescount[proc] < serieslength) pagepred = predict_series(proc, series, seriescount); else pagepred = predict_preceeds(proc, page, preceeds); } if(successrate[proc] < 0){ //make prediction method decisions here if(bestoption <= 5){ int stop = 0; for(pagetmp = 0; (pagetmp < MAXPROCPAGES) && !stop; pagetmp++){ if(preceeds[proc][page][pagetmp] > 30){ currentpredictor[proc] = 4; //better chances here stop = 1; } } for(pagetmp = 0; (pagetmp < MAXPROCPAGES) && !stop; pagetmp++){ if(hotpage[proc][pagetmp] > 50){ currentpredictor[proc] = 1; //maybe there's a hot page to swap stop = 1; } } if(repeats[proc][page] > 1 && !stop){ currentpredictor[proc] = 2; stop = 1; } else if(seriesfull[proc] == 1 && !stop){ currentpredictor[proc] = 3; stop = 1; } bestoption = goodpredictor[proc][j]; } else{ for(j = 0; j < 4; j++){ if(goodpredictor[proc][j] > bestoption){ bestoption = goodpredictor[proc][j]; currentpredictor[proc] = j+1; } } if(bestoption > 20){ for(j = 0; j < 4; j++) goodpredictor[proc][j] = 0; goodpredictor[proc][j] = 2; bestoption = 0; } } // printf("current best predictor is %d with score %d\n", currentpredictor[proc], bestoption); currentpredictor[proc] = 4; if(currentpredictor[proc] == 1) pagepred = predict_hot(proc, hotpage); else if(currentpredictor[proc] == 2) pagepred = predict_repeats(proc, page, repeatcount, repeats); else if(currentpredictor[proc] == 3 && seriescount[proc] < serieslength) pagepred = predict_series(proc, series, seriescount); else pagepred = predict_preceeds(proc, page, preceeds); } //printf("current method: %d\n", currentpredictor[proc]); prevpredictor[proc] = currentpredictor[proc]; timestamps[proc][pagepred] = 0; if(!q[proc].pages[page]){ current = 1; swap_page(q, timestamps, proc, page, current, hotpage, prediction); } if(successrate[proc] >= 20){ int evictpage, outproc, least; nextpg = page; for(j = 0; j < 5; j++){ least = 0; for(pagetmp = 0; pagetmp < MAXPROCPAGES; pagetmp++){ if(!q[proc].pages[pagetmp]) //cant evict page thats not in continue; if(timestamps[proc][pagetmp] > least){ least = timestamps[proc][pagetmp]; evictpage = pagetmp; outproc = proc; // hotness = hotpage[proctmp][pagetmp]; // printf("current LRU timestamp = %d\n", least); } } //call pageout() if(q[outproc].pages[evictpage]){ //can only evict page thats in pageout(outproc, evictpage); } nextpg = predict_preceeds(proc, nextpg, preceeds); swap_page(q, timestamps, proc, nextpg, current, hotpage, prediction); } } lastproc = proc; lastpage = page; prevpage[proc] = page; prevpred[proc] = pagepred; } /* advance time for next pageit iteration */ tick++; //printf("miss count: %d, good predictions: %d\n", miss, goodpredict); }
void pageit(Pentry q[MAXPROCESSES]) { /* Static Vars */ static int tick = 0; static int outTestRun = 0; static int inTestRun = 0; static int iterations = 0; /* Local vars */ int testProc = 0; int testPage = 0; int pageinret = -1; int pageoutret = -1; /* All pages are swapped out on start */ if(q[testProc].pages[testPage]){ /* Page is swapped in */ if(!inTestRun){ fprintf(stdout, "%4d - %d:%d is swapped in\n", tick, testProc, testPage); fprintf(stdout, "%4d - q[%d].pages[%d] = %ld\n", tick, testProc, testPage, q[testProc].pages[testPage]); pageinret = pagein(testProc, testPage); fprintf(stdout, "%4d - pagein(%d, %d) returns %d\n", tick, testProc, testPage, pageinret); fprintf(stdout, "%4d - q[%d].pages[%d] = %ld\n", tick, testProc, testPage, q[testProc].pages[testPage]); pageoutret = pageout(testProc, testPage); fprintf(stdout, "%4d - pageout(%d, %d) returns %d\n", tick, testProc, testPage, pageoutret); if(pageoutret){ /* Wait for pageout to complete */ inTestRun = 1; outTestRun = 0; iterations++; } fprintf(stdout, "%4d - q[%d].pages[%d] = %ld\n", tick, testProc, testPage, q[testProc].pages[testPage]); } } else{ /* Page is swapped out */ if(!outTestRun){ fprintf(stdout, "%4d - %d:%d is swapped out\n", tick, testProc, testPage); fprintf(stdout, "%4d - q[%d].pages[%d] = %ld\n", tick, testProc, testPage, q[testProc].pages[testPage]); pageoutret = pageout(testProc, testPage); fprintf(stdout, "%4d - pageout(%d, %d) returns %d\n", tick, testProc, testPage, pageoutret); fprintf(stdout, "%4d - q[%d].pages[%d] = %ld\n", tick, testProc, testPage, q[testProc].pages[testPage]); pageinret = pagein(testProc, testPage); fprintf(stdout, "%4d - pagein(%d, %d) returns %d\n", tick, testProc, testPage, pageinret); if(pageinret){ /* Wait for pagein to complete */ outTestRun = 1; inTestRun = 0; iterations++; }else{ fprintf(stdout, "%4d - pageout in progress...\n", tick); } fprintf(stdout, "%4d - q[%d].pages[%d] = %ld\n", tick, testProc, testPage, q[testProc].pages[testPage]); } } /* Run test for I state change iterations */ if(iterations > MAXITERATIONS){ fprintf(stdout, "API Test Exiting\n"); exit(EXIT_SUCCESS); } tick++; }
static void pager(void *junk) { int i; Segment *s; Proc *p, *ep; if(waserror()) panic("pager: os error\n"); p = proctab(0); ep = &p[conf.nproc]; loop: up->psstate = "Idle"; sleep(&swapalloc.r, needpages, 0); print("uh oh. someone woke the pager\n"); while(needpages(junk)) { if(swapimage.c) { p++; if(p >= ep) p = proctab(0); if(p->state == Dead || p->noswap) continue; if(!canqlock(&p->seglock)) continue; /* process changing its segments */ for(i = 0; i < NSEG; i++) { if(!needpages(junk)){ qunlock(&p->seglock); goto loop; } if((s = p->seg[i])) { switch(s->type&SG_TYPE) { default: break; case SG_TEXT: pageout(p, s); break; case SG_DATA: case SG_BSS: case SG_STACK: case SG_SHARED: up->psstate = "Pageout"; pageout(p, s); if(ioptr != 0) { up->psstate = "I/O"; executeio(); } break; } } } qunlock(&p->seglock); } else { print("out of physical memory; no swap configured\n"); if(!cpuserver || freebroken() == 0) killbig("out of memory"); /* Emulate the old system if no swap channel */ tsleep(&up->sleep, return0, 0, 5000); wakeup(&palloc.r); } } goto loop; }