00001
00002
00003
00004
00005
00006
00007
00008
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
00049 if(TMM_PageSwappedIn(tmm,process,page)>=0) return(0);
00050
00051 if(TMM_PageSwappedOut(tmm,process,page)<0) return(-1);
00052 if(TMM_FrameFree(tmm,frame)<0) return(-1);
00053
00054
00055 TMM_AssignFrame(tmm,process,frame,page);
00056
00057
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
00071 return(0);
00072 }
00073
00074 int TMM_SwapOut(ToyMM *tmm, int process, int page)
00075 {
00076
00077
00078 if(TMM_PageFree(tmm,process,page)>=0) return(-1);
00079
00080
00081
00082 if(TMM_PageSwappedOut(tmm,process,page)>=0) return(0);
00083
00084
00085
00086 if(TMM_SwapWrite(tmm,process,page)<0) return(-1);
00087
00088
00089 TMM_FreeFrame(tmm,process,page);
00090
00091
00092 TMM_MarkPageSwappedOut(tmm,process,page);
00093
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
00129 else if(fread(data,elements,sizeof(ToyMem),tmm->swap)<=0) return(-1);
00130
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
00139 else if(fwrite(data,elements,sizeof(ToyMem),tmm->swap)<=0)return(-1);
00140
00141 else return(0);
00142 }
00143
00145 int TMM_SwapSeek(ToyMM *tmm, int process, int page)
00146 {
00147 int pos=TMM_CalculateFilePos(tmm,process,page);
00148
00149 if(pos<0) return(-1);
00150
00151 else if(fseek(tmm->swap,pos,SEEK_SET)<0) return(-1);
00152
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
00163 memset(&header,0,sizeof(ToySwapHeader));
00164 memset(blank,0,sizeof(blank));
00165
00166
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
00174 if(fseek(tmm->swap,0,SEEK_SET)<0) return(-1);
00175
00176
00177 if(fwrite(&header,1,sizeof(ToySwapHeader),tmm->swap)<=0) return(-1);
00178
00179 if(fwrite(blank,1,sizeof(blank),tmm->swap)<=0) return(-1);
00180
00181 return(0);
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);
00194 tmm->swap=NULL;
00195
00196
00197
00198 #ifdef SWAP_FILEDELETE
00199 remove(SWAP_FILENAME);
00200 #endif
00201 }
00202
00203
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
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;
00229
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
00242 if(TMM_PagingEnabled(tmm)<0) return(-1);
00243
00244
00245 memset(&mem,0,sizeof(ToyMem));
00246 mem.type=DATA_ERROR;
00247
00248
00249 if(tmm->swap!=NULL)
00250 {
00251 TMM_SwapDestroy(tmm);
00252 }
00253
00254
00255 fp=fopen(SWAP_FILENAME,"wb+");
00256 tmm->swap=fp;
00257
00258 if(fp==NULL)
00259 {
00260 return(-1);
00261 }
00262 else if(TMM_SwapWriteHeader(tmm)<0)
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
00273 {
00274 int n=-1,m=-1;
00275
00276
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);
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 }