This is my project report for MIT 6.S081(Operating System), 2021 Fall.
PLEASE NOTE: The hyperlinks to my source code in this repo are INVALID!!! This is a public version of my project. I don't open my source code because it is a course project and I believe I'm obliged to help protect academic integrity.
If you want to verify my code, I think the GitHub Action is enough;
If you want to see my code, please contact me at zj_hu [at] zju.edu.cn
and demonstrate your identity first.
Additionally, I wrote a summery for the course. Please look at Summery.md if you are interested.
The original requirements can be found here.
To implement following functions:
sleep
: Pause for a user-specified number of tickspingpong
: Use UNIX system calls to "ping-pong" a byte between two processes over a pair of pipes, one for each direction.primes
: Write a concurrent version of prime sieve using pipes.find
: Write a simple version of the UNIX find program: find all the files in a directory tree with a specific name.xargs
: Write a simple version of the UNIX xargs program: read lines from the standard input and run a command for each line, supplying the line as arguments to the command.
user/sleep.c
user/pingpong.c
user/primes.c
user/find.c
user/xargs.c
The original requirements can be found here.
To implement the following two functions in the kernel:
trace
: Add a system call tracing feature. It should take one argument, an integer "mask", whose bits specify which system calls to trace. Modify the xv6 kernel to print out a line when each system call is about to return, if the system call's number is set in the mask.sysinfo
: It collects information about the running system. The system call takes one argument: a pointer to astruct sysinfo
(seekernel/sysinfo.h
). The kernel should fill out the fields of this struct: thefreemem
field should be set to the number of bytes of free memory, and thenproc
field should be set to the number of processes whosestate
is notUNUSED
.
kernel/proc.c
kernel/syscall.c
kernel/kalloc.c
The original requirements can be found here.
To implement the following three functions in the kernel:
- Make it possible for processes in user mode to directly retrieve
pid
without entering kernel. When each process is created, map one read-only page atUSYSCALL
(a VA defined inmemlayout.h
). At the start of this page, store astruct usyscall
(also defined inmemlayout.h
), and initialize it to store thePID
of the current process. vmprint()
: It should take apagetable_t
argument, and print thatpagetable
.sys_pgaccess()
: return the info of accessed pages to the buffer passed in by user.
The original requirements can be found here.
- Implement the
backtrace
function to print out the return addresses of the functions which are called. - Implement
sigalarm(int ticks, (void *handler)())
so that it will set an alarm which will set off at the interval ofticks
. When the alarm set off, the system will call thehandler
function to handle the alarm. Callsigalarm(0, 0)
to unset the alarm.
The original requirements can be found here.
To implement copy-on-write fork in the xv6 kernel.
The goal of copy-on-write (COW) fork()
is to defer allocating and copying physical memory pages for the child until the copies are actually needed, if ever.
COW fork()
creates just a pagetable
for the child, with PTE
s for user memory pointing to the parent's physical pages. COW fork() marks all the user PTE
s in both parent and child as not writable. When either process tries to write one of these COW pages, the CPU will force a page fault. The kernel page-fault handler detects this case, allocates a page of physical memory for the faulting process, copies the original page into the new page, and modifies the relevant PTE
in the faulting process to refer to the new page, this time with the PTE
marked writeable. When the page fault handler returns, the user process will be able to write its copy of the page.
COW fork()
makes freeing of the physical pages that implement user memory a little trickier. A given physical page may be referred to by multiple processes' page tables, and should be freed only when the last reference disappears.
The original requirements can be found here.
Uthread
: Design the context switch mechanism for a user-level threading system, and then implement it.Using threads
: Explore parallel programming with threads and locks using a hash table.- Implement a barrier: a point in an application at which all participating threads must wait until all other participating threads reach that point too. Use
pthread
condition variables, which are a sequence coordination technique similar toxv6
's sleep and wakeup.
The original requirements can be found here.
No detailed report provided because the hints in the lab specification are lucid enough.
Your job is to complete e1000_transmit()
and e1000_recv()
, both in kernel/e1000.c
, so that the driver can transmit and receive packets. You are done when make grade
says your solution passes all the tests.
- Every time
e1000_recv()
is called, there could be multiple packages waiting to be read. If not all of these packages are processed, then the program will just sleep forever, while the switcher cannot find anyRUNNABLE
thread to execute. net_rx()
, which is called ine1000_recv()
, will finally calle1000_transmit()
. Since we need to add lock for bothe1000_transmit()
ande1000_recv()
, it's impossible to just add a lock through out the functions.
The original requirements can be found here.
- To implement per-CPU freelists, and stealing when a CPU's free list is empty, so that lock contentions can be reduced.
- Modify the block cache so that the number of
acquire
loop iterations for all locks in the bcache is close to zero when runningbcachetest
. Use hash table to minimize lock contention onbcache.lock
.
Note that there was a bug in the original code. I fixed it. Please look at the detailed report at docs/lock.md for more infomation.
Here is the original requirement.
- Increase the maximum size of an xv6 file from
$12+256=268 \ blocks$ to$(11+256+256^2) blocks$ - Implement the
symlink(char *target, char *path)
system call, which creates a new symbolic link at path that refers to file named bytarget
.
Here is the original requirement.
Implement enough mmap
and munmap
functionality, including:
mmap
a file to a virtual area which is allocated by the OS applying the lazy allocation. Support settingPROT
(PROT_READ, PROT_WRITE, PROT_EXEC
),flags
(MAP_SHARED, MAP_PRIVATE
), offset and length. When the mmap-ed page is accessed, it will invoke a page fault and the OS will read in the corresponding page in the related file to that mmap-ed page.munmap
the mmap-ed pages. It cannot unmap a hole in the virtual area.- After adding these features, the normal system operations like
fork()
and other illegal page faults are still processed correctly.
Note: The usertests
is time-consuming. If your computer has a weak performance, the usertests
may fail because of time out.
NOTE: THERE ARE SOME BUGS IN THE ORIGINAL CODE. I FIXED IT.
IF YOU HAVE QUESTIONS, SEE THE DETAILED REPORT.
Note: The usertests
is EVEN MORE TIME-CONSUMING. If your computer has a weak performance, the usertests
may fail because of time out.