/*A "Paging System" Implementation Using Files for Physical Memory and Processes In this assignment, you are required to implement a paging system that uses a binary file (bf_memory) to mimic physical memory. The file should be 512KB in size in addition to the space required to save all page tables and allocation information. Split the 512KB into 1024 sections (to mimic frames in physical memory) each of 512 Bytes. When a new file is started, all 1024 sections should belong to the free-section list. When a file (assuming the file has a process' binary image) needs to be loaded in bf_memory, allocate sections from the free-section list, and update the file's page table with the mapping information. Each file has a page table that specifies the mapping of pages to sections in bf_memory. Your program should be executed using the following command (assuming your executable is called pagesys): pagesys bf_memory_filename where bf_memory_filename is a new or previously-created filename that holds bf_memory, free-section information, and all page tables of files. In addition, provide an interactive shell that accepts the following commands: loadin process_image_file which loads a file called process_image_file into appropriate sections in filename, saves page table information, and updates free-section list accordingly. If number of free sections is less than the process_image_file pages, then disallow the load to take place. Delete the process_image_file from UNIX's filesystem after the operation. dumpout process_image_file which creates a file in UNIX's filesystem and dumps all the file's sections in it. Those sections will be claimed again and added to the free-section list. In addition, delete all page table and allocation information previously kept about that file. memdump provides a list of all sections in bf_memory along with page information for the page allocated in each section. pilist list each process_image_file in bf_memory along with its actual size, list of allocated sections, and the number of allocated sections. exit exits the paging system saving all information already available. When the program is started again, it should come back to the same state it was in before exiting. Please note that your implementation should maintain the integrity of the process_image_file after it is dumped out. The file should be a replica of the original file that was loaded in. */ /*Anan Tongprasith*/ /******************/ #include #include #include #include #include #include /**************** Data structure containing page tables ***********/ struct pagetables { char pname[20]; int ptr; long size; }; /******************************************************************/ /******This function read a line from a file and return it ********/ char *rdln(int fd); /******This function create a new bf_memory file *******/ int createnew(char *newname); int main(int argc, char *argv[]) { char ppp[512],cmnd[10]="1",param[20]="1",buf[30],name[20],sptr[5],temp[5]; int count=0,ptr[1024],pnum[1024]; int fdd,fd,i,j,ii,k; struct pagetables pgt[20]; struct stat mystat;long size; /* initialize process table */ for(i=0;i<20;i++) pgt[i].ptr=-1; /* initialize free page table */ for(i=0;i<1024;i++) { ptr[i]=-1;pnum[i]=-1; } if(argc==1) { printf("No input file.\n"); exit(0); } if((fd=open(argv[1],O_RDWR))<0) { fd=createnew(argv[1]);} /*Create a new bf_memory file*/ lseek(fd,524288,SEEK_SET); for(i=0;i<1024;i++) /*Reading in freepage table*/ { strcpy(buf,rdln(fd));sscanf(buf,"%s %s",name,sptr); ptr[i]=atoi(buf); if(ptr[i]>=0) pnum[i]=atoi(sptr); } i=0;strcpy(buf,rdln(fd));count=atoi(buf); while( count > 0 ) /*Reading in process table*/ { strcpy(buf,rdln(fd));sscanf(buf,"%s %s %s",name,sptr,temp); strcpy(pgt[i].pname,name); pgt[i].ptr=atoi(sptr); pgt[i].size=atoi(temp); j=pgt[i].ptr; while(j<1200) { pnum[j]=i; j=ptr[j]; } i+=1;count-=1; } while(TRUE) /*Reading your command*/ { printf("command>"); scanf("%s",cmnd); if(strcmp(cmnd,"exit")==0) /* exit command */ { close(fd); exit(0); } if(strcmp(cmnd,"memdump")==0) /* memdump command */ { for(i=0;i<1024;i++) { if(ptr[i]>=0) printf("page# %i, process#%i %s\n",i,pnum[i],pgt[pnum[i]].pname); else printf("page# %i, free\n",i); /*free page*/ if((i%20)==0) scanf("%c",buf); } } if(strcmp(cmnd,"pilist")==0) /* pilist command */ { for(i=0;i<20;i++) { if(pgt[i].ptr>=0) /*look through process table*/ { printf("process# %i %s %d bytes\n",i,pgt[i].pname,pgt[i].size); printf("allocated sections: "); count=pgt[i].ptr; do { printf("%i ",count); count=ptr[count]; } while (count>=0&&count<1200); printf("\n"); } } } if(strcmp(cmnd,"dumpout")==0) /* dumpout command */ { scanf("%s",param); /* what file? */ k=-1; for(i=0;i<20;i++) /*looking for it*/ { if(pgt[i].ptr>=0) { if(strcmp(pgt[i].pname,param)==0) { k=pgt[i].ptr;j=i; } } } if(k==-1) { printf("Process %s not found\n",param);} else /* found it */ { unlink(param); fdd=creat(param,0777); while(ptr[k]<1200) /* writing it out */ { lseek(fd,k*512,SEEK_SET); read(fd,ppp,512); write(fdd,ppp,512); i=k;k=ptr[k]; ptr[i]=-1; } ptr[k]=-1; lseek(fd,k*512,SEEK_SET); read(fd,ppp,512); k=pgt[j].size%512;if(k==0) k=512; write(fdd,ppp,k); close(fdd); pgt[j].ptr=-1; /*delete it from bf_memory*/ k=0; for(i=0;i<20;i++) { if(pgt[i].ptr>=0) k+=1; } lseek(fd,524288,SEEK_SET); for(i=0;i<1024;i++) { sprintf(buf,"%d %d\n",ptr[i],pnum[i]); write(fd,buf,strlen(buf)); } sprintf(buf,"%i\n",k); write(fd,buf,strlen(buf)); for(i=0;i<20;i++) { if(pgt[i].ptr>=0) { sprintf(buf,"%s %i %i\n",pgt[i].pname,pgt[i].ptr,pgt[i].size); write(fd,buf,strlen(buf)); } } } } if(strcmp(cmnd,"loadin")==0) /* loadin command */ { scanf("%s",param); /* what file? */ if(stat(param,&mystat)==0) { size=0; for(i=0;i<1024;i++) /* enough page? */ { if(ptr[i]<0) size+=1; } if(size*512=0) k++; i=0;size=(mystat.st_size+511)/512; while(ptr[i]>=0) i++; /* first page */ strcpy(pgt[k].pname,param);/*name*/ pgt[k].size=mystat.st_size;/*size*/ pgt[k].ptr=i; /* first page */ size-=1;ptr[i]=1200;pnum[i]=k; while(size>0) /* other pages */ { j=i; while(ptr[j]>=0) j++; ptr[i]=j;pnum[i]=k; ptr[j]=1200; size-=1;i=j; } pnum[i]=k; /* reading the file */ fdd=open(param,O_RDONLY); i=pgt[k].ptr; /* loading into bf_memory */ while(ptr[i]<1200) { read(fdd,ppp,512); lseek(fd,i*512,SEEK_SET); write(fd,ppp,512); i=ptr[i]; } lseek(fd,i*512,SEEK_SET); count=read(fdd,ppp,512); write(fd,ppp,count); close(fdd);unlink(param); for(i=0;i<512-count;i++) write(fd,"0",1); lseek(fd,524288,SEEK_SET); /* updating the freepage table */ for(i=0;i<1024;i++) { sprintf(buf,"%d %d\n",ptr[i],pnum[i]); write(fd,buf,strlen(buf)); } k=0; /* updating the process table */ for(i=0;i<20;i++) { if(pgt[i].ptr>=0) k+=1; } sprintf(buf,"%i\n",k); write(fd,buf,strlen(buf)); for(i=0;i<20;i++) { if(pgt[i].ptr>=0) { sprintf(buf,"%s %i %i\n",pgt[i].pname,pgt[i].ptr,pgt[i].size); write(fd,buf,strlen(buf)); } } } } else { printf("Cannot find %s\n",param); } } } close(fd); return 0; } /************ Reading a line *************/ char *rdln(int fd) { char buf1[30]="",*t="0"; if(read(fd,t,1)<0) return "-1"; while(*t!='\n') { strcat(buf1,t); read(fd,t,1); } strcat(buf1,"\0"); return buf1; } /************ Creating a new bf_memory file *************/ int createnew(char *newname) { int fd,i,j;char *a="0"; printf("Creating a new file...please wait\n"); fd=creat(newname,0666); for(i=0;i<512;i++) { for(j=0;j<1024;j++) write(fd,a,1); } sprintf(a,"-1\n"); for(i=0;i<1024;i++) write(fd,a,3); return fd; write(fd,"0\n",1); }