The objective of this lab is to gain understanding on how to use OS161's thread library. There is also a little challenge at the end for those of you who would like to gain a broader understanding on the topic.
exercise 1, multi-threaded hello world
The objective of this exercise is to become familiar with OS161's thread
related system calls located in
First, make sure you happy with assignment0. Once you have done assignment0 and have submitted it, then read on.
Modifying your Kernel
We will now go through the steps required to modify and rebuild your kernel. We will add a new file to the sources. The file contains a function we will call from existing code. We need to add the file to the kernel configuration, re-config the kernel, and then rebuild again.
- Take a glance at
src/kern/include/thread.hand think about what each function does.
- Download multi_hello.c and place it into
- Find an appropriate place the in the kernel code, and add a call
multi_hello()(defined in multi_hello.c) to print out a initial greeting (Hint: the same place as assignment 0 might be a good idea). It should appear immediately before the prompt just as it did for assignment 0.
- As you have added a file to the kernel code, we need the follow the
same steps as assignment 0 and add place an include for
- Re-configure the kernel again by,
% cd ~/cs3231/src/kern/conf % ./config ASST0
- Rebuild the kernel
% cd ../compile/ASST0 % make depend % make % make install
- Run the kernel to confirm that you have successfully modified the kernel.
thread_fork()to fork a new thread using
hello_thread(). Examples on how to can be found though out the kernel.
- Re-compile and run the kernel to verify your code. NOTE: you don't need to re-configure the kernel as you have not change any includes .
- Now add another thread that prints out "OS/161 is my friend\n" and repeat the steps to re-compile and run the kernel.
exercise 2, Simple synchronisation
Now that we have successfully created a thread it is time to see how some the other thread related function work.Take another looks at
- First, modify your two threads so that one prints even numbers and the other
prints odd numbers up to ten in a small loop so they print
thread 1 : count 1 thread 1 : count 3 thread 1 : count 5 thread 1 : count 7 thread 1 : count 9 thread 2 : count 2 thread 2 : count 4 thread 2 : count 6 thread 2 : count 8 thread 2 : count 10
- Then think how you could make the two threads collectively count up correctly
and modify the two threads. You want to the end result to looks like
thread 1 : count 1 thread 2 : count 2 thread 1 : count 3 thread 2 : count 4 thread 1 : count 5 thread 2 : count 6 thread 1 : count 7 thread 2 : count 8 thread 1 : count 9 thread 2 : count 10
- If you haven't already add some code so the threads clean up after them selvs and think about what resouces a thread may consume.
exercise 3, pthread synchronisation
As you have seen in lectures OS/161 is not the only OS to have threads, Linux and most other UNIXs also have support for threads. One of the most commonly used thread libraries on Linux is called "POSIX Threads" or pthread. Some guide on pthreads can be found at
In this exercise, we will use pthread's synchronisation mechanisms to solve some simple problems, not OS161.
- pick a directory somewhere not inside os161, this exercise doesn't need os161.
- Download the following file in to the same directory, Makefile, mutex.c and deadlock.c.
makeand compile the programs and observe what they do
% make ... % ./mutex Mutex program starting. Hello world, I'm thread 1 Hello world, I'm thread 2 Hello world, I'm thread 3 Hello world, I'm thread 4 Hello world, I'm thread 5 Hello world, I'm thread 6 Hello world, I'm thread 7 Hello world, I'm thread 8 Hello world, I'm thread 9 Hello world, I'm thread 10 thread 3 counting 1 thread 1 counting 2 thread 6 counting 3 thread 10 counting 4 thread 4 counting 5 thread 7 counting 6 thread 9 counting 7 thread 2 counting 8 thread 8 counting 9 thread 1 counting 10 thread 5 counting 11 thread 2 counting 12 thread 4 counting 13 ... %./deadlock deadlock program starting. Hello world, I'm thread 1deadlock program starting. Hello world, I'm thread 1 thread 1 about to get resource A thread 1: I got resource A Hello world, I'm thread 2 thread 2 about to get resource B thread 2: I got resource B thread 2 about to get resource A thread 1 about to get resource B thread 1 about to get resource A thread 1: I got resource A Hello world, I'm thread 2 thread 2 about to get resource B thread 2: I got resource B thread 2 about to get resource A thread 1 about to get resource B
- Use pthread's synchronisation primitives (Hint: mutexs or semaphores) to solve the problems.
For the mutex program you need to make thread obey their order so that thread 1 counts then thread 2 then thread 3 and so on. You may not remove the sleep() call or alter the section that makes them sleep for a random number of seconds.
In the end the out put should look like
% ./mutex Mutex program starting. Hello world, I'm thread 1 Hello world, I'm thread 2 Hello world, I'm thread 3 Hello world, I'm thread 4 Hello world, I'm thread 5 Hello world, I'm thread 6 Hello world, I'm thread 7 Hello world, I'm thread 8 Hello world, I'm thread 9 Hello world, I'm thread 10 thread 1 counting 1 thread 2 counting 2 thread 3 counting 3 thread 4 counting 4 thread 5 counting 5 thread 6 counting 6 thread 7 counting 7 thread 8 counting 8 thread 9 counting 9 thread 10 counting 10 thread 1 counting 11 thread 2 counting 12 thread 3 counting 13 ...
The deadlock program has the classical deadlock example of two thread that need two resources A and B. The two threads attempt to acquire the renounces in opposite orders, you need to resolve the deadlock.
The labs are not assessable so don't solve them the easy way, use pthread synchronisation primitives to solve the problem.
Happy hacking :)