Assignments 2- 2021

Phase 2

All teams, please study: 

Team 1 - process hierachy

Study:
-V52: https://www.youtube.com/watch?v=tSnT9SYAb9A



Create the system call pid_father() which returns the pid of the father (see task_struct). 
Make init creates one child which creates one grandson. Both init and grandson continually prints "init" and father's pid, however, the child process, exits. What happens to the grandson parent?
Study the linux source code and show how the kernel changes the grandson's father.


Team 2 - signal

Study the following code:

#include<stdio.h>
#include<signal.h>
void bypass_sigint(int sig_no)
{
  printf("divide by zero\n");
}
int main()
{
  int a,b,c;
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = &bypass_sigint;
    sigaction(SIGFPE, &sa,NULL);
    while (1) {
      sleep(1);
        printf("do nothing \n ");
    }
    return 0;
}

Make init fork and exec this code. It creates a handler for zero division (bypass_signint).
Study the Linux kernel and answer:
- how the kernel generates this signal - zero division - to the process? Take some screenshots of the gdb and explains what is happening, from an instruction such as "x/y" to the handler call.
- make init signals the child process with a zero division from time to time. Notice how the child process behaves.

Team 3 - semaphore using semop

Study:
-V78:





Create the system call show_queue(semaphore) that shows the queue of a given semaphore created by semop. Do:

  • Read http://www.cis.upenn.edu/~lee/07cis505/Lec/SemaphoreOperations.pdf . Learn how to use semaphore operations.
  • Make the init create a semaphore initialized by one. Create another 10 processes. Make each one, do something like: while(1) {  print 1; print 2; print 3; print 4; print 5; down(S); print 6; print 7; print 8; print 9; up(S);} ; so it must be common to have 9 processes in the semaphore queue. Study the strings that are printed and explain them.
  • Using gdb, navigate inside the kernel and study how a process is queued in a semaphore. Understand how a semaphore queue is taken by its identification (sem_id).
  • Study how work the data structures dealing with semaphores, mainly the queue. Insert printk's whenever a process is inserted in a semaphore queue printing the semaphore id and the pid.
Queues are made of linked lists inside the kernel.
The URL http://isis.poly.edu/kulesh/stuff/src/klist/ shows how the kernel deals with lists.
Create an init process that tests your system call show_queue(semaphore).

Team 4 - process states

Study:

-V53: https://www.youtube.com/watch?v=uZgfu4fGtN0



See figure 3-3 from the book: "Linux kernel Development"; Robert Love which shows process states (See task_struct in Linux source code).
Make the system call: show_state(pid) which shows the state of the pid process.  
We are going to monitor the state of a child process using this new system call. In order to do that:
- init (father) must create (fork and execve) a child process.
- The child will continually reads the keyboard, sleep for 1 second , and quits (exit) if pressed key is "q".
- The father will continually print its child state.
Compare the monitored states with figure 3-3.
Use some loop to make the child process running in order to see it in the running state.
Answer:
- Is there a moment when a process pid disappears and it is impossible to show_state(pid)?    

Team 5 - system call forkexecve

Create the system call forkexec which forks and does execve as:

  int forkexecve(const char *filename, char *const argv[], char *const envp[]);

forkexecve must fork and then, execve. Remember that your system call code inside the kernel (ex: sys_forkexec) can not call system calls such as fork() and execve().
Test it, making init forkexecve another process.

Team 6. Peterson solution

Study:
-V73: https://www.youtube.com/watch?v=tMtMr-d3QBs solucao Peterson

-V74: https://www.youtube.com/watch?v=XBJf27Sny4M solucao Peterson casos





Create 2 system calls:
write_number(number);
stores number in a memory position inside the kernel.

number = read_number(); 
returns the stored number.

Creates 2 processes that continually read_number and write_number as:

while (1) {
   x = read_number();
   sleep(1)
   x = x+1;
   write_number(x);
}
Does write_number allways write a number incremented by one? No, it may happen a race condition.
a. Explain the race condition.
b. Create a mechanism to dectect this race condition (for instance, modify the system call to observe repeated numbers).
c. Solve this problem using Peterson solution for these two processes and test it. You will have to create other shared memory positions inside the kernel by other system calls similar to read_number and write_number.
d. Implement another solution that doens't share memory by the kernel through system calls. Implement threads that shares memory used in the Peterson Solution.

Team 7 - spin lock

Study:




Read (and goole other sources for spin lock):
Explain what it does and its use in your report.
There are many spin locks inside Linux kernel. When semop increments or decrements a semaphore (a shared variable), it uses spin lock. Create an init that uses semop. Run with gdb untill the spin lock and explain its use.
Find the ARM code in the kernel related to spin lock. What instructions does it use that works as "Test and set lock"? See:

Explain how the spinlock is implemented in ARM.
Create a spinlock that is implemented in the user space, i.e., make two processes (init and its child) looping something like:

while (1) {
     enter_region(); 
     print "A", print "B", print "C" ;
    leave_region; 
}

where enter_region and leave_region are implemented by LDREX and STREX.
Do your best to run the spin lock in gdb step by step.

Team 8 CFS Completely Fair Scheduler

Create the system call cfs() which returns a string such as:
"pid1:virtualRuntime1 pid2:virtualRuntime2 pid3:virtualRuntime3 ..."
which is ordained from the lowest virtualRuntime to the highest.
In oder to test, make an init which forks many other processes: some continually making arithmetic operations (cpu bound processes) and others getting chars from the keyboard (getc). From time to time, init must call cfs() and displays it.

Team 9 - process switch

Study:
-V76: https://www.youtube.com/watch?v=70nKCN_BQRA





Last year, Shibatas's team answered the following question:

Create 2 system calls:
block(pid)
blocks the pid process inserting it in a blocked processes queue.

error = unblock()
which unblock the first process in the blocked queue returning error = 0, or does nothing, and returns error = 1.


Test his solution making:
- init creates two children. First child continually prints "1" and second child continually prints "2".
- init continually blocks first child (you must see a lot of "2"), sleeps, unblock first child (you must see a mix of "1" and "2" ), sleeps, blocks second child, sleeps, unblocks second child, sleeps, blocks first child, and so on.

Study what happens when the first child is blocked:
- how is it removed from the running queue? Place a breakpoint at the end of the system call block(pid) and explain what happens. Take a screenshot.
- how the kernel chooses another process to run? Explain and take a screenshot.
- how the registers of the coming process are settled? Explain and take a screenshot.


Team 10 - Semaphore

Study:
-V78
--V79: https://www.youtube.com/watch?v=dI2NqcP40l4


Create three system calls:

semaforo_id = init_semaphore( valor_inicial),
up(semaforo_id) - which may call unblock.
down(semaforo_id) - which may call block.

In your work, you will make use of many queues. For instance: the first time the system call init is called, it will return semphore_id = 0 and will create a queue to semaphore 0; the second time, semphore_id = 1 and it will create to semaphore 1 and so on. It will return -1 in case of error (for instance, it can not allocate memory in kernel).
Look the Shibata's team implementation of block, unblock; but notice that "block" blocks other processes and not itself. Use wait_queue as a mechanism to block itself.


Comentários

Postagens mais visitadas deste blog

Basics on ARM processor

Assignments - 1