[an error occurred while processing this directive][an error occurred while processing this directive]
This assignment covers:
In the previous assignment (Lab 1), you had only one user program running by the operating system. In the Part A of this assignment, you are supposed to implement a fully operational multiprogramming environment, where multiple user programs can be executed at the same time. Programs will be allowed to invoke child user programs and, if needed, may wait for completion of these child programs. In such a multiprogramming environment, synchronization becomes important since programs may access shared data structures concurrently.
Part B of this assignment is to implement argument passing such that programs can read command line arguments. Part B is supposed to teach you how the operating system can pass arguments to user programs, in particular, how it is solved in 80x86 architecture by pushing them into the program's stack.
In Part C you will make the operating sytem more robust by implementing argument validation for system calls. The goal is to make the system safe from misbehaving user programs, i.e. a misbehaving program should not be able to crash the operating system.
Note that in this assignment you are not supposed to implement synchronized access to the file system.
In this assignment, you will need to implement two new systems calls and extend one system call from the previous lab:
In addition to the source code which you have already looked at in the
second lab, you should read and understand the code
in userprog/process.c
. This file contains a set of
functions that you can use to implement execution of a new user
program and argument passing. You have to clearly understand
how the user program is loaded into the memory and how it is started.
Before you begin doing your lab assignment, you have to answer the following set of questions to ensure that you are ready to continue:
wait()?create()). (a) Specify the situations when
accessing the data via that pointer can lead to problems. (b)
What can be done about it? (Tip: read "Accessing
User Memory" Section). The main part of this assignment is to implement (extend) the following system calls:
Runs the executable whose name is given in cmd_line, passing any given arguments, and returns the new process’s program id (pid). Must return pid -1, if the program cannot load or run for any reason.
Terminates the current user program, returning the exit code status to the kernel.
Provides synchronization between user programs. Parent process
waits until its pid-child process dies (if the child is still
running) and receives the child exit code. If the child has
finished, wait() should return child's exit value without
waiting.
Consider all possible situations with wait() that your
program must handle before starting your implementation:
wait() while the child
is still running wait() afterwards, orwait().wait() before the child exits.Each thread can have many children (threads), and the number of threads can vary over time and there is no (fixed) upper limit on the number of threads!
Synchronization is one of the most essential aspects in these assignments. The operating system may work fine in some situations but it can crash or malfunction in the other situations, if synchronization is implemented incorrectly or not sufficiently. Therefore, requirements regarding synchronization are as follows:
Note that in this assignment you are not supposed to implement synchronized access to the file system.
When you do your implementation, don't forget to clean up data structures that you dynamically allocate. Memory leakage is a VERY BAD thing!
A user program may be called with arguments in the command line. Implement arguments passing, so the arguments of a user program can be accessible within it (details).
At first, you should go into userprog/process.c
,
find the function setup_stack() and change back the
following line:
*esp = PHYS_BASE - 12;
into
*esp = PHYS_BASE;
Now your program will always fail until you implement argument
passing. Try to run any user program.
Stop! Before continuing, explain why you have KERNEL PANIC after you have removed "-12". What is wrong and why did the program work before?
The user program with arguments should be called with apostrophes (') from the Pintos command line. For example, pintos --qemu -- run 'insult -s 17', where user program insult is called with arguments -s and 17.
When the user program with arguments is called from exec(), you have to call it like this: exec("insult -s 17").
Although you can parse the string from the command line any way you
like, we recommend you to have a look at the
function strtok_r(), prototyped
in lib/string.h
and implemented with thorough comments
in lib/string.c
. You can find more about it by looking
at the man page (run man strtok_r at the prompt). We suggest
that you limit the number of arguments to, for example, 32, which will
simplify your implementation because you can use a static array of a
fixed size to store the parsed arguments.
Necessary details about setting up the stack for this task you can find in Program Startup Details section of the Pintos documentation.
In this part of the assignment you must make the operating system
robust by validating the arguments to the system calls. As long as
this validation is not implemented a user program may do
for instance create((char*)0,1) causing the kernel to crash when trying
to read the name of the file to be created.
Your task is to validate all arguments passed by user programs to the interrupt handler via system calls.
Once you have finished both Part A and Part B you can run the tests by issuing make check. Please note that you must do both A and B before you can run the tests; if you have only implemented Part A all tests will fail. For the test script to work you need to add printf("%s: exit(%d)\n", thread-name, thread-exit-value) to the code that is executed when a user process exits or is killed.
When you have finished all parts of this lab all 50 tests should pass. As always when testing: passing all tests is not a guarantee that the code is correct.
| Code directory: | src/userprog, src/threads, src/lib, src/lib/kernel |
| Textbook chapters: | Chapter 2.3: System Calls Chapter 2.4: Types of System Calls Chapter 4.4: Threading Issues Chapter 6.2: The Critical-Section Problem Chapter 8.4: Paging |
| Documentation: | Pintos documentation related to Project 2 (Always remember that the TDDE68 lab instructions always have higher precedence) |
In order to reduce time for demos and maximize time for questions, please make sure you can be fluent describing all your code and answer questions on implementation details. Hesitations and discussions are time consuming and this time is not available to other groups for solving problems. Please be ready to describe the creation of a new process, waiting for a process and terminating a process as well as stack building and pointer checking.
In order to help you checking your code, below is a list of issues commonly met when grading this lab. Remember passing all the tests and complying with this check list is not necessarily enough. You need to make sure yourself lab assistants won't point out any other issue.