project 2 mcp ghost in the shell cis 415 operating systems fall 2019 p
Search for question
Question
Project 2
(MCP: Ghost-in-the-shell)
CIS 415 - Operating systems
Fall 2019 Prof. Allen Malony
Due date: 11:59 pm, Tuesday, Nov 8th, 2023
Introduction:
The British philosopher, Gilbert Ryle, in The Concept of Mind criticizes the classical
Cartesian rationalism that the mind is distinct from the body (known as mind-body duality). He
argues against the “dogma of the ghost in the machine” as an independent non-material entity,
temporarily inhabiting and governing the body. In The Ghost in the Machine, Arthur Koestler
furthers the position that mind and body are connected and that the personal experience of mind-
body duality is emergent from the observation that everything in nature is both a whole and a
part. The manga series by Masamune Shirow, The Ghost in the Shell, whose title is an homage to
Koestler, explores the proposition that human consciousness and individuality IS the “ghost” and
whether it can exist independently of a physical body, with all that implies. When I was going to
UCLA for my B.S. and Master's degrees, I worked for 3 summers as an intern at
Burroughs Corporation's Medium Systems Division in Pasadena, California. Sadly, Burroughs
no longer exists, having merged with Sperry Corporation to form Unisys, but they were a major
player in computing systems for a long time. During my last summer internship at Burroughs,
my job was to write modules for the Master Control Program, affectionately known as the
MCP:
http://en.wikipedia.org/wiki/Burroughs MCP
The MCP might be considered primitive in contrast to modern operating systems, but it
was innovative in many respects, including: the first operating system to manage multiple
processors, the first commercial implementation of virtual memory, and the first OS written
exclusively in a high-level language. MCP executed “jobs” with each containing one or more
tasks. Tasks within a job could run sequentially or in parallel. Logic could be implemented at the
job level to control the flow of a job by writing in the MCP's workflow control language (WFL).
Once all tasks in a job completed, the job itself was done. In some respects, we might regard
these features of MCP as now being provided through shell scripts that access an operating
system's services. I often wonder whether the ghosts of the modules I wrote for MCP continue to
live in the shells being used today.
Project Details:
In this project, you will implement the MCP Ghost in the Shell (MCP for short) whose primary job is to launch a pool of sub-processes that will execute commands given in an input file. The
MCP will read a list of commands (with arguments) to run from a file, it will then start up and
run the process that will execute the command, and then schedule the processes to run
concurrently in a time-sliced manner. In addition, the MCP will monitor the processes, keeping
track of how the processes are using system resources. There are a total of 4 parts to the project,
each building on the other. The objective is to give you a good introduction to processes, signals,
signal handling, and scheduling. Each part is a complete program by itself and must be saved in
a separate *.c file.
Part 1: MCP Launches the Workload
For part 1 of this project, you will be developing the first version of the MCP such that it can
launch the workload and get all of the processes running together.
Program Requirements:
Your MCP v1.0 must perform the following steps:
1. Read the program workload from the specified input file (This should work just like the
file mode from Project 1). Each line in the file contains the command and its arguments.
2. For each command, your MCP must launch the a separate process to run the command
using some variant of the following system calls:
a. fork(2): http://man7.org/linux/man-pages/man2/fork.2.html
b. One of the exec() system calls (see exec):
i.
http://man7.org/linux/man-pages/man3/exec.3.html
3. Once all of the processes are running, your MCP must wait for each process to terminate
using one of the wait family of system calls (wait/waitpid).
a. wait(2): http://man7.org/linux/man-pages/man2/waitid.2.html
4. After all processes have terminated, your MCP must exit using the exit() system call.
a. exit(): http://man7.org/linux/man-pages/man2/exit.2.html
Fig. 1 presents the pseudocode for launching processes: for (int i = 0; i < line_number; i++)
{
pid_array[i] = fork();
if (pid_array[i] < 0)
{
//error handling
}
if (pid_array[i] == 0)
{
if (execvp (path, arg) :
===
-1)
{
error handling
}
//
exit(-1);
}
}
Remarks:
Fig. 1: Pseudocode for launching processes
To make things simpler, assume that the programs will run in the environment used to execute
the MCP (i.e. the VM). While this may appear to be simple, there are many, many things that can
go wrong. You should spend some time reading the entire man page for all of these system calls.
Also, you will need to figure out how to read the commands and their arguments from the
"workload" file and get them in the proper form to call exec. These commands can be anything
that will run in the same environment as the MCP, meaning the environment in which the MCP
is launched. A set of commands are provided to help to evaluate your work, but you should also
construct your own. Lastely, the console output of your program has a heavy influence on your
final grade so take some time to think about how your program represents what is going on at
this stage. What is expected is that your output will be somewhat jumbled. This can be an
excellent indicator that your code is working as intended. If you find that your messages are all
synchronized then you know that something is going wrong.
Part 2: MCP Controls the Workload
Successful completion of Part 1 will give you a basic working MCP. However, if we just wanted to run all the workload programs at the same time, we might as well use a shell script.
Rather, our ultimate goal is to schedule the programs in the workload to run in a time-shared
manner. Part 2 will take the first step to allow the MCP to gain control for this purpose. This will
be completed in two core steps:
Step 1:
Step 1 of Part 2 will implement a way for the MCP to stop all forked (MCC) child
processes right before they call exec(). This gives the MCP back control before any of the
workload programs are launched. The idea is to have each forked child process wait for a
SIGUSR1 signal before calling exec() with its associated workload program. The sigwait()
system call will be useful here. Note: that until the forked child process does the exec() call, it is
running the same code as it's parent (i.e. MCP's code). Once Step 1 is working, the MCP is in a
state where each child process is waiting on a SIGUSR1 signal. The first time a workload
process is selected to run by the MCP scheduler, it will be started by the MCP sending the
SIGUSR1 signal to it. Once a child process receives the SIGUSR1 signal, it launches the
associated workload program with the exec() call.
Step 2:
Step 2 will implement the needed mechanism for the MCP to signal a running process to
stop (using the SIGSTOP signal) and then to continue it again (using the SIGCONT signal). This
is the mechanism that the MCP will use on a process after it has been started the first time.
Sending a SIGSTOP signal to a running process is like running a program at the command line
and typing Ctrl-Z to suspend (stop) it. Sending a suspended process a SIGCONT signal is like
bringing a suspended job into the foreground at the command line.
Program Requirements:
Thus, in Part 2, you will take your MCP v1.0 and implement both Step 1 and 2 to create
MCP v2.0. Your MCP v2.0 must do the following:
1. Immediately after each program is created using the fork() system call, the forked MCP
child process waits until it receives a SIGUSR1 signal before calling exec().
2. After all of the MCP child processes have been forked and are now waiting, the MCP
parent process must send each child process a SIGUSR1 signal (at the same time) to
wake them up. Each child process will then return from the sigwait() and call exec() to
run the workload program.
3. After all of the workload programs have been launched and are now executing, the MCP
must send each child process a SIGSTOP signal to suspend them.
4. After all of the child processes have been suspended, the MCP must send each child
process a SIGCONT signal to wake them up.
5. Again, once all of the processes are back up and running, the MCP must wait for each
child process to terminate. After all processes have terminated, the MCP will exit and free any allocated memory.
Remarks:
MCP 2.0 demonstrates that we can control the suspending and continuing of processes.
You should test out that things are working properly. One way to do this is to create messages
that indicate what steps the MCP is presently taking and for which child process. The console
output of your program has a heavy influence on your final grade so take some time to think
about how your program represents what is going on at this stage.
Again, a set of programs will be provided to evaluate your work, but you should also
construct your own. Handling asynchronous signaling is far more nuanced than described here.
We recommend that you should spend some time studying to gain a better understanding of the
system calls used in this project as well as signals and signal handling.
Part 3: MCP Schedules Processes
Now that the MCP can stop and continue workload processes, we want to implement a
MCP scheduler that will run the processes according to some scheduling policy. The simplest
policy is to equally share the processor by giving each process the same amount of time to run
(e.g., 1 second). The general situation is that there is 1 workload process executing. After its time
slice has completed, we want to stop that process and start up another ready process. The MCP
decides which is the next workload process to run, starts the timer, and continues that process.
Program Requirements:
MCP 2.0 knows how to resume a process, but we need a way to have it run for only a
certain amount of time. For Part 3 of this project, you will be upgrading your MCP v2.0 to
include process scheduling. Note: if a child process is running, it is still the case that the MCP is
running "concurrently" with it. Thus, one way to approach the problem of process scheduling is
for the MCP to poll the system time to determine when the time slice is expended. This is
inefficient and not as accurate as it can be.
Thus, we will be using signal processing to implement a more intelligent way of process
scheduling. In general, this is done by setting an alarm using the alarm(2) system call. This tells
the operating system to deliver a SIGALRM signal after some specified time. In general, signal
handling is done by registering a signal handling function with the operating system. When the
signal is delivered, the MCP will be interrupted and the signal handling function will be
executed. The following must happen after the alarm signal is received by the MCP:
1. The MCP will suspend the currently running workload process using SIGSTOP.
2. The MCP decides on the next workload process to run, and sends it a SIGCONT signal.
3. The MCP will reset the alarm, and continue with whatever else it was doing.
Remarks:
Your new and improved MCP v3.0 is now a working workload process scheduler./n