Professional Documents
Culture Documents
Note that this representation means that multiple instances of a signal with
the same type (having the same identifier) do not stack (are treated as a
single signal).
Each signal must also be associated with some action. To support this, add an array
of NUMSIG entries where every entry is a pointer to a function. We require that
every signal will have a default handler. This handler must only print the following
message: A signal was accepted by process %pid%, where %pid% is the pid of the
process.
The register_handler function is not native to xv6 and was added by the OS team to
support the present assignment (you can find it in proc.c). The function locates the
stack of the current process and opens a new frame. It must also update the old
instruction pointer so that when the new code (sighandler) is completed the process
normally resumes its execution.
Notice that our implementation differs from real world signal handling
schemes. In a real OS the kernel must not use the user stack (try to think
why) and should return to kernel mode after executing the handler code in
order to restore the process context.
Note: the scheduler may prevent the process from handling the signal as
soon as it is generated
You must use function prototypes and signals definitions from the signal.h
file.
/* thread's id */
/* current stack pointer register */
/* current base pointer register */
/* the thread's stack */
/* thread's state: running, runnable, waiting */
You may add any fields you see fit to the above struct. This type and the prototypes
of the ULT package API functions are defined for you in the uthread.h file, which we
added to the current revision in the svn repository.
The threads framework must maintain a table of the threads that exist within the
process. You can define a static array for this purpose, whose size will be defined by
the MAX_UTHREADS=64 macro (defined in uthread.h as well).
The application programming interface (API) of your threads package has to include
the following functions:
After performing the initialization steps you are free to use the uthread library.
Dont forget to allocate space for the threads stack. A size of a single page
(4096 bytes) should suffice.
Consider what happens when the threads entry function finishes: does it
have an address to return to? Hint: you can
o Wrap the entry function, so that a thread_exit call will be carried out
implicitly after the entry function finishes
o On thread creation, push the thread_exit as the return address.
Figure 1: depicts the stacks of threads A and B, executing functions fooA and fooB
respectively. Thread A calls uthread_yield. The value of the esp register should be
changed to point to the top of stack of thread B, so uthread_yield will return to the
next instruction in fooB (after the call to uthread_yield).
Tip: backing-up and restoring esp and performing stack related operations
requires inlining assembly code into your C code.
Scheduling policy:
Your threads package should support a round-robin scheduling policy where threads
are scheduled in a cyclic manner.
For more information about basic assembly operations (and conventions) you
can refer to: http://www.cs.virginia.edu/~evans/cs216/guides/x86.html
Notice that spinlocks are not the same as fair binary semaphores, for
example starvation can happen with spinlocks but not with semaphores due
to the queue of waiting threads that the semaphore maintains.
You have complete freedom to choose the algorithm you choose to implement in
order to solve the FSSP. Consider using the algorithm proposed by John
McCarthy and Marvin Minsky.
Submission guidelines
Assignment due date: 27/04/2014
Make sure that your Makefile is properly updated and that your code compiles with
no warnings whatsoever. We strongly recommend documenting your code changes
with remarks these are often handy when discussing your code with the graders.
Due to our constrained resources, assignments are only allowed in pairs. Please
note this important point and try to match up with a partner as soon as possible.
Submissions are only allowed through the submission system. To avoid submitting a
large number of xv6 builds you are required to submit a patch (i.e. a file which
patches the original xv6 and applies all your changes). You may use the following
instructions to guide you through the process:
Back-up your work before proceeding!
Before creating the patch review the change list and make sure it contains all the
changes that you applied and nothing more. Modified files are automatically
detected by svn but new files should be added explicitly with the svn add
command:
> svn add <filename>
In case you need to revert to a previous version:
> svn revert <filename>
At this point you may examine the differences (the patch):
> svn diff
Alternatively, if you have a diff utility such as kompare:
> svn diff | kompare o
Once you are ready to create a patch simply make sure the output is redirected to
the patch file:
> svn diff > ID1_ID2.patch
Tip: Although the graders will only apply your latest patch file, the submission
system supports multiple uploads. Use this feature often and make sure you upload
patches of your current work even if you havent completed the assignment.
Finally, you should note that the graders are instructed to examine your code on lab
computers only(!) - Test your code on lab computers prior to submission.
Enjoy!