/*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);
}
               (
geocities.com/vienna/7079)                   (
geocities.com/vienna)