Skip to content

Instantly share code, notes, and snippets.

@bridgesign
Last active April 16, 2024 14:52
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bridgesign/e932115f1d58c7e763e6e443500c6561 to your computer and use it in GitHub Desktop.
Save bridgesign/e932115f1d58c7e763e6e443500c6561 to your computer and use it in GitHub Desktop.
Creating a system call in xv6 for keeping count of read syscalls on per prcoess basis

Constructing a System call that gives the count of how many times System call Read was called.

We will be using xv6 OS for this exercise. In this exercise, we will construct a system call that can give read counts on per process basis and then modify it to obtain a system call that will give read counts of all processes since the start of kernel.

Adding the counter

To add a system call that can get the number of times the system call 'read' was used in a specific program, we require to make a variable that stores this count for each process.

So, we first start by looking at the files proc.c and proc.h
These files are associated with creating a process. We need to store the count on a per process basis so we will have to add something to the structure that is created for a process.
For that, open proc.h. In this file, the structure for a process is defined. Find struct proc and then add an integer to keep account for the read calls. eg. int readid;

The file proc.c contains the code for initiallizing the process. Here the function allocproc allocates processes and it can be seen that it jumps to label found where it is assigned the pid. Add a line here to initialize the readcount to zero in this case p->readid = 0;

We have created and initialized the counter in the process so work with these two files is done.

Constructing the System Call

We now need to construct the system call. Here we only bother with the construction of the system call. Linking it so that we can call it will be done in next section. We will be looking at the files sysproc.c and syscall.c
The functions in sysproc.c can access the process structure of a given process by calling myproc(). Using this, we define the function sys_getreadcount which takes no arguments and returns an int.

int
sys_getreadcount(void)
{
  return myproc()->readid;
}

Now we need to add the code to increase the counter whenever the system call 'read' is called the process.
In the file syscall.c, we see that ```syscall(void)``` is called whenever a system call is done. We just need to add the condition to increament the counter whenever the system call is read. Just above, we observe that ```static int (*syscalls[])(void)``` is defined which maps each to system call to something (These are integers as we will see further). We observe that the call ```syscall(void)``` is defining ```int num;``` according to which we it is calling the system call. We know the entry for ```sys_read``` and hence we only need to increament the counter if ```num==SYS_read``` . So now your ```syscall``` looks like this
void
syscall(void)
{
  int num;
  struct proc *curproc = myproc();

  num = curproc->tf->eax;
  if (num==SYS_read){
    curproc->readid = curproc->readid + 1; //my change
  }
  if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
    curproc->tf->eax = syscalls[num]();
  } else {
    cprintf("%d %s: unknown sys call %d\n",
            curproc->pid, curproc->name, num);
    curproc->tf->eax = -1;
  }
}

Linking the System Call

Now we need to make the changes so that we can call the system call getreadcount(). We will be looking at the files syscall.c, syscall.h, user.h and usys.S
We saw that every system call is mapped to something in syscall.c. Open syscall.h and it can be observed that these are just integers. Now add an entry in syscall.h #define SYS_getreadcount 22
Go back to syscall.c and add the entry [SYS_getreadcount] sys_getreadcount, //my change to define that it maps to sys_getreadcount. Go up a bit and you will observe that the external functions are defined here. As getreadcount is also an external function add a line to tell that to the compiler extern int sys_getreadcount(void); //my chnage.
Our work in these two files is done.

Now open the file user.h. The system calls are defined here for the user to call. Add the line int getreadcount(void); in the file (Anywhere is okay but it will be better to maintain the uniformity and put it where they have mentioned the system calls).
Open usys.S. We can see that it is linked with syscall.h. This is just an assembly file that tells to move the integer associated with each system call to the register 'eax'. Just add the line SYSCALL(getreadcount)
That's it!

Its testing time!

Open the cat.c file and try calling the new system call and print the number of reads that were done at the beginning and at the end.

Modifying the System Call

We need to make a global count. So, in syscall.c, in the beginning add the line int readcount = 0;. This will serve as our counter. Now, we need to do few modifications in the syscall(void). We need to increament the counter when system call is read and update readid for process when getreadcount is called. Your code will look like this

void
syscall(void)
{
  int num;
  struct proc *curproc = myproc();

  num = curproc->tf->eax;
  if (num==SYS_read){
    readcount++; //my change
  }
  if (num==SYS_getreadcount){
    curproc->readid = readcount; //my change
  }
  if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
    curproc->tf->eax = syscalls[num]();
  } else {
    cprintf("%d %s: unknown sys call %d\n",
            curproc->pid, curproc->name, num);
    curproc->tf->eax = -1;
  }
}
@bridgesign
Copy link
Author

bridgesign commented Feb 4, 2021 via email

@bridgesign
Copy link
Author

bridgesign commented Mar 27, 2021 via email

@Changyh001
Copy link

🔥

@NickCoooke
Copy link

love this. thank you

@tingcai98
Copy link

wonderful notes!

@catasotopavez
Copy link

thank you

@SebastianGarcia4
Copy link

love u

@HerlockSholmesm
Copy link

Does it count read syscalls from the start or it counts up to that previous systemcall?

Because we are changing the read_time for one process, namely the current process, not all of them at once. Am I true?

@bsce21017
Copy link

Very Helpful. Thank you 🎓

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment