Clarify that joinability is not inherited.
[pintos-anon] / doc / threads.texi
1 @node Project 1--Threads, Project 2--User Programs, Pintos Tour, Top
2 @chapter Project 1: Threads
3
4 In this assignment, we give you a minimally functional thread system.
5 Your job is to extend the functionality of this system to gain a
6 better understanding of synchronization problems. Additionally, you
7 will use at least part of this increased functionality in future
8 assignments.
9
10 You will be working in primarily in the @file{threads} directory for
11 this assignment, with some work in the @file{devices} directory on the
12 side.  Compilation should be done in the @file{threads} directory.
13
14 Before you read the description of this project, you should read all
15 of the following sections: @ref{Introduction}, @ref{Coding Standards},
16 @ref{Project Documentation}, @ref{Debugging Tools}, and
17 @ref{Development Tools}.  You should at least skim the material in
18 @ref{Threads Tour}.  To complete this project you will also need to
19 read @ref{Multilevel Feedback Scheduling}.
20
21 @menu
22 * Understanding Threads::       
23 * Project 1 Code::              
24 * Debugging versus Testing::    
25 * Tips::                        
26 * Problem 1-1 Alarm Clock::     
27 * Problem 1-2 Join::            
28 * Problem 1-3 Priority Scheduling::  
29 * Problem 1-4 Advanced Scheduler::  
30 * Threads FAQ::                 
31 @end menu
32
33 @node Understanding Threads
34 @section Understanding Threads
35
36 The first step is to read and understand the initial thread system.
37 Pintos, by default, implements thread creation and thread completion,
38 a simple scheduler to switch between threads, and synchronization
39 primitives (semaphores, locks, and condition variables). 
40
41 However, there's a lot of magic going on in some of this code, so if
42 you haven't already compiled and run the base system, as described in
43 the introduction (@pxref{Introduction}), you should do so now.  You
44 can read through parts of the source code by hand to see what's going
45 on.  If you like, you can add calls to @func{printf} almost
46 anywhere, then recompile and run to see what happens and in what
47 order.  You can also run the kernel in a debugger and set breakpoints
48 at interesting spots, single-step through code and examine data, and
49 so on.  @xref{i386-elf-gdb}, for more information.
50
51 When a thread is created, you are creating a new context to be
52 scheduled. You provide a function to be run in this context as an
53 argument to @func{thread_create}. The first time the thread is
54 scheduled and runs, it will start from the beginning of that function
55 and execute it in the context. When that function returns, that thread
56 completes. Each thread, therefore, acts like a mini-program running
57 inside Pintos, with the function passed to @func{thread_create}
58 acting like @func{main}.
59
60 At any given time, Pintos is running exactly one thread, with the
61 others switched out.  The scheduler decides which thread to run next
62 when it needs to switch between them.  (If no thread is ready to run
63 at any given time, then the special ``idle'' thread runs.)  The
64 synchronization primitives are used to force context switches when one
65 thread needs to wait for another thread to do something.
66
67 The exact mechanics of a context switch are pretty gruesome and have
68 been provided for you in @file{threads/switch.S} (this is 80@var{x}86
69 assembly; don't worry about understanding it).  It involves saving the
70 state of the currently running thread and restoring the state of the
71 thread we're switching to.
72
73 Using the @command{gdb} debugger, slowly trace through a context
74 switch to see what happens (@pxref{i386-elf-gdb}).  You can set a
75 breakpoint on the @func{schedule} function to start out, and then
76 single-step from there.@footnote{@command{gdb} might tell you that
77 @func{schedule} doesn't exist, which is arguably a @command{gdb} bug.
78 You can work around this by setting the breakpoint by filename and
79 line number, e.g.@: @code{break thread.c:@var{ln}} where @var{ln} is
80 the line number of the first declaration in @func{schedule}.}  Be sure
81 to keep track of each thread's address
82 and state, and what procedures are on the call stack for each thread.
83 You will notice that when one thread calls @func{switch_threads},
84 another thread starts running, and the first thing the new thread does
85 is to return from @func{switch_threads}.  We realize this comment will
86 seem cryptic to you at this point, but you will understand threads
87 once you understand why the @func{switch_threads} that gets called is
88 different from the @func{switch_threads} that returns.
89
90 @strong{Warning}: In Pintos, each thread is assigned a small,
91 fixed-size execution stack just under @w{4 kB} in size.  The kernel
92 does try to detect stack overflow, but it cannot always succeed.  You
93 may cause bizarre problems, such as mysterious kernel panics, if you
94 declare large data structures as non-static local variables,
95 e.g. @samp{int buf[1000];}.  Alternatives to stack allocation include
96 the page allocator in @file{threads/palloc.c} and the block allocator
97 in @file{threads/malloc.c}.  Note that the page allocator doles out
98 @w{4 kB} chunks and that @func{malloc} has a @w{2 kB} block size
99 limit.  If you need larger chunks, consider using a linked structure
100 instead.
101
102 @node Project 1 Code
103 @section Code
104
105 Here is a brief overview of the files in the @file{threads}
106 directory.  You will not need to modify most of this code, but the
107 hope is that presenting this overview will give you a start on what
108 code to look at.
109
110 @table @file
111 @item loader.S
112 @itemx loader.h
113 The kernel loader.  Assembles to 512 bytes of code and data that the
114 PC BIOS loads into memory and which in turn loads the kernel into
115 memory, does basic processor initialization, and jumps to the
116 beginning of the kernel.  You should not need to look at this code or
117 modify it.
118
119 @item kernel.lds.S
120 The linker script used to link the kernel.  Sets the load address of
121 the kernel and arranges for @file{start.S} to be at the very beginning
122 of the kernel image.  Again, you should not need to look at this code
123 or modify it, but it's here in case you're curious.
124
125 @item start.S
126 Jumps to @func{main}.
127
128 @item init.c
129 @itemx init.h
130 Kernel initialization, including @func{main}, the kernel's ``main
131 program.''  You should look over @func{main} at least to see what
132 gets initialized.
133
134 @item thread.c
135 @itemx thread.h
136 Basic thread support.  Much of your work will take place in these
137 files.  @file{thread.h} defines @struct{thread}, which you will
138 modify in the first three projects.
139
140 @item switch.S
141 @itemx switch.h
142 Assembly language routine for switching threads.  Already discussed
143 above.
144
145 @item palloc.c
146 @itemx palloc.h
147 Page allocator, which hands out system memory in multiples of 4 kB
148 pages.
149
150 @item malloc.c
151 @itemx malloc.h
152 A very simple implementation of @func{malloc} and @func{free} for
153 the kernel.
154
155 @item interrupt.c
156 @itemx interrupt.h
157 Basic interrupt handling and functions for turning interrupts on and
158 off.
159
160 @item intr-stubs.S
161 @itemx intr-stubs.h
162 Assembly code for low-level interrupt handling.
163
164 @item synch.c
165 @itemx synch.h
166 Basic synchronization primitives: semaphores, locks, and condition
167 variables.  You will need to use these for synchronization through all
168 four projects.
169
170 @item test.c
171 @itemx test.h
172 Test code.  For project 1, you will replace this file with your test
173 cases.
174
175 @item io.h
176 Functions for I/O port access.  This is mostly used by source code in
177 the @file{devices} directory that you won't have to touch.
178
179 @item mmu.h
180 Functions and macros related to memory management, including page
181 directories and page tables.  This will be more important to you in
182 project 3.  For now, you can ignore it.
183 @end table
184
185 @menu
186 * devices code::                
187 * lib files::                   
188 @end menu
189
190 @node devices code
191 @subsection @file{devices} code
192
193 The basic threaded kernel also includes these files in the
194 @file{devices} directory:
195
196 @table @file
197 @item timer.c
198 @itemx timer.h
199 System timer that ticks, by default, 100 times per second.  You will
200 modify this code in Problem 1-1.
201
202 @item vga.c
203 @itemx vga.h
204 VGA display driver.  Responsible for writing text to the screen.
205 You should have no need to look at this code.  @func{printf} will
206 call into the VGA display driver for you, so there's little reason to
207 call this code yourself.
208
209 @item serial.c
210 @itemx serial.h
211 Serial port driver.  Again, @func{printf} calls this code for you,
212 so you don't need to do so yourself.  Feel free to look through it if
213 you're curious.
214
215 @item disk.c
216 @itemx disk.h
217 Supports reading and writing sectors on up to 4 IDE disks.  This won't
218 actually be used until project 2.
219
220 @item intq.c
221 @itemx intq.h
222 Interrupt queue, for managing a circular queue that both kernel
223 threads and interrupt handlers want to access.  Used by the keyboard
224 and serial drivers.
225 @end table
226
227 @node lib files
228 @subsection @file{lib} files
229
230 Finally, @file{lib} and @file{lib/kernel} contain useful library
231 routines.  (@file{lib/user} will be used by user programs, starting in
232 project 2, but it is not part of the kernel.)  Here's a few more
233 details:
234
235 @table @file
236 @item ctype.h
237 @itemx inttypes.h
238 @itemx limits.h
239 @itemx stdarg.h
240 @itemx stdbool.h
241 @itemx stddef.h
242 @itemx stdint.h
243 @itemx stdio.c
244 @itemx stdio.h
245 @itemx stdlib.c
246 @itemx stdlib.h
247 @itemx string.c
248 @itemx string.h
249 Implementation of the standard C library.  @xref{C99}, for information
250 on a few recently introduced pieces of the C library that you might
251 not have encountered before.  @xref{Unsafe String Functions}, for
252 information on what's been intentionally left out for safety.
253
254 @item debug.c
255 @itemx debug.h
256 Functions and macros to aid debugging.  @xref{Debugging Tools}, for
257 more information.
258
259 @item random.c
260 @itemx random.h
261 Pseudo-random number generator.
262
263 @item round.h
264 Macros for rounding.
265
266 @item syscall-nr.h
267 System call numbers.  Not used until project 2.
268
269 @item kernel/list.c
270 @itemx kernel/list.h
271 Doubly linked list implementation.  Used all over the Pintos code, and
272 you'll probably want to use it a few places yourself in project 1.
273
274 @item kernel/bitmap.c
275 @itemx kernel/bitmap.h
276 Bitmap implementation.  You can use this in your code if you like, but
277 you probably won't have any need for project 1.
278
279 @item kernel/hash.c
280 @itemx kernel/hash.h
281 Hash table implementation.  Likely to come in handy for project 3.
282
283 @item kernel/console.c
284 @itemx kernel/console.h
285 Implements @func{printf} and a few other functions.
286 @end table
287
288 @node Debugging versus Testing
289 @section Debugging versus Testing
290
291 When you're debugging code, it's useful to be able to be able to run a
292 program twice and have it do exactly the same thing.  On second and
293 later runs, you can make new observations without having to discard or
294 verify your old observations.  This property is called
295 ``reproducibility.''  The simulator we use, Bochs, can be set up for
296 reproducibility, and that's the way that @command{pintos} invokes it
297 by default.
298
299 Of course, a simulation can only be reproducible from one run to the
300 next if its input is the same each time.  For simulating an entire
301 computer, as we do, this means that every part of the computer must be
302 the same.  For example, you must use the same disks, the same version
303 of Bochs, and you must not hit any keys on the keyboard (because you
304 could not be sure to hit them at exactly the same point each time)
305 during the runs.
306
307 While reproducibility is useful for debugging, it is a problem for
308 testing thread synchronization, an important part of this project.  In
309 particular, when Bochs is set up for reproducibility, timer interrupts
310 will come at perfectly reproducible points, and therefore so will
311 thread switches.  That means that running the same test several times
312 doesn't give you any greater confidence in your code's correctness
313 than does running it only once.
314
315 So, to make your code easier to test, we've added a feature, called
316 ``jitter,'' to Bochs, that makes timer interrupts come at random
317 intervals, but in a perfectly predictable way.  In particular, if you
318 invoke @command{pintos} with the option @option{-j @var{seed}}, timer
319 interrupts will come at irregularly spaced intervals.  Within a single
320 @var{seed} value, execution will still be reproducible, but timer
321 behavior will change as @var{seed} is varied.  Thus, for the highest
322 degree of confidence you should test your code with many seed values.
323
324 On the other hand, when Bochs runs in reproducible mode, timings are not
325 realistic, meaning that a ``one-second'' delay may be much shorter or
326 even much longer than one second.  You can invoke @command{pintos} with
327 a different option, @option{-r}, to make it set up Bochs for realistic
328 timings, in which a one-second delay should take approximately one
329 second of real time.  Simulation in real-time mode is not reproducible,
330 and options @option{-j} and @option{-r} are mutually exclusive.
331
332 @node Tips
333 @section Tips
334
335 @itemize @bullet
336 @item
337 There should be no busy waiting in any of your solutions to this
338 assignment.  We consider a tight loop that calls @func{thread_yield}
339 to be one form of busy waiting.
340
341 @item
342 Proper synchronization is an important part of the solutions to these
343 problems.  It is tempting to synchronize all your code by turning off
344 interrupts with @func{intr_disable} or @func{intr_set_level}, because
345 this eliminates concurrency and thus the possibility for race
346 conditions, but @strong{don't}.  Instead, use semaphores, locks, and
347 condition variables to solve the bulk of your synchronization
348 problems.  Read the tour section on synchronization
349 (@pxref{Synchronization}) or the comments in @file{threads/synch.c} if
350 you're unsure what synchronization primitives may be used in what
351 situations.
352
353 You might run into a few situations where interrupt disabling is the
354 best way to handle synchronization.  If so, you need to explain your
355 rationale in your design documents.  If you're unsure whether a given
356 situation justifies disabling interrupts, talk to the TAs, who can
357 help you decide on the right thing to do.
358
359 Disabling interrupts can be useful for debugging, if you want to make
360 sure that a section of code is not interrupted.  You should remove
361 debugging code before turning in your project.
362
363 @item
364 All parts of this assignment are required if you intend to earn full
365 credit on this project.  However, some will be more important in
366 future projects:
367
368 @itemize @minus
369 @item
370 Problem 1-1 (Alarm Clock) could be handy for later projects, but it is
371 not strictly required.
372
373 @item
374 Problem 1-2 (Join) will be needed for future projects.  We don't give
375 out solutions, so to avoid extra work later you should make sure that
376 your implementation of @func{thread_join} works correctly.
377
378 @item
379 Problems 1-3 and 1-4 won't be needed for later projects.
380 @end itemize
381
382 @item
383 Problem 1-4 (MLFQS) builds on the features you implement in Problem
384 1-3.  You should have Problem 1-3 fully working before you begin to
385 tackle Problem 1-4.
386
387 @item
388 In the past, many groups divided the assignment into pieces, then each
389 group member worked on his or her piece until just before the
390 deadline, at which time the group reconvened to combine their code and
391 submit.  @strong{This is a bad idea.  We do not recommend this
392 approach.}  Groups that do this often find that two changes conflict
393 with each other, requiring lots of last-minute debugging.  Some groups
394 who have done this have turned in code that did not even successfully
395 boot.
396
397 Instead, we recommend integrating your team's changes early and often,
398 using a source code control system such as CVS (@pxref{CVS}) or a
399 group collaboration site such as SourceForge (@pxref{SourceForge}).
400 This is less likely to produce surprises, because everyone can see
401 everyone else's code as it is written, instead of just when it is
402 finished.  These systems also make it possible to review changes and,
403 when a change introduces a bug, drop back to working versions of code.
404
405 @item
406 You should expect to run into bugs that you simply don't understand
407 while working on this and subsequent projects.  When you do, go back
408 and reread the appendix on debugging tools, which is filled with
409 useful debugging tips that should help you to get back up to speed
410 (@pxref{Debugging Tools}).  Be sure to read the section on backtraces
411 (@pxref{Backtraces}), which will help you to get the most out of every
412 kernel panic or assertion failure.
413 @end itemize
414
415 @node Problem 1-1 Alarm Clock
416 @section Problem 1-1: Alarm Clock
417
418 Improve the implementation of the timer device defined in
419 @file{devices/timer.c} by reimplementing @func{timer_sleep}.
420 Threads call @code{timer_sleep(@var{x})} to suspend execution until
421 time has advanced by at least @w{@var{x} timer ticks}.  This is
422 useful for threads that operate in real-time, for example, for
423 blinking the cursor once per second.  There is no requirement that
424 threads start running immediately after waking up; just put them on
425 the ready queue after they have waited for approximately the right
426 amount of time.
427
428 A working implementation of this function is provided.  However, the
429 version provided is poor, because it ``busy waits,'' that is, it spins
430 in a tight loop checking the current time until the current time has
431 advanced far enough.  This is undesirable because it wastes time that
432 could potentially be used more profitably by another thread.  Your
433 solution should not busy wait.
434
435 The argument to @func{timer_sleep} is expressed in timer ticks, not in
436 milliseconds or any another unit.  There are @code{TIMER_FREQ} timer
437 ticks per second, where @code{TIMER_FREQ} is a macro defined in
438 @code{devices/timer.h}.
439
440 Separate functions @func{timer_msleep}, @func{timer_usleep}, and
441 @func{timer_nsleep} do exist for sleeping a specific number of
442 milliseconds, microseconds, or nanoseconds, respectively, but these will
443 call @func{timer_sleep} automatically when necessary.  You do not need
444 to modify them.
445
446 If your delays seem too short or too long, reread the explanation of the
447 @option{-r} option to @command{pintos} (@pxref{Debugging versus
448 Testing}).
449
450 @node Problem 1-2 Join
451 @section Problem 1-2: Join
452
453 Implement @code{thread_join(tid_t)} in @file{threads/thread.c}.  There
454 is already a prototype for it in @file{threads/thread.h}, which you
455 should not change.  This function causes the currently running thread
456 to block until the thread whose thread id is passed as an argument
457 exits.  If @var{A} is the running thread and @var{B} is the argument,
458 then we say that ``@var{A} joins @var{B}.''
459
460 Incidentally, we don't use @code{struct thread *} as
461 @func{thread_join}'s parameter type because a thread pointer is not
462 unique over time.  That is, when a thread dies, its memory may be,
463 whether immediately or much later, reused for another thread.  If
464 thread @var{A} over time had two children @var{B} and @var{C} that
465 were stored at the same address, then @code{thread_join(@var{B})} and
466 @code{thread_join(@var{C})} would be ambiguous.  Introducing a thread
467 id or @dfn{tid}, represented by type @code{tid_t}, that is
468 intentionally unique over time solves the problem.  The provided code
469 uses an @code{int} for @code{tid_t}, but you may decide you prefer to
470 use some other type.
471
472 The model for @func{thread_join} is the @command{wait} system call
473 in Unix-like systems.  (Try reading the manpages.)  That system call
474 can only be used by a parent process to wait for a child's death.  You
475 should implement @func{thread_join} to have the same restriction.
476 That is, a thread may only join its immediate children.
477
478 A thread need not ever be joined.  Your solution should properly free
479 all of a thread's resources, including its @struct{thread},
480 whether it is ever joined or not, and regardless of whether the child
481 exits before or after its parent.  That is, a thread should be freed
482 exactly once in all cases.
483
484 Joining a given thread is idempotent.  That is, joining a thread T
485 multiple times is equivalent to joining it once, because T has already
486 exited at the time of the later joins.  Thus, joins on T after the
487 first should return immediately.
488
489 Calling @func{thread_join} on an thread that is not the caller's
490 child should cause the caller to return immediately.  For this purpose,
491 children are not inherited, that is, if @var{A} has child @var{B} and
492 @var{B} has child @var{C}, then @var{A} always returns immediately
493 should it try to join @var{C}, even if @var{B} is dead.
494
495 Consider all the ways a join can occur: nested joins (@var{A} joins
496 @var{B}, then @var{B} joins @var{C}), multiple joins (@var{A} joins
497 @var{B}, then @var{A} joins @var{C}), and so on.  Does your join work
498 if @func{thread_join} is called on a thread that has not yet been
499 scheduled for the first time?  You should handle all of these cases.
500 Write test code that demonstrates the cases your join works for.
501
502 Be careful to program this function correctly.  You will need its
503 functionality for project 2.
504
505 Once you've implemented @func{thread_join}, define
506 @code{THREAD_JOIN_IMPLEMENTED} in @file{constants.h}.
507 @xref{Conditional Compilation}, for more information.
508
509 @node Problem 1-3 Priority Scheduling
510 @section Problem 1-3: Priority Scheduling
511
512 Implement priority scheduling in Pintos.  Priority scheduling is a key
513 building block for real-time systems.  Implement functions
514 @func{thread_set_priority} to set the priority of the running thread
515 and @func{thread_get_priority} to get the running thread's priority.
516 (This API only allows a thread to examine and modify its own
517 priority.)  There are already prototypes for these functions in
518 @file{threads/thread.h}, which you should not change.
519
520 Thread priority ranges from @code{PRI_MIN} (0) to @code{PRI_MAX} (59).
521 The initial thread priority is passed as an argument to
522 @func{thread_create}.  If there's no reason to choose another
523 priority, use @code{PRI_DEFAULT} (29).  The @code{PRI_} macros are
524 defined in @file{threads/thread.h}, and you should not change their
525 values.
526
527 When a thread is added to the ready list that has a higher priority
528 than the currently running thread, the current thread should
529 immediately yield the processor to the new thread.  Similarly, when
530 threads are waiting for a lock, semaphore or condition variable, the
531 highest priority waiting thread should be woken up first.  A thread
532 may raise or lower its own priority at any time, but lowering its
533 priority such that it no longer has the highest priority must cause it
534 to immediately yield the CPU.
535
536 One issue with priority scheduling is ``priority inversion'': if a
537 high priority thread needs to wait for a low priority thread (for
538 instance, for a lock held by a low priority thread, or in
539 @func{thread_join} for a thread to complete), and a middle priority
540 thread is on the ready list, then the high priority thread will never
541 get the CPU because the low priority thread will not get any CPU time.
542 A partial fix for this problem is to have the waiting thread
543 ``donate'' its priority to the low priority thread while it is holding
544 the lock, then recall the donation once it has acquired the lock.
545 Implement this fix.
546
547 You will need to account for all different orders in which priority
548 donation and inversion can occur.  Be sure to handle multiple
549 donations, in which multiple priorities are donated to a thread.  You
550 must also handle nested donation: given high, medium, and low priority
551 threads @var{H}, @var{M}, and @var{L}, respectively, if @var{H} is
552 waiting on a lock that @var{M} holds and @var{M} is waiting on a lock
553 that @var{L} holds, then both @var{M} and @var{L} should be boosted to
554 @var{H}'s priority.
555
556 You only need to implement priority donation when a thread is waiting
557 for a lock held by a lower-priority thread.  You do not need to
558 implement this fix for semaphores, condition variables, or joins,
559 although you are welcome to do so.  However, you do need to implement
560 priority scheduling in all cases.
561
562 @node Problem 1-4 Advanced Scheduler
563 @section Problem 1-4: Advanced Scheduler
564
565 Implement Solaris's multilevel feedback queue scheduler (MLFQS) to
566 reduce the average response time for running jobs on your system.
567 @xref{Multilevel Feedback Scheduling}, for a detailed description of
568 the MLFQS requirements.
569
570 Demonstrate that your scheduling algorithm reduces response time
571 relative to the original Pintos scheduling algorithm (round robin) for
572 at least one workload of your own design (i.e.@: in addition to the
573 provided test).
574
575 You must write your code so that we can turn the MLFQS on and off at
576 compile time.  By default, it must be off, but we must be able to turn
577 it on by inserting the line @code{#define MLFQS 1} in
578 @file{constants.h}.  @xref{Conditional Compilation}, for details.
579
580 @node Threads FAQ
581 @section FAQ
582
583 @enumerate 1
584 @item
585 @b{I am adding a new @file{.h} or @file{.c} file.  How do I fix the
586 @file{Makefile}s?}@anchor{Adding c or h Files}
587
588 To add a @file{.c} file, edit the top-level @file{Makefile.build}.
589 You'll want to add your file to variable @samp{@var{dir}_SRC}, where
590 @var{dir} is the directory where you added the file.  For this
591 project, that means you should add it to @code{threads_SRC}, or
592 possibly @code{devices_SRC} if you put in the @file{devices}
593 directory.  Then run @code{make}.  If your new file doesn't get
594 compiled, run @code{make clean} and then try again.
595
596 When you modify the top-level @file{Makefile.build}, the modified
597 version should be automatically copied to
598 @file{threads/build/Makefile} when you re-run make.  The opposite is
599 not true, so any changes will be lost the next time you run @code{make
600 clean} from the @file{threads} directory.  Therefore, you should
601 prefer to edit @file{Makefile.build} (unless your changes are meant to
602 be truly temporary).
603
604 There is no need to edit the @file{Makefile}s to add a @file{.h} file.
605
606 @item
607 @b{How do I write my test cases?}
608
609 Test cases should be replacements for the existing @file{test.c}
610 file.  Put them in a @file{threads/testcases} directory.
611 @xref{TESTCASE}, for more information.
612
613 @item
614 @b{Why can't I disable interrupts?}
615
616 Turning off interrupts should only be done for short amounts of time,
617 or else you end up losing important things such as disk or input
618 events.  Turning off interrupts also increases the interrupt handling
619 latency, which can make a machine feel sluggish if taken too far.
620 Therefore, in general, setting the interrupt level should be used
621 sparingly.  Also, any synchronization problem can be easily solved by
622 turning interrupts off, since while interrupts are off, there is no
623 concurrency, so there's no possibility for race conditions.
624
625 To make sure you understand concurrency well, we are discouraging you
626 from taking this shortcut at all in your solution.  If you are unable
627 to solve a particular synchronization problem with semaphores, locks,
628 or conditions, or think that they are inadequate for a particular
629 reason, you may turn to disabling interrupts.  If you want to do this,
630 we require in your design document a complete justification and
631 scenario (i.e.@: exact sequence of events) to show why interrupt
632 manipulation is the best solution.  If you are unsure, the TAs can
633 help you determine if you are using interrupts too haphazardly.  We
634 want to emphasize that there are only limited cases where this is
635 appropriate.
636
637 You might find @file{devices/intq.h} and its users to be an
638 inspiration or source of rationale.
639
640 @item
641 @b{Where might interrupt-level manipulation be appropriate?}
642
643 You might find it necessary in some solutions to the Alarm problem.
644
645 You might want it at one small point for the priority scheduling
646 problem.  Note that it is not required to use interrupts for these
647 problems.  There are other, equally correct solutions that do not
648 require interrupt manipulation.  However, if you do manipulate
649 interrupts and @strong{correctly and fully document it} in your design
650 document, we will allow limited use of interrupt disabling.
651
652 @item
653 @b{What does ``warning: no previous prototype for `@var{function}''
654 mean?}
655
656 It means that you defined a non-@code{static} function without
657 preceding it by a prototype.  Because non-@code{static} functions are
658 intended for use by other @file{.c} files, for safety they should be
659 prototyped in a header file included before their definition.  To fix
660 the problem, add a prototype in a header file that you include, or, if
661 the function isn't actually used by other @file{.c} files, make it
662 @code{static}.
663 @end enumerate
664
665 @menu
666 * Problem 1-1 Alarm Clock FAQ::  
667 * Problem 1-2 Join FAQ::        
668 * Problem 1-3 Priority Scheduling FAQ::  
669 * Problem 1-4 Advanced Scheduler FAQ::  
670 @end menu
671
672 @node Problem 1-1 Alarm Clock FAQ
673 @subsection Problem 1-1: Alarm Clock FAQ
674
675 @enumerate 1
676 @item
677 @b{Why can't I use most synchronization primitives in an interrupt
678 handler?}
679
680 As you've discovered, you cannot sleep in an external interrupt
681 handler.  Since many lock, semaphore, and condition variable functions
682 attempt to sleep, you won't be able to call those in
683 @func{timer_interrupt}.  You may still use those that never sleep.
684
685 Having said that, you need to make sure that global data does not get
686 updated by multiple threads simultaneously executing
687 @func{timer_sleep}.  Here are some pieces of information to think
688 about:
689
690 @enumerate a
691 @item
692 Interrupts are turned off while @func{timer_interrupt} runs.  This
693 means that @func{timer_interrupt} will not be interrupted by a
694 thread running in @func{timer_sleep}.
695
696 @item
697 A thread in @func{timer_sleep}, however, can be interrupted by a
698 call to @func{timer_interrupt}, except when that thread has turned
699 off interrupts.
700
701 @item
702 Examples of synchronization mechanisms have been presented in lecture.
703 Going over these examples should help you understand when each type is
704 useful or needed.  @xref{Synchronization}, for specific information
705 about synchronization in Pintos.
706 @end enumerate
707
708 @item
709 @b{What about timer overflow due to the fact that times are defined as
710 integers? Do I need to check for that?}
711
712 Don't worry about the possibility of timer values overflowing.  Timer
713 values are expressed as signed 63-bit numbers, which at 100 ticks per
714 second should be good for almost 2,924,712,087 years.
715
716 @item
717 @b{The test program mostly works but reports a few out-of-order
718 wake ups.  I think it's a problem in the test program.  What gives?}
719 @anchor{Out of Order 1-1}
720
721 This test is inherently full of race conditions.  On a real system it
722 wouldn't work perfectly all the time either.  There are a few ways you
723 can help it work more reliably:
724
725 @itemize @bullet
726 @item
727 Make time slices longer by increasing @code{TIME_SLICE} in
728 @file{timer.c} to a large value, such as 100.
729
730 @item
731 Make the timer tick more slowly by decreasing @code{TIMER_FREQ} in
732 @file{timer.h} to its minimum value of 19.
733 @end itemize
734
735 The former two changes are only desirable for testing problem 1-1 and
736 possibly 1-3.  You should revert them before working on other parts
737 of the project or turn in the project.
738
739 @item
740 @b{Should @file{p1-1.c} be expected to work with the MLFQS turned on?}
741
742 No.  The MLFQS will adjust priorities, changing thread ordering.
743 @end enumerate
744
745 @node Problem 1-2 Join FAQ
746 @subsection Problem 1-2: Join FAQ
747
748 @enumerate 1
749 @item
750 @b{Am I correct to assume that once a thread is deleted, it is no
751 longer accessible by the parent (i.e.@: the parent can't call
752 @code{thread_join(child)})?}
753
754 A parent joining a child that has completed should be handled
755 gracefully and should act as a no-op.
756 @end enumerate
757
758 @node Problem 1-3 Priority Scheduling FAQ
759 @subsection Problem 1-3: Priority Scheduling FAQ
760
761 @enumerate 1
762 @item
763 @b{Doesn't the priority scheduling lead to starvation? Or do I have to
764 implement some sort of aging?}
765
766 It is true that strict priority scheduling can lead to starvation
767 because thread may not run if a higher-priority thread is runnable.
768 In this problem, don't worry about starvation or any sort of aging
769 technique.  Problem 4 will introduce a mechanism for dynamically
770 changing thread priorities.
771
772 This sort of scheduling is valuable in real-time systems because it
773 offers the programmer more control over which jobs get processing
774 time.  High priorities are generally reserved for time-critical
775 tasks. It's not ``fair,'' but it addresses other concerns not
776 applicable to a general-purpose operating system.
777
778 @item
779 @b{After a lock has been released, does the program need to switch to
780 the highest priority thread that needs the lock (assuming that its
781 priority is higher than that of the current thread)?}
782
783 When a lock is released, the highest priority thread waiting for that
784 lock should be unblocked and put on the ready to run list.  The
785 scheduler should then run the highest priority thread on the ready
786 list.
787
788 @item
789 @b{If a thread calls @func{thread_yield} and then it turns out that
790 it has higher priority than any other threads, does the high-priority
791 thread continue running?}
792
793 Yes.  If there is a single highest-priority thread, it continues
794 running until it blocks or finishes, even if it calls
795 @func{thread_yield}.
796
797 @item
798 @b{If the highest priority thread is added to the ready to run list it
799 should start execution immediately.  Is it immediate enough if I
800 wait until next timer interrupt occurs?}
801
802 The highest priority thread should run as soon as it is runnable,
803 preempting whatever thread is currently running.
804
805 @item
806 @b{What happens to the priority of the donating thread?  Do the priorities
807 get swapped?}
808
809 No.  Priority donation only changes the priority of the low-priority
810 thread.  The donating thread's priority stays unchanged.  Also note
811 that priorities aren't additive: if thread A (with priority 5) donates
812 to thread B (with priority 3), then B's new priority is 5, not 8.
813
814 @item 
815 @b{Can a thread's priority be changed while it is sitting on the ready
816 queue?}
817
818 Yes.  Consider this case: low-priority thread L currently has a lock
819 that high-priority thread H wants.  H donates its priority to L (the
820 lock holder).  L finishes with the lock, and then loses the CPU and is
821 moved to the ready queue.  Now L's old priority is restored while it
822 is in the ready queue.
823
824 @item
825 @b{Can a thread's priority change while it is sitting on the queue of a
826 semaphore?}
827
828 Yes.  Same scenario as above except L gets blocked waiting on a new
829 lock when H restores its priority.
830
831 @item
832 @b{Why is @file{p1-3.c}'s FIFO test skipping some threads?  I know my
833 scheduler is round-robin'ing them like it's supposed to.   Our output
834 starts out okay, but toward the end it starts getting out of order.}
835
836 The usual problem is that the serial output buffer fills up.  This is
837 causing serial_putc() to block in thread @var{A}, so that thread
838 @var{B} is scheduled.  Thread @var{B} immediately tries to do output
839 of its own and blocks on the serial lock (which is held by thread
840 @var{A}).  Now that we've wasted some time in scheduling and locking,
841 typically some characters have been drained out of the serial buffer
842 by the interrupt handler, so thread @var{A} can continue its output.
843 After it finishes, though, some other thread (not @var{B}) is
844 scheduled, because thread @var{B} was already scheduled while we
845 waited for the buffer to drain.
846
847 There's at least one other possibility.  Context switches are being
848 invoked by the test when it explicitly calls @func{thread_yield}.
849 However, the time slice timer is still alive and so, every tick (by
850 default), a thread gets switched out (caused by @func{timer_interrupt}
851 calling @func{intr_yield_on_return}) before it gets a chance to run
852 @func{printf}, effectively skipping it.  If we use a different jitter
853 value, the same behavior is seen where a thread gets started and
854 switched out completely.
855
856 Normally you can fix these problems using the same techniques
857 suggested on problem 1-1 (@pxref{Out of Order 1-1}).
858
859 @item
860 @b{What happens when a thread is added to the ready list which has
861 higher priority than the currently running thread?}
862
863 The correct behavior is to immediately yield the processor.  Your
864 solution must act this way.
865
866 @item
867 @b{What should @func{thread_get_priority} return in a thread while
868 its priority has been increased by a donation?}
869
870 The higher (donated) priority.
871
872 @item
873 @b{Should @file{p1-3.c} be expected to work with the MLFQS turned on?}
874
875 No.  The MLFQS will adjust priorities, changing thread ordering.
876
877 @item
878 @b{@func{printf} in @func{sema_up} or @func{sema_down} makes the
879 system reboot!}
880
881 Yes.  These functions are called before @func{printf} is ready to go.
882 You could add a global flag initialized to false and set it to true
883 just before the first @func{printf} in @func{main}.  Then modify
884 @func{printf} itself to return immediately if the flag isn't set.
885 @end enumerate
886
887 @node Problem 1-4 Advanced Scheduler FAQ
888 @subsection Problem 1-4: Advanced Scheduler FAQ
889
890 @enumerate 1
891 @item
892 @b{What is the interval between timer interrupts?}
893
894 Timer interrupts occur @code{TIMER_FREQ} times per second.  You can
895 adjust this value by editing @file{devices/timer.h}.  The default is
896 100 Hz.
897
898 You can also adjust the number of timer ticks per time slice by
899 modifying @code{TIME_SLICE} in @file{devices/timer.c}.
900
901 @item
902 @b{Do I have to modify the dispatch table?}
903
904 No, although you are allowed to. It is possible to complete
905 this problem (i.e.@: demonstrate response time improvement)
906 without doing so.
907
908 @item
909 @b{When the scheduler changes the priority of a thread, how does this
910 affect priority donation?}
911
912 Short (official) answer: Don't worry about it. Your priority donation
913 code may assume static priority assignment.
914
915 Longer (unofficial) opinion: If you wish to take this into account,
916 however, your design may end up being ``cleaner.''  You have
917 considerable freedom in what actually takes place. I believe what
918 makes the most sense is for scheduler changes to affect the
919 ``original'' (non-donated) priority.  This change may actually be
920 masked by the donated priority.  Priority changes should only
921 propagate with donations, not ``backwards'' from donees to donors.
922
923 @item
924 @b{What is meant by ``static priority''?}
925
926 Once thread A has donated its priority to thread B, if thread A's
927 priority changes (due to the scheduler) while the donation still
928 exists, you do not have to change thread B's donated priority.
929 However, you are free to do so.
930
931 @item
932 @b{Do I have to make my dispatch table user-configurable?}
933
934 No.  Hard-coding the dispatch table values is fine.
935 @end enumerate