00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include "ToySegment.h"
00012 #include "ToySegmentList.h"
00013 #include "ToyProcess.h"
00014 #include "ToyMemType.h"
00015 #include "ToyMem.h"
00016 #include "ToyMem_Internal.h"
00017 #include "ToyLoad.h"
00018 #include "ToyMemPage.h"
00019 #include "ToyVirtualMem.h"
00020 #include "ToySwap.h"
00021
00022 int TMM_PagingEnabled(ToyMM *tmm)
00023 {
00024 if((tmm->invPageTable==NULL)||(tmm->pageSize==0))
00025 {
00026 return(-1);
00027 }
00028 else
00029 {
00030 return(0);
00031 }
00032 }
00033
00034 void TMM_ClearFrameStatus(ToyMM *tmm, int frame)
00035 {
00036 InvPageTable *ipt=TMM_GetFrame(tmm,frame);
00037 if(ipt==NULL) return;
00038
00039 ipt->status=0;
00040 }
00041
00042 void TMM_SetFrameStatus(ToyMM *tmm, int frame)
00043 {
00044 InvPageTable *ipt=TMM_GetFrame(tmm,frame);
00045 if(ipt==NULL) return;
00046
00047 ipt->status=1;
00048 }
00049
00050
00051 void TMM_IncrementLinearScan(ToyMM *tmm)
00052 {
00053 if(TMM_PagingEnabled(tmm)<0) return;
00054
00055 tmm->page++;
00056 if(tmm->page>=TMM_GetNumPages(tmm))
00057 {
00058 tmm->page=0;
00059 }
00060 else if(tmm->page<0)
00061 {
00062 tmm->page=0;
00063 }
00064 }
00065
00066 void TMM_MarkPageSwappedOut(ToyMM *tmm,int process,int page)
00067 {
00068 tmm->processList[process]->pagetable[page].paged=1;
00069 tmm->processList[process]->pagetable[page].frame=-1;
00070 }
00071
00072 int TMM_PageSwappedIn(ToyMM *tmm, int process, int page)
00073 {
00074 PageTable *pt=TMM_GetPage(tmm,process,page);
00075 if(pt==NULL) return(-1);
00076 else if(pt->paged==1) return(-1);
00077 else if(pt->frame<0) return(-1);
00078 else return(0);
00079 }
00080
00081 int TMM_PageSwappedOut(ToyMM *tmm, int process, int page)
00082 {
00083 PageTable *pt=TMM_GetPage(tmm,process,page);
00084 if(pt==NULL) return(-1);
00085 else if(pt->paged==0) return(-1);
00086 else if(pt->frame>=0) return(-1);
00087 else return(0);
00088 }
00089
00090 int TMM_CountFreePages(ToyMM *tmm, int process)
00091 {
00092 int n=-1;
00093 int freepages=0;
00094 Process *proc=TMM_GetProcess(tmm,process);
00095 if(proc==NULL) return(-1);
00096 else if(TMM_PagingEnabled(tmm)<0) return(-1);
00097
00098 for(n=0; n<TMM_GetNumPages(tmm); n++)
00099 {
00100 if(TMM_PageFree(tmm,process,n)>=0) freepages++;
00101 }
00102
00103 return(freepages);
00104 }
00105
00106 InvPageTable *TMM_GetFrame(ToyMM *tmm, int frame)
00107 {
00108 if(tmm==NULL) return(NULL);
00109 else if(TMM_PagingEnabled(tmm)<0) return(NULL);
00110 else if(frame<0) return(NULL);
00111 else if(frame>=TMM_GetNumPages(tmm)) return(NULL);
00112 else return(tmm->invPageTable+frame);
00113 }
00114
00115 int TMM_FrameFree(ToyMM *tmm, int frame)
00116 {
00117 if(TMM_PagingEnabled(tmm)<0) return(-1);
00118 else if (frame<0) return(-1);
00119 else if(frame>TMM_GetNumPages(tmm)) return(-1);
00120 else if(tmm->invPageTable[frame].ID>=0) return(-1);
00121 else return(0);
00122 }
00123
00124
00125 PageTable *TMM_GetPage(ToyMM *tmm, int process, int page)
00126 {
00127 Process *proc=TMM_GetProcess(tmm,process);
00128 if(proc==NULL) return(NULL);
00129 else if(TMM_PagingEnabled(tmm)<0) return(NULL);
00130 else if(proc==NULL) return(NULL);
00131 else if(page<0) return(NULL);
00132 else if(page>=TMM_GetNumPages(tmm)) return(NULL);
00133 else return(proc->pagetable+page);
00134 }
00135
00136 int TMM_PageFree(ToyMM *tmm, int process, int page)
00137 {
00138 PageTable *ptable=TMM_GetPage(tmm,process,page);
00139 if(ptable==NULL) return(-1);
00140 else if(ptable->frame>=0) return(-1);
00141 else if(ptable->paged>0) return(-1);
00142 else return(0);
00143 }
00144
00145 int TMM_GetNumPages(ToyMM *tmm)
00146 {
00147 if(TMM_PagingEnabled(tmm)<0) return(-1);
00148 else return(tmm->memSize/tmm->pageSize);
00149 }
00150
00151 int TMM_FrameRecentlyUsed(ToyMM *tmm, int frame)
00152 {
00153 if(TMM_FrameFree(tmm,frame)>=0) return(-1);
00154 else if(tmm->invPageTable[frame].status==0) return(-1);
00155 else return(0);
00156 }
00157
00158
00159 int TMM_FindFreeFrame(ToyMM *tmm)
00160 {
00161 int iterations=-1;
00162 int maxpages=TMM_GetNumPages(tmm);
00163 if(maxpages<0) return(-1);
00164
00165
00166 while(iterations<maxpages)
00167 {
00168 int frame=tmm->page;
00169 iterations++;
00170
00171 if(TMM_FrameFree(tmm,tmm->page)>=0)
00172 {
00173 TMM_IncrementLinearScan(tmm);
00174 return(frame);
00175 }
00176 else if(tmm->invPageTable[tmm->page].status==0)
00177 {
00178 int process=tmm->invPageTable[tmm->page].ID;
00179 int page=tmm->invPageTable[tmm->page].page;
00180
00181 if(TMM_SwapOut(tmm,process,page)<0)
00182 {
00183 printf("Swapping error in linear scan!\n");
00184 printf("Email me at monttyle@heavyspace.ca and tell me how you caused this\n");
00185 abort();
00186 }
00187
00188 TMM_IncrementLinearScan(tmm);
00189 return(frame);
00190 }
00191 else
00192 {
00193 TMM_ClearFrameStatus(tmm,tmm->page);
00194 TMM_IncrementLinearScan(tmm);
00195 }
00196 }
00197
00198 return(-1);
00199 }
00200
00202 int TMM_GetNumFrames(ToyMM *tmm, int length)
00203 {
00204 if(tmm==NULL) return(-1);
00205 else if(TMM_PagingEnabled(tmm)<0) return(-1);
00206 else if(length<0) return(-1);
00207 else if(length<tmm->pageSize) return(1);
00208 else if((length%tmm->pageSize)!=0) return((length/tmm->pageSize)+1);
00209 else return(length/tmm->pageSize);
00210 }
00211
00213 int TMM_GetFramedSize(ToyMM *tmm, int size)
00214 {
00215 int frames=TMM_GetNumFrames(tmm,size);
00216
00217 if(frames<0) return(-1);
00218 else return(frames*tmm->pageSize);
00219 }
00220
00222 int TMM_GetFrameNum(ToyMM *tmm, int process, int page)
00223 {
00224 Process *proc=TMM_GetProcess(tmm,process);
00225
00226 if(proc==NULL) return(-1);
00227 else if(page>=(tmm->memSize/tmm->pageSize)) return(-1);
00228 else return(proc->pagetable[page].frame);
00229 }
00230
00232 int TMM_GetRealAddress(ToyMM *tmm, int process, int vaddr)
00233 {
00234 int page=-1;
00235 int offset=-1;
00236 int frame=-1;
00237 int raddr=-1;
00238
00239
00240 if(TMM_PagingEnabled(tmm)<0) return(vaddr);
00241
00242 offset=vaddr%tmm->pageSize;
00243 page=vaddr/tmm->pageSize;
00244
00245
00246 if(TMM_PageSwappedOut(tmm,process,page)>=0)
00247 {
00248 frame=TMM_FindFreeFrame(tmm);
00249 if(frame<0) return(-1);
00250 if(TMM_SwapIn(tmm,process,page,frame)<0) return(-1);
00251 }
00252
00253 frame=TMM_GetFrameNum(tmm,process,page);
00254
00255 if(frame<0) return(-1);
00256 TMM_SetFrameStatus(tmm,frame);
00257
00258 raddr=(frame*tmm->pageSize)+offset;
00259 return(raddr);
00260 }
00261
00262 void TMM_EmptyFrame(ToyMM *tmm, int frame)
00263 {
00264 int n=-1;
00265 int addr=frame*tmm->pageSize;
00266
00267
00268 for(n=0; n<tmm->pageSize; n++)
00269 {
00270
00271 tmm->mem[addr+n].type=DATA_ERROR;
00272 }
00273 }
00274
00275 void TMM_AssignFrame(ToyMM *tmm, int process, int frame, int page)
00276 {
00277 Process *proc=TMM_GetProcess(tmm,process);
00278 if(proc==NULL) return;
00279
00280
00281 TMM_EmptyFrame(tmm,frame);
00282
00283
00284 tmm->invPageTable[frame].ID=process;
00285 tmm->invPageTable[frame].page=page;
00286 tmm->invPageTable[frame].status=1;
00287
00288
00289 proc->pagetable[page].frame=frame;
00290 proc->pagetable[page].paged=0;
00291 }
00292
00293 void TMM_FreeFrame(ToyMM *tmm, int process, int page)
00294 {
00295 Process *proc=TMM_GetProcess(tmm,process);
00296 if(proc==NULL) return;
00297
00298 if(proc->pagetable[page].frame!=-1)
00299 {
00300 TMM_EmptyFrame(tmm,proc->pagetable[page].frame);
00301 tmm->invPageTable[proc->pagetable[page].frame].ID=-1;
00302 proc->pagetable[page].frame=-1;
00303 proc->pagetable[page].paged=0;
00304 }
00305 }
00306