From 1e70978fdf2e3dd9a3c2153dab259bc689fd7d31 Mon Sep 17 00:00:00 2001
From: Ben Pfaff R=l3DQpy&agEBy{4=P2bsJuJSvM7d0Naik-FcF&Nyg
zr%YTp!H}6N`$OJX(Hz?-sOo(&)XgRHYF*v)$rgzdL<(O*mk2}f?nxEuS8ug52E8+W
z@orOHU-w4Z{Rf^EhR@Nh-<*6l+Y-(`t;}wa|ME(KKzxna5ziDsq>ODcX3WrxF!Vpm
zUS7VGwcH+p{M4Z7b1wB{oB+|b>y=e5xct+sO|Q#g0Y4&iQokC-tLeDjJ@uuO(q~M|
zU~Us0YpFiRVwmTVsJY}=mQ}rt&2?<}OM)EAsZOhYF;eQKmGI8;y
DEaPEQzyQB8+x53O`P0Rfl*
zW*YhQBw#
ut01EWKg-(4pX>w*6AQ@
zxuElnaJh;m6dE1gzbA`Ehnz!opcfZM8%LWvCiZ0a&=ZY9^Rcqup;YK5tc6
OPl_dG-E?QG1NryrZnek
zA3_IdUkC}^DkKn_ngvQh@
T5f#U"opJd;oT -4:II*";!&H:cO-%";$WeJHR2&Uk0a[KQ6XI$%k+JdU6d7NhZ#S;Y#s5q7N+IB9oNg(YPD-rre" eE -O?jK*=X!Eg"??CG!XNl0&d/c!$F/"b+JYPc&4!2rjD\%nU(B]g5_026S-=./,Sq\W -SKNM/*$C%/Jd LK;9t[s";8aG -+B/pn"eEdUL99\gUcgImC')fh+ID:T+Fse`X8#+DYU#<$G(n#X5ls<'cp\F3:k)"Y -5nVIL1,s##"G-tFNYEUi!rmoZ+UB7F_FPf83'ef$=`L5C+[KLfdKgD;&B#1$dRYYi -&G1Q>M!-BKKFf7m&f_c/(%jirNY2I+TY2T^5nAX3#U/t.O<@,>8HK5_P!K0AJHX'X -00pnFWX'70JHX'X0*DhP"Wp#U&2-Qc82!73#U"oP&d`kTNa[0(63quB+YQBUJg6r% -":-:q8HK//qPZ[jTRd4[HmTg)JdWa2)PFT/59lhQNg%Ckq4!4i7QCpOaDHr)CiUJ) -OP:b0d/F"Elp(O?s8O3R)\%&o80Fl71uQ_J:(IIbLHH-tZClrB)E:/G%9J3]TRd^E -MKBCtF:h9PMKgO<4 ,+hHG-QOQRF\0qo3XmJ:ddXml^Bc"PJNs1O?6;Kr?`3o# -lLGC&GVG#&L62/eI`#TeCc3+Qp)=,?2B*/LAfD2.6Qe+=*/7;Pj,QBUa>AoKq&Hmu -Km3@RD`E`Z=QOg08&D@..Lfd^Ab2<1i.<2H8.\J4r/ZF85ob=[!XXOr&b&(?YYW@% -"nipcr-Jo4s'bq9Da9GEs6rN#5`q)!hLP_3o9eLQJe3JDrX^7B@"eXb#X/eC_6,!c -6']N,O7&?j^]XX&~> -EI -Q -BT -286.08 414 TD -0 0 0 rg -/N8 12 Tf --0.0086 Tc -0.0326 Tw -(Figure 2)Tj -ET -PDFVars/TermAll get exec end end -userdict /pgsave get restore -showpage -%%PageTrailer -%%EndPage -%%Trailer -%%DocumentProcessColors: Cyan Magenta Yellow Black -%%EOF diff --git a/doc/mlfqs.texi b/doc/mlfqs.texi index 253f91b..2ac1780 100644 --- a/doc/mlfqs.texi +++ b/doc/mlfqs.texi @@ -356,7 +356,12 @@ consumes its timeslice, its priority is lowered about ten levels Since the coarse job runs more frequently, it drops in priority at a faster rate than the other two jobs. +@ifnottex @image{mlfqs1} +@end ifnottex +@iftex +@image{mlfqs1, 3in} +@end iftex The impact of this policy on the relative execution times of the three applications is shown in the next graph below. Because the coarse @@ -364,7 +369,12 @@ application acquires more CPU time, it finishes its work earlier than the other applications, even though all three jobs require the same amount of time in a dedicated environment. +@ifnottex @image{mlfqs2} +@end ifnottex +@iftex +@image{mlfqs2, 3in} +@end iftex @node Project Requirements @section Project Requirements diff --git a/doc/projects.texi b/doc/pintos.texi similarity index 93% rename from doc/projects.texi rename to doc/pintos.texi index b5b08f5..1dd83fd 100644 --- a/doc/projects.texi +++ b/doc/pintos.texi @@ -37,7 +37,9 @@ @end macro @titlepage -@title Pintos Projects +@title Pintos +@author by Ben Pfaff +@author based on past contributions of CS 140 TAs @end titlepage @contents diff --git a/doc/threads.texi b/doc/threads.texi index 04d48d1..63aed69 100644 --- a/doc/threads.texi +++ b/doc/threads.texi @@ -15,9 +15,8 @@ Before you read the description of this project, you should read all of the following sections: @ref{Introduction}, @ref{Coding Standards}, @ref{Project Documentation}, @ref{Debugging Tools}, and @ref{Development Tools}. You should at least skim the material in -@ref{Threads Tour}, but there's no need to fret over the details. To -complete this project you will also need to read @ref{Multilevel -Feedback Scheduling}. +@ref{Threads Tour}. To complete this project you will also need to +read @ref{Multilevel Feedback Scheduling}. @menu * Understanding Threads:: @@ -131,7 +130,7 @@ gets initialized. @item thread.c @itemx thread.h Basic thread support. Much of your work will take place in these -files. @file{thread.h} defines @code{struct thread}, which you will +files. @file{thread.h} defines @struct{thread}, which you will modify in the first three projects. @item switch.S @@ -407,7 +406,7 @@ should implement @func{thread_join} to have the same restriction. That is, a thread may only join its immediate children. A thread need not ever be joined. Your solution should properly free -all of a thread's resources, including its @code{struct thread}, +all of a thread's resources, including its @struct{thread}, whether it is ever joined or not, and regardless of whether the child exits before or after its parent. That is, a thread should be freed exactly once in all cases. diff --git a/doc/tour.texi b/doc/tour.texi index ae9e74e..ee90cca 100644 --- a/doc/tour.texi +++ b/doc/tour.texi @@ -204,7 +204,7 @@ threads to continue running. @end menu @node struct thread -@subsection @struct{thread} +@subsection @code{struct thread} The main Pintos data structure for threads is @struct{thread}, declared in @file{threads/thread.h}. @struct{thread} has these @@ -283,6 +283,7 @@ memory. The rest of the page is used for the thread's stack, which grows downward from the end of the page. It looks like this: @example +@group 4 kB +---------------------------------+ | kernel stack | | | | @@ -304,6 +305,7 @@ grows downward from the end of the page. It looks like this: | name | | status | 0 kB +---------------------------------+ +@end group @end example The upshot of this is twofold. First, @struct{thread} must not be @@ -346,8 +348,8 @@ called early in Pintos initialization. Called by @func{main} to start the scheduler. Creates the idle thread, that is, the thread that is scheduled when no other thread is ready. Then enables interrupts, which enables the scheduler because -processes are rescheduled in the return path from the timer -interrupt. FIXME +processes are rescheduled on return from the timer interrupt, using +@func{intr_yield_on_return} (@pxref{External Interrupt Handling}). @end deftypefun @deftypefun void thread_create (const char *@var{name}, int @var{priority}, thread_func *@var{func}, void *@var{aux}) diff --git a/doc/userprog.texi b/doc/userprog.texi index 72ab256..da9fe3d 100644 --- a/doc/userprog.texi +++ b/doc/userprog.texi @@ -478,25 +478,25 @@ because there's no way to return an error code from a memory access. Therefore, for those who want to try the latter technique, we'll provide a little bit of helpful code: -@example +@verbatim /* Tries to copy a byte from user address USRC to kernel address DST. Returns true if successful, false if USRC is invalid. */ -static inline bool get_user (uint8_t *dst, const uint8_t *usrc) @{ +static inline bool get_user (uint8_t *dst, const uint8_t *usrc) { int eax; asm ("movl $1f, %%eax; movb %2, %%al; movb %%al, %0; 1:" : "=m" (*dst), "=&a" (eax) : "m" (*usrc)); return eax != 0; -@} +} /* Tries write BYTE to user address UDST. Returns true if successful, false if UDST is invalid. */ -static inline bool put_user (uint8_t *udst, uint8_t byte) @{ +static inline bool put_user (uint8_t *udst, uint8_t byte) { int eax; asm ("movl $1f, %%eax; movb %b2, %0; 1:" : "=m" (*udst), "=&a" (eax) : "r" (byte)); return eax != 0; -@} -@end example +} +@end verbatim Each of these functions assumes that the user address has already been verified to be below @code{PHYS_BASE}. They also assume that you've @@ -592,7 +592,7 @@ This value, the exit status of the process, must be returned to the thread's parent when @func{join} is called. @item -@b{Can I just cast a pointer to a @code{struct file} object to get a +@b{Can I just cast a pointer to a @struct{file} object to get a unique file descriptor? Can I just cast a @code{struct thread *} to a @code{pid_t}? It's so much simpler that way!} @@ -688,7 +688,7 @@ some of your caches. This is why inlining code can be much faster. @end menu @node Argument Passing to main -@subsection Argument Passing to @func{main} +@subsection Argument Passing to @code{main()} In @func{main}'s case, there is no caller to prepare the stack before it runs. Therefore, the kernel needs to do it. Fortunately, @@ -807,12 +807,12 @@ You may find the non-standard @func{hex_dump} function, declared in Here's what it would show in the above example, given that @code{PHYS_BASE} is @t{0xc0000000}: -@example +@verbatim bfffffc0 00 00 00 00 | ....| bfffffd0 04 00 00 00 d8 ff ff bf-ed ff ff bf f5 ff ff bf |................| bfffffe0 f8 ff ff bf fc ff ff bf-00 00 00 00 00 2f 62 69 |............./bi| bffffff0 6e 2f 6c 73 00 2d 6c 00-2a 2e 68 00 2a 2e 63 00 |n/ls.-l.*.h.*.c.| -@end example +@end verbatim @node System Calls @section System Calls @@ -868,4 +868,4 @@ In this example, the caller's stack pointer would be at The 80@var{x}86 convention for function return values is to place them in the @samp{EAX} register. System calls that return a value can do -so by modifying the @samp{eax} member of @code{struct intr_frame}. +so by modifying the @samp{eax} member of @struct{intr_frame}. diff --git a/doc/vm.texi b/doc/vm.texi index 4d495d4..64619c8 100644 --- a/doc/vm.texi +++ b/doc/vm.texi @@ -131,6 +131,7 @@ address. @end enumerate @example +@group 32 22 12 0 +--------------------------------------------------------------------+ | Page Directory Index | Page Table Index | Page Offset | @@ -158,6 +159,7 @@ address. 1|____________| | 1|____________| | |____________| 0|____________| \__\0|____________| \____\|____________| / / +@end group @end example Header @file{threads/mmu.h} has useful functions for various @@ -471,7 +473,7 @@ true if the first is less than the second. These two functions have to be compatible with the prototypes for @code{hash_hash_func} and @code{hash_less_func} in @file{lib/kernel/hash.h}. -Here's a quick example. Suppose you want to put @code{struct thread}s +Here's a quick example. Suppose you want to put @struct{thread}s in a hash table. First, add a @code{hash_elem} to the thread structure by adding a line to its definition: @@ -479,7 +481,7 @@ structure by adding a line to its definition: hash_elem h_elem; /* Hash table element. */ @end example -We'll choose the @code{tid} member in @code{struct thread} as the key, +We'll choose the @code{tid} member in @struct{thread} as the key, and write a hash function and a comparison function: @example @@ -493,7 +495,8 @@ thread_hash (const hash_elem *e, void *aux UNUSED) /* Returns true if A's tid is less than B's tid. */ bool -thread_less (const hash_elem *a_, const hash_elem *b_, void *aux UNUSED) +thread_less (const hash_elem *a_, const hash_elem *b_, + void *aux UNUSED) @{ struct thread *a = hash_entry (a_, struct thread, h_elem); struct thread *b = hash_entry (b_, struct thread, h_elem); @@ -509,7 +512,7 @@ struct hash threads; hash_init (&threads, thread_hash, thread_less, NULL); @end example -Finally, if @code{@var{t}} is a pointer to a @code{struct thread}, +Finally, if @code{@var{t}} is a pointer to a @struct{thread}, then we can insert it into the hash table with: @example -- 2.30.2