Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields  

ToySwap.c

00001 /***************************************************************************
00002              ToySwap.c  -  Implements the interface to the swap file.
00003     Provides the functions TMM_Swap, TMM_SwapIn, TMM_SwapOut,
00004     TMM_SwapCreate, TMM_SwapDestroy.
00005                              -------------------
00006     begin                : Mon Mar 24 2003
00007     copyright            : (C) 2003 by Tyler Montbriand
00008     email                : monttyle@heavyspace.ca
00009  ***************************************************************************/
00010 
00011 #include <string.h>
00012 #include <stdio.h>
00013 
00014 #include "ToySegment.h"
00015 #include "ToySegmentList.h"
00016 #include "ToyProcess.h"
00017 #include "ToyMemType.h"
00018 #include "ToyMem.h"
00019 #include "ToyMem_Internal.h"
00020 #include "ToyLoad.h"
00021 #include "ToyVirtualMem.h"
00022 #include "ToySwap.h"
00023 
00025 #define SWAP_FILEDELETE
00026 
00032 ToyMem *TMM_GetPageMem(ToyMM *tmm, int process, int page);
00033 int TMM_SwapRawWrite(ToyMM *tmm, ToyMem data[],int elements);
00034 int TMM_SwapRawRead(ToyMM *tmm, ToyMem data[], int elements);
00035 int TMM_SwapSeek(ToyMM *tmm, int process, int page);
00036 int TMM_SwapWriteHeader(ToyMM *tmm);
00037 void TMM_SwapNotify(ToyMM *tmm, int process, int page, int in);
00038 int TMM_CalculateFilePos(ToyMM *tmm, int process, int page);
00040 int TMM_SwapWrite(ToyMM *tmm, int process, int page);
00042 int TMM_SwapRawRead(ToyMM *tmm, ToyMem data[], int elements);
00044 int TMM_SwapRead(ToyMM *tmm, int process, int page);
00045 
00046 int TMM_SwapIn(ToyMM *tmm, int process, int page, int frame)
00047 {
00048   /* Not an error, but don't need to do anything */
00049   if(TMM_PageSwappedIn(tmm,process,page)>=0)  return(0);
00050   /* Sanity checking */
00051   if(TMM_PageSwappedOut(tmm,process,page)<0)  return(-1);
00052   if(TMM_FrameFree(tmm,frame)<0)              return(-1);
00053   
00054   /* OK, now we're cookin'.  Assign specified free page to process */
00055   TMM_AssignFrame(tmm,process,frame,page);
00056 
00057   /* Read in swap data from file */
00058   if(TMM_SwapRead(tmm,process,page)<0)
00059   {
00060     TMM_FreeFrame(tmm,process,page);
00061     return(-1);
00062   }
00063 
00064 
00065   if(tmm->watchPaging>0)
00066   {
00067     TMM_SwapNotify(tmm,process,page,1);
00068   }
00069 
00070   /* OK.  We're done!*/
00071   return(0);  /* Return success */
00072 }
00073 
00074 int TMM_SwapOut(ToyMM *tmm, int process, int page)
00075 {
00076   
00077   /* Check if page exists */
00078   if(TMM_PageFree(tmm,process,page)>=0)        return(-1);
00079   
00080   
00081   /* Check if page is already paged out */  
00082   if(TMM_PageSwappedOut(tmm,process,page)>=0)  return(0);
00083 
00084   
00085   /* Write to file */
00086   if(TMM_SwapWrite(tmm,process,page)<0)        return(-1);
00087 
00088   /* Disassociate from process */      
00089   TMM_FreeFrame(tmm,process,page);
00090 
00091   /* Mark page as paged out */
00092   TMM_MarkPageSwappedOut(tmm,process,page);
00093   /* Success! */
00094 
00095 
00096   if(tmm->watchPaging>0)
00097   {
00098     TMM_SwapNotify(tmm,process,page,0);
00099   }
00100 
00101   return(0);
00102 }
00103 
00104 int TMM_SwapWrite(ToyMM *tmm, int process, int page)
00105 {
00106   ToyMem *memptr=TMM_GetPageMem(tmm,process,page);
00107   if(memptr==NULL)                                      return(-1);  
00108   else if(TMM_SwapSeek(tmm,process,page)<0)             return(-1);
00109   else if(TMM_SwapRawWrite(tmm,memptr,tmm->pageSize)<0) return(-1);
00110   else                                                  return(0); 
00111 }
00112 
00113 
00114 
00115 int TMM_SwapRead(ToyMM *tmm, int process, int page)
00116 {
00117   ToyMem *memptr=TMM_GetPageMem(tmm,process,page);
00118   
00119   if(memptr==NULL)                                      return(-1);
00120   else if(TMM_SwapSeek(tmm,process,page)<0)             return(-1);
00121   else if(TMM_SwapRawRead(tmm,memptr,tmm->pageSize)<0)  return(-1);
00122   else                                                  return(0);
00123 }
00124 
00125 int TMM_SwapRawRead(ToyMM *tmm, ToyMem data[], int elements)
00126 {
00127   if((data==NULL)||(elements<0))                            return(-1);
00128   /* Attempt to read memory elements from swapfile */
00129   else if(fread(data,elements,sizeof(ToyMem),tmm->swap)<=0) return(-1);
00130   /* Return success */
00131   else                                                      return(0);
00132 }
00133 
00135 int TMM_SwapRawWrite(ToyMM *tmm, ToyMem data[],int elements)
00136 {
00137   if((data==NULL)||(elements<0))                            return(-1);
00138   /* Attempt to write memory elements to swapfile */
00139   else if(fwrite(data,elements,sizeof(ToyMem),tmm->swap)<=0)return(-1);
00140   /* Return success */
00141   else                                                      return(0);  
00142 }
00143 
00145 int TMM_SwapSeek(ToyMM *tmm, int process, int page)
00146 { /* Calculate position in file */
00147   int pos=TMM_CalculateFilePos(tmm,process,page);
00148   /* Invalid position, return error */
00149   if(pos<0)                                 return(-1);
00150   /* Couldn't seek, return error */
00151   else if(fseek(tmm->swap,pos,SEEK_SET)<0)  return(-1);
00152   /* Seek succeeded - return success */
00153   else                                      return(0);
00154 }
00155 
00157 int TMM_SwapWriteHeader(ToyMM *tmm)
00158 {
00159   ToySwapHeader header;  
00160   char          blank[SWAP_OFFSET-sizeof(ToySwapHeader)];
00161   
00162   /* Set all values in structure to NULL */
00163   memset(&header,0,sizeof(ToySwapHeader));
00164   memset(blank,0,sizeof(blank));
00165   
00166   /* Copy appropriate values into structure */
00167   strcpy(header.FileStr,SWAP_FILENAME);
00168   header.Version=0x004;
00169   header.MemSize=tmm->memSize;
00170   header.PageSize=tmm->pageSize;
00171   header.CurrentPage=tmm->page;
00172 
00173   /* Attempt to seek to start of file */
00174   if(fseek(tmm->swap,0,SEEK_SET)<0)  return(-1);
00175 
00176   /* Write the header itself */
00177   if(fwrite(&header,1,sizeof(ToySwapHeader),tmm->swap)<=0)  return(-1);
00178   /* Write the blank bytes up 'till the Swap data itself */
00179   if(fwrite(blank,1,sizeof(blank),tmm->swap)<=0)            return(-1);  
00180 
00181   return(0); /* Success */
00182 }
00183 
00185 int TMM_SwapDestroy(ToyMM *tmm)
00186 {
00187   if(tmm==NULL)
00188   {
00189     return(-1);
00190   }
00191   else if(tmm->swap!=NULL)
00192   {    
00193     fclose(tmm->swap);  /* Close swap file */        
00194     tmm->swap=NULL;     /* Mark tmm as having no swap */
00195     
00196 /* When SWAP_FILEDELETE is defined, we don't
00197    just close the file, we delete it.        */
00198 #ifdef SWAP_FILEDELETE
00199     remove(SWAP_FILENAME);
00200 #endif    
00201   }
00202   
00203   /* Return success */  
00204   return(0);  
00205 }
00206 
00207 void TMM_SwapNotify(ToyMM *tmm, int process, int page, int in)
00208 {
00209   if(TMM_PagingEnabled(tmm)<0) return;
00210   else if(tmm->watchPaging)
00211   {    
00212     if(in)  printf(SWAP_IN_PREFIX SWAP_CMD_STR  "in\n",page,process);
00213     else    printf(SWAP_OUT_PREFIX SWAP_CMD_STR"out\n",page,process);
00214   }
00215 }
00216 
00218 int TMM_CalculateFilePos(ToyMM *tmm, int process, int page)
00219 {
00220   int pos=-1;
00221   /* Sanity checking */
00222   if(TMM_PagingEnabled(tmm)<0)        return(-1);
00223   if(process<0)                       return(-1);
00224   else if(process>=MAX_PROCESSES)     return(-1);
00225   else if(page<0)                     return(-1);
00226   else if(page>=TMM_GetNumPages(tmm)) return(-1);
00227 
00228   pos=SWAP_OFFSET;  /* Swap data starts at SWAP_OFFSET */
00229   /* Calculate position in file */
00230   pos+=(process*tmm->memSize)*sizeof(ToyMem);
00231   pos+=(page*tmm->pageSize)*sizeof(ToyMem);
00232   return(pos);
00233 }
00234 
00235 int TMM_SwapCreate(ToyMM *tmm)
00236 {
00237   FILE *fp=NULL;
00238   ToyMem mem;
00239 
00240   if(tmm==NULL)                 return(-1);
00241   /* We don't use swap files in legacy mode */
00242   if(TMM_PagingEnabled(tmm)<0)  return(-1);
00243 
00244   /* Initialize data variable */
00245   memset(&mem,0,sizeof(ToyMem));
00246   mem.type=DATA_ERROR;
00247 
00248   /* If a swap file already exists, get rid of it */
00249   if(tmm->swap!=NULL)
00250   {
00251     TMM_SwapDestroy(tmm);
00252   }
00253 
00254   /* Open the file for writing, reading, and seeking */
00255   fp=fopen(SWAP_FILENAME,"wb+");
00256   tmm->swap=fp;
00257 
00258   if(fp==NULL)  /* Return error if we can't create the file */
00259   {
00260     return(-1);
00261   }
00262   else if(TMM_SwapWriteHeader(tmm)<0) /* Attempt to write header */
00263   {
00264     TMM_SwapDestroy(tmm);
00265     return(-1);
00266   }
00267   else if(TMM_SwapSeek(tmm,0,0)<0)
00268   {
00269     TMM_SwapDestroy(tmm);
00270     return(-1);
00271   }
00272   else  /* Write empty swap data */
00273   {
00274     int n=-1,m=-1;
00275 
00276     /* Write memsize elements for every process */
00277     for(n=0; n<tmm->memSize; n++)
00278     for(m=0; m<MAX_PROCESSES; m++)
00279     if(TMM_SwapRawWrite(tmm,&mem,1)<0)
00280     {
00281       TMM_SwapDestroy(tmm);
00282       return(-1);
00283     }
00284 
00285     return(0);    /* Success */
00286   }
00287 }
00288 
00289 ToyMem *TMM_GetPageMem(ToyMM *tmm, int process, int page)
00290 {
00291   ToyMem *mem=NULL;
00292   PageTable *pt=TMM_GetPage(tmm,process,page);
00293 
00294   if(pt==NULL)            return(NULL);
00295   else if(pt->paged==1)   return(NULL);
00296   else if(pt->frame<0)    return(NULL);
00297   else if(tmm->mem==NULL) return(NULL);
00298   mem=tmm->mem;
00299   mem+=(pt->frame*tmm->pageSize);
00300 
00301   return(mem);
00302 }

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