HW 2留学生讲解、辅导C/C++语言、讲解C/C++程序设计、辅导Nachos

- 首页 >> C/C++编程

HW 2

Follow the Lab1 instruction and create a new fresh Nachos

folder.

Overview

So far, all the code you have written for Nachos has been part

of the operating system kernel (ThreadTest() is compiled and ran

within Nachos). In a real operating system, the kernel not only

uses its procedures internally, but allows user-level programs

to access some of its routines via “system calls”. In this

project, you are going to implement several system call routines

for user programs and round-robin scheduling.

The user programs are written in C and located under test/

directory. There are several example programs provided,

including halt, shell, etc. The command “./nachos -

x ../test/programname” will load the program ‘programname’ to

Nachos memory (see addrspace.cc and progtest.cc) and run it on

Nachos.

Task 1 (30pts) System Calls for user program: userprog/syscall.h

defines the system call prototypes of Nachos. These are kernel

procedures that user programs can invoke. You need to implement

the following system calls.

Fork_POS()enables the user program to fork a kernel child

thread. It takes integer 1, 2 or 3 as parameter, creates a

corresponding kernel thread, which executes one of the test

functions basing on the parameter value, and returns an

integer as the process ID of the child. For example, when

child = Fork_POS(2) is called in a user program, a kernel

thread will be created in ExceptionHandler() and this

thread will call the ForkTest2 function (using the

Fork()call of thread.cc). The child process ID will be

assigned to child.

void ForkTest1(int id)

{

printf("ForkTest1 is called, its PID is %d\n", id);

for (int i = 0; i < 3; i++)

{

printf("ForkTest1 is in loop %d\n", i);

for (int j = 0; j < 100; j++)

kernel->interrupt->OneTick();

}

Exit_POS(id);

}

void ForkTest2(int id)

{

printf("ForkTest2 is called, its PID is %d\n", id);

for (int i = 0; i < 3; i++)

{

printf("ForkTest2 is in loop %d\n", i);

for (int j = 0; j < 100; j++)

kernel->interrupt->OneTick();

2

? Wait_POS() provides the routine for the user program to

wait for the execution of its child thread. It takes the

child process ID as parameter. The parent will be put into

sleep until the child awakens it. The child wakes up the

parent when it finishes by calling Exit_POS, which you’ll

implement. Wait_POS() and Exit_POS() should be able to

handle certain errors such as invalid child process ID or

no parent process waiting.

Exit_POS() is called by a child and wakes up its parent.

This function is not a system call but you need to

implement in exception.cc

For this task, syscall.h, exception.cc, start.s (assembly

routine for system calls and under test/ directory), and

scheduler.cc must be modified. The userprog/exception.cc

implements the handlers for system calls and other user-level

exceptions. In the original file, only the Halt() system call is

supported.

Hint: you can find a good example from system call Add.

You can find test programs (prog1.c, prog2.c and prog3.c) in the

Testing section. For this task testing, you don’t need

multitasking with round-robin.

Task 2 (20pts) Multitasking (running multiple user-level

programs): when the ‘-x’ flag is used, the ‘main’ function of

Nachos calls the RunUserProg() function with the string

following ‘-x’ as parameter. Remember that every user program

should have its own thread structure, but for now there’s only

one thread, the ‘main’ thread.

The goal of this task is to make the command

./nachos -x ../test/mprog1 -x ../test/mprog2

work in Nachos. What this means is that when you type this

command, Nachos will load multiple user programs into its main

memory and start executing them as threads with round-robin

scheduling. You need to implement Write system call.

Write()writes string to a specified destination. We’re

faking it using printf, therefore it always writes to the

screen. This system call takes three arguments: a char*

buffer, an int size, and an OpenFileId. Since we’re faking

it, we can ignore the OpenFileId parameter. You need to

obtain the first two arguments from the user program and

print an character at a time using printf.

3

Task 3 (45pts) Memory Allocation (Address Space for user

programs): The main issue in this implementation is how to

create the address spaces of the Nachos processes and put them

all in the main memory without overlapping. The allocation of

address space is done in userprog/addrspace.cc.

If the total size of the user programs (for

example, ./nachos -x ../test/prog1 -x ../test/prog2 …) are

smaller than the memory size, you can just use contiguous memory

allocation. However, for the command like ./nachos -

x ../test/matmult, you need to consider larger memory allocation

needed than Nachos physical memory size. matmult is a matrix

multiplication program. If you run the program now, you’ll get

an assertion failure in userprog/addrspace.cc because there’s

not enough memory to load it. So what you need to accomplish is

to let Nachos run the program with part of the address space

loaded, and load the other part(s) when they are accessed.

Because an exception will arise when they are accessed, the

loading should be done as an exception handling in

userprog/exception.cc.

You’re free to use whatever design you choose.

For the first case, you can use the page table and assume

the memory allocation is contiguous by keeping track of the

first free page frame to load a given user program’s

address space.

For the second case, you can store the whole address space

in a file, and load the accessed part every time an

exception arises.

Task 4 (5pts) Round-robin scheduling: Round-robin scheduling

gives each process (Nachos thread) a fix time slice (quantum) to

run. After the quantum expires, the CPU will be taken from the

process and given to the next process in the ready list. The

older process is then inserted to the end of the ready list.

You already added the flag “quantum” from the programming

assignment 1, i.e., when you type the command “./nachos -

quantum 200”, Nachos will run with the quantum set to 200

clock ticks.

4

Testing:

We will build and run your Nachos on the VM. TAs will test

multitasking with user programs with their quantum size and

memory allocation using matmult program.

Place the following programs into test/ directory and update

Makefile. The test programs must be compiled before Nachos is

built.

// Task 1 testing programs

/*** prog1.c ***/

#include "syscall.h"

int

main()

{

int child;

child = Fork_POS(1);

Wait_POS(child);

child = Fork_POS(2);

Wait_POS(child);

child = Fork_POS(3);

Wait_POS(child);

Exit(0);

}

/*** prog2.c ***/

#include "syscall.h"

int

main()

{

int child1, child2;

child1 = Fork_POS(1);

child2 = Fork_POS(2);

Wait_POS(child1);

Wait_POS(child2);

Exit(0);

}

/*** prog3.c ***/

#include "syscall.h"

int

main()

{

Fork_POS(1);

Fork_POS(2);

Fork_POS(3);

Exit(0);

}

5

// mprog1.c for Task 2, 3 and 4 testing

#include "syscall.h"

int

main()

{

OpenFileId output = ConsoleOutput;


char* str = "current user program: prog1";

int i,j;

for (i = 0; i < 5; i++)

{

Write(str, 27, output);

for (j = 0; j < 10000; j++);

}


Exit(0);

}

// mprog2.c for Task 2, 3 and 4 testing

#include "syscall.h"

int

main()

{

OpenFileId output = ConsoleOutput;


char* str = "current user program: prog2";

int i,j;

for (i = 0; i < 5; i++)

{

Write(str, 27, output);

for (j = 0; j < 10000; j++);

}


Exit(0);

}


站长地图