Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields  

ToyVirtualMem.c

00001 /***************************************************************************
00002                           ToyVirtualMem.c  -  Glue logic to simplify the
00003     use of virtual memory in the Toy Memory Manager.
00004                              -------------------
00005     begin                : Sat Feb 22 2003
00006     copyright            : (C) 2003 by Tyler Montbriand
00007     email                : monttyle@heavyspace.ca
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   /* Avoid infinite loop */
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   /* Didn't find any frames, return error */        
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   /* Paging not enabled?  It **is** a real address. */
00240   if(TMM_PagingEnabled(tmm)<0)  return(vaddr);
00241 
00242   offset=vaddr%tmm->pageSize;    
00243   page=vaddr/tmm->pageSize;
00244 
00245   /* If the current page is swapped out, we gotta swap it back in */
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   /* Mark every mem element in the frame as empty */
00268   for(n=0; n<tmm->pageSize; n++)
00269   {
00270     /* Mark type as empty */
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   /* Set all memory in frame to empty */
00281   TMM_EmptyFrame(tmm,frame);
00282 
00283   /* Update the Inverted Page Table */
00284   tmm->invPageTable[frame].ID=process;
00285   tmm->invPageTable[frame].page=page;
00286   tmm->invPageTable[frame].status=1;
00287 
00288   /* Update the Page Table */
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 

Generated on Fri Apr 4 14:29:07 2003 for ToyMem by doxygen1.3-rc3