cs50300:fall16:lab5

DUE: Tuesday, November 1st by 11:59 PM

By the end of this lab students will be able to:

  • Understand the complexity of tracking and releasing resources allocated by a process
  • Learn how choices for initialization and the ability to reverse allocations affect on process termination
  • Extend the XINU operating system with a new system call that can be used to cleanup and restart processes

Operating systems may need to terminate and recreate processes when they apply software updates, (e.g., new device drivers and critical security updates), repair corrupted data structures, and clean up system resources, etc. Embedded systems that operate real-time mechanisms (e.g., brake control in an automobile) are required to restart processes in situations where a problem or unexpected condition threatens continuous operation. Therefore, many operating systems provide a method for a user to invoke a reboot or shutdown of the operating system (e.g. through a graphical interface, key combination, or system call).

The restart function

For this lab you will be creating a new system call for XINU restart to force XINU to restart user processes without performing a power cycle.

The format for the restart system call is as follows:

syscall restart(uint32 delay);

The restart system call terminates all user processes in the system and restarts them as if they had just been created and resumed. See “System processes vs User Processes” below for a description of which processes are callified as user processes that need to be restarted and which processes are not.

Freeing a buffer pool

One of the resources a user process can allocate is a buffer pool. Recall, that a process calls mkbufpool to allocate a buffer pool. Among other steps that mkbufpool performs, it calls getmem to allocate memory for the buffer pool. Although XINU provides provides getbuf and freebuf that can be used to allocate and release buffers dynamically, there is no system call to free the entire buffer pool.

As part of this lab you will need to provide a new system call freebufpool which will allow a user to free a buffer pool that has been allocated with mkbufpool. When freebufpool is called, any memory allocated to the pool must be returned to the free list. Similarly, any other resources that were allocated for the pool must be released.

NOTE: When the freebufpool system call is invoked there maybe buffers still allocated within the buffer pool. If there are any buffers currently allocated from the buffer pool then freebufpool cannot release all the memory and should return SYSERR. It is important that any buffers allocated by processes be freed as part of the process cleanup function (see below).

The format for the freebufpool system call is as follows:

syscall freebufpool(bpid32 poolid);

Process cleanup function

As part of being restarted, a process may need to perform cleanup on allocated memory or other operating systems resources (e.g., semaphores). To allow a process to perform cleanup you will be adding a new system call regcleanup. The new system call will be a take a single function pointer as a parameter which will be the function pointer to the cleanup function that will be registered to the current process. The cleanup function will take no arguments and have the following format:

void process_cleanup_function();

The prototype for the regcleanup system call is as follows:

syscall	regcleanup(void *);

Cleanup functions are stored on a per process basis. Each process can register a different cleanup function. Only a single cleanup function can be registered for a given process.

NOTE: When a process is created using the create system call, it will have no cleanup function registered (you will need to modify create.c to set the cleanup function to NULL when a process is created). You will need to make sure that if there is no cleanup function registered (the process never calls regcleanup), that XINU does not attempt to call a cleanup function for the process when it ends.

NOTE: the process stack, etc. that is freed by the kill system call should still be done by XINU in the kill system call. The cleanup function is only used for additional cleanup by the process.

NOTE: It is possible to change the cleanup function at any time. Furthermore, calling regcleanup(NULL) will remove any previously-registered cleanup function for the process.

Assuming the cleanup function pointer is not NULL, the cleanup function will need to be invoked when the process ends (either explicitly through a call to kill or implicitly by returning from the process function).

Retrieving Buffer Pool Information

For a process that allocates buffers from a buffer pool, it will most likely need to free the buffers and the buffer pool when its cleanup function executes. If a buffer pool is used by only a single process then it is possible for that process to keep track of how many buffers it has retrieved (with getbuff) and then it can ensure that all of those buffers are freed before calling freebufpool. However, what if a process is sharing a buffer pool with another process? How can it know when all the buffers in the pool are freed so that it can successfully call freebufpool? To allow a process to retrieve information about the buffers in a buffer pool you will need to provide system call called bufsavail.

The prototype for the bufsavail system call is:

int32 bufsavail(bpid32 poolid, int32* totalbufs);

The return value from bufsavail is the total number of buffers available in the buffer pool. The poolid input parameter is the identifier for the buffer pool to query and the totalbufs is an output parameter that will be set to the total number of buffers contained in the buffer pool (this parameter will have the same value as numbufs passed to mkbufpool).

Using the bufsavail system call will allow a process cleanup function to query the available buffers in the buffer pool. If the number available is equal to the total buffers in the pool, then the process can know that the buffer pool has no allocated buffers and can be safely deleted with freebufpool.

In /homes/cs503/xinu there is a file called xinu-fall2016-lab5.tar.gz that contains a start to the code. Unpack:

tar zxvf /u/u3/cs503/xinu/xinu-fall2016-lab5.tar.gz

This will create a directory called xinu-fall2016-lab5.

Along with the main code for XINU, this tarball contains the following files (additional explanation of the contents of the files is in the following sections).

  • system/freebufpool.c - function declaration for the freebufpool function.
  • system/regcleanup.c - function declaration fot the regcleanup function.
  • system/restart.c - function declaration for the restart function.
  • system/bufsavail.c - function declaration for the bufsavail function.
  • include/prototypes.h - modified prototypes.h file which includes the restart and freebufpool function.

Your task is to complete these functions to perform the requirements specified in the previous section.

Contents of ''freebufpool.c''

The freebufpool.c file contains an empty function declaration for the freebufpool function. Your job is to fill in code to free up the resources allocated by the buffer pool with the given pool identifier.

NOTE: It cannot be assumed that all buffers within the pool have been freed with freebuf when freebufpool is called. If any buffers are allocated when freebufpool is called then it should return SYSERR.

Contents of ''regcleanup.c''

The regcleanup.c file contains an empty function declaration for the regcleanup function. Your job is to fill in code to register the cleanup function with the current process. HINT: consider adding an entry to the process table.

Contents of ''restart.c''

The restart.c file contains an empty function declaration for the restart function. Your job is to fill in code to free up the resources allocated by user processes in XINU and restart them.

NOTE: Do not forget to delay for the specified number of seconds before the restart is started. Other processes must be allowed to execute during this delay time.

Contents of ''bufsavail.c''

The bufsavail.c file contains an empty function declaration for the bufsavail function. Your job is to fill in code to query the buffer pool for the available and total buffers.

NOTE: Do not forget to do parameter checking. If the pool identifier is not valid bufsavail should return SYSERR.

System Processes vs User Processes

As part of XINU initialization one or more processes may be created to handle critical system tasks. Take a look at system/initialize.c where the nulluser function calls net_init. The net_init function is located in net/net.c which initializes the network stack and creates two processes ipout and netin for processing the sending and receiving of network packets. These processes, created by the system, are critical to XINU execution and should not be restarted as part of the restart system call. Only user processes should be restarted, however ALL user process need to be restarted.

Question: How do you determine which process are user processes when the restart system call is invoked?

  • Answer: Prior to creating and resuming the main process, the only processes that exist in the system are system processes. No system process will be created after the main process is created and resumed. So, you will need to record the list of processes that currently exist prior to creating and resuming main in order to determine which processes to restart when the restart system call is invoked.

NOTE: The main process is a user process so if it is still running when the restart system call is invoked, it will also need to be restarted.

  • Provide a set of test cases to ensure that your code works as required. Put these test cases in main.c
    • Make sure your test cases not only test the new functionality of the new system calls, but that existing system calls still function correctly.
    • Don't forget to include test cases for the extra credit (see below) if you choose to implement the extra credit requirements. No extra credit will be awarded if test cases are not included.
  • The TAs will be replacing main.c with their own test cases after running your submitted test cases. Make sure you do not define any dependent variables in main.c. You are free to modify any other file(s) to implement the lab requirements.
    • Make sure that there are no dependent declarations in main.c.
  • If your submitted code does not compile (either the exact submitted code or the code after the TA's replace any test case files), you will receive zero (0) points for code execution. If this happens, you will be allowed to resubmit for half credit only.
  • Please run “make clean” prior to submission so that you don't submit object files
  • NOTE: When you make xinu for this lab the make file will generate a binary file in the compile directory called xinu. This is the file you will need to download to your backend.

Recall that when a process allocates memory with getmem, XINU does not keep reference counts or records of which process allocated the memory. As such, when that process is terminated, the memory allocated by the process cannot be automatically freed.

For extra credit add a feature to allow the restart system call to restore the freelist to its original state before user processes were started.

Question: How do you handle memory allocated on the heap by user processes? When a process ends, the memory allocated by getmem is not automatically freed?

  • Answer: Prior to creating and resuming the main process, the memory allocated on the heap has only been allocated by system processes (which are not restarted). Furthermore, you can also assume that system processes do not allocate additional heap after they have had a chance to run. So, prior to creating and resuming the main process, you need to record the contents (create a snapshot) of the freelist (referred to as memlist in the XINU code) so that it can be restored to that point when the restart is invoked. In other words, as part of the process restart, after all the user processes have ended and before they are started, the freelist should be restored to the state at which it was in before the main process is created and resumed.

This additional record keeping should be implemented in system/initialize.c.

NOTE: If a process registers a process cleanup function, the cleanup function should be allowed to execute before restoring the freelist to the state of the snapshot.

NOTE: All processes require an allocated stack in order to run. At the time the freelist snapshot is taken (in initialize.c) no user process will have their stacks allocated. However, when restart restarts user process, the processes will need to have an allocated stack. Do not forget to make sure that the correct stacks for the user processes are correctly allocated and initialized as part of restart.

Question: How are buffer pools handled as part of the freelist restore from the snapshot?

  • Answer: The intent is that process cleanup functions to take care of freeing up buffers and buffer pools. However, consider what problems can happen if a process does not clean up the allocated buffers and pools. Should the operating system call freebufpool or just restore the freelist snapshot? The choice of how to implement this is up to you. Discuss the advantages and disadvantages of your implementation in your lab analysis report.

Additional Extra Credit Study Questions:

  • Does this behavior of restart have any practical use?
    • Is there a better alternative behavior of restart?
    • What are the advantages and disadvantages of either implementation?
  • Consider how processes can communicate in Xinu: Does restarting all user processes create any timing problems that might affect inter processes communication?

Submit using the turnin command (see below) your complete source code (all of XINU) including the any files you added to complete the lab. In the system directory include a PDF file called lab5_analysis.pdf with a report discussing:

  • The details behind your implementation (including a discussion of the extra credit if attempted). As part of this discussion write answers to the following questions:
    • What specific problems can occur if user processes are repeatedly killed and restarted?
    • Suppose a set of user processes is killed in random order. Show how the system can be left in a state where some processes never die?

NOTE: Make sure you put your name on your report, that the file is named exactly as specified, and the file located in the directory specified.

To turn in your lab use the following command

turnin -c cs503 -p lab5 xinu-fall2016-lab5

assuming xinu-fall2016-lab5 is the name of the directory containing your code.

If you wish to, you can verify your submission by typing the following command:

turnin -v -c cs503 -p lab5

Do not forget the -v above, as otherwise your earlier submission will be erased (it is overwritten by a blank submission).

Note that resubmitting overwrites any earlier submission and erases any record of the date/time of any such earlier submission.

We will check that the submission time stamp is before the due date; Any submission past the due date will be deducted the appropriate number of grace days. If submission is beyond your remaining number of grace days, your work will not be accepted.

  • cs50300/fall16/lab5.txt
  • Last modified: 2016/10/27 20:31
  • by lembkej