X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=doc%2Freference.texi;h=c25f3ddebd160d1eefc5574552b6f32f5a826d31;hb=5440a348242d2a56cee111000b676ac3d7d84ea5;hp=3fe8b68a19d55c08901bef173bc144890450257b;hpb=95e1f45529540b68ac09b2e54ce4fe85d7302d96;p=pintos-anon diff --git a/doc/reference.texi b/doc/reference.texi index 3fe8b68..c25f3dd 100644 --- a/doc/reference.texi +++ b/doc/reference.texi @@ -163,7 +163,7 @@ this, but calling it a second time is harmless. The next block of functions we call initialize the kernel's memory system. @func{palloc_init} sets up the kernel page allocator, which -doles out memory one or more pages at a time (@xpref{Page Allocator}). +doles out memory one or more pages at a time (@pxref{Page Allocator}). @func{malloc_init} sets up the allocator that handles allocations of arbitrary-size blocks of memory (@pxref{Block Allocator}). @@ -230,27 +230,27 @@ grows downward from the end of the page. It looks like this: @example @group - 4 kB +---------------------------------+ - | kernel stack | - | | | - | | | - | V | - | grows downward | - | | - | | - | | - | | - | | - | | - | | - | | - +---------------------------------+ - | magic | - | : | - | : | - | status | - | tid | - 0 kB +---------------------------------+ + 4 kB +---------------------------------+ + | kernel stack | + | | | + | | | + | V | + | grows downward | + | | + | | + | | + | | + | | + | | + | | + | | +sizeof (struct thread) +---------------------------------+ + | magic | + | : | + | : | + | status | + | tid | + 0 kB +---------------------------------+ @end group @end example @@ -276,6 +276,7 @@ if you like. @end deftypecv @deftypecv {Member} {@struct{thread}} {enum thread_status} status +@anchor{Thread States} The thread's state, one of the following: @defvr {Thread State} @code{THREAD_RUNNING} @@ -294,7 +295,12 @@ invoked. Ready threads are kept in a doubly linked list called The thread is waiting for something, e.g.@: a lock to become available, an interrupt to be invoked. The thread won't be scheduled again until it transitions to the @code{THREAD_READY} state with a -call to @func{thread_unblock}. +call to @func{thread_unblock}. This is most conveniently done +indirectly, using one of the Pintos synchronization primitives that +block and unblock threads automatically (@pxref{Synchronization}). + +There is no @i{a priori} way to tell what a blocked thread is waiting +for, but a backtrace can help (@pxref{Backtraces}). @end defvr @defvr {Thread State} @code{THREAD_DYING} @@ -332,23 +338,24 @@ priority scheduling in project 1 (@pxref{Priority Scheduling}). @deftypecv {Member} {@struct{thread}} {@struct{list_elem}} elem A ``list element'' used to put the thread into doubly linked lists, -either the list of threads ready to run or a list of threads waiting -on a semaphore. Take a look at @file{lib/kernel/list.h} for -information on how to use Pintos doubly linked lists. +either @code{ready_list} (the list of threads ready to run) or a list of +threads waiting on a semaphore in @func{sema_down}. It can do double +duty because a thread waiting on a semaphore is not ready, and vice +versa. @end deftypecv @deftypecv {Member} {@struct{thread}} {uint32_t *} pagedir -Only present in project 2 and later. +Only present in project 2 and later. @xref{Page Tables}. @end deftypecv @deftypecv {Member} {@struct{thread}} {unsigned} magic -Always set to @code{THREAD_MAGIC}, which is just a random number defined +Always set to @code{THREAD_MAGIC}, which is just an arbitrary number defined in @file{threads/thread.c}, and used to detect stack overflow. @func{thread_current} checks that the @code{magic} member of the running thread's @struct{thread} is set to @code{THREAD_MAGIC}. Stack overflow -will normally change this value, triggering the assertion. For greatest -benefit, as you add members to @struct{thread}, leave @code{magic} as -the final member. +tends to change this value, triggering the assertion. For greatest +benefit, as you add members to @struct{thread}, leave @code{magic} at +the end. @end deftypecv @node Thread Functions @@ -396,20 +403,21 @@ Creates and starts a new thread named @var{name} with the given @func{thread_create} allocates a page for the thread's @struct{thread} and stack and initializes its members, then it sets -up a set of fake stack frames for it (more about this -later). The thread is initialized in the blocked state, so the final -action before returning is to unblock it, which allows the new thread to -be scheduled. -@end deftypefun +up a set of fake stack frames for it (@pxref{Thread Switching}). The +thread is initialized in the blocked state, then unblocked just before +returning, which allows the new thread to +be scheduled (@pxref{Thread States}). @deftp {Type} {void thread_func (void *@var{aux})} -This is the type of a thread function. Its @var{aux} argument is the -value passed to @func{thread_create}. +This is the type of the function passed to @func{thread_create}, whose +@var{aux} argument is passed along as the function's argument. @end deftp +@end deftypefun @deftypefun void thread_block (void) Transitions the running thread from the running state to the blocked -state. The thread will not run again until @func{thread_unblock} is +state (@pxref{Thread States}). The thread will not run again until +@func{thread_unblock} is called on it, so you'd better have some way arranged for that to happen. Because @func{thread_block} is so low-level, you should prefer to use one of the synchronization primitives instead (@pxref{Synchronization}). @@ -417,8 +425,9 @@ one of the synchronization primitives instead (@pxref{Synchronization}). @deftypefun void thread_unblock (struct thread *@var{thread}) Transitions @var{thread}, which must be in the blocked state, to the -ready state, allowing it to resume running. This is called when the -event that the thread is waiting for occurs, e.g.@: when the lock that +ready state, allowing it to resume running (@pxref{Thread States}). +This is called when the event that the thread is waiting for occurs, +e.g.@: when the lock that the thread is waiting on becomes available. @end deftypefun @@ -450,20 +459,20 @@ time. @deftypefun int thread_get_priority (void) @deftypefunx void thread_set_priority (int @var{new_priority}) -Skeleton to set and get thread priority. @xref{Priority Scheduling}. +Stub to set and get thread priority. @xref{Priority Scheduling}. @end deftypefun @deftypefun int thread_get_nice (void) @deftypefunx void thread_set_nice (int @var{new_nice}) @deftypefunx int thread_get_recent_cpu (void) @deftypefunx int thread_get_load_avg (void) -Skeletons for the advanced scheduler. @xref{4.4BSD Scheduler}. +Stubs for the advanced scheduler. @xref{4.4BSD Scheduler}. @end deftypefun @node Thread Switching @subsection Thread Switching -@func{schedule} is the function responsible for switching threads. It +@func{schedule} is responsible for switching threads. It is internal to @file{threads/thread.c} and called only by the three public thread functions that need to switch threads: @func{thread_block}, @func{thread_exit}, and @func{thread_yield}. @@ -471,7 +480,7 @@ Before any of these functions call @func{schedule}, they disable interrupts (or ensure that they are already disabled) and then change the running thread's state to something other than running. -@func{schedule} is simple but tricky. It records the +@func{schedule} is short but tricky. It records the current thread in local variable @var{cur}, determines the next thread to run as local variable @var{next} (by calling @func{next_thread_to_run}), and then calls @func{switch_threads} to do @@ -486,7 +495,7 @@ CPU's current stack pointer in the current @struct{thread}'s @code{stack} member, restores the new thread's @code{stack} into the CPU's stack pointer, restores registers from the stack, and returns. -The rest of the scheduler is implemented as @func{schedule_tail}. It +The rest of the scheduler is implemented in @func{schedule_tail}. It marks the new thread as running. If the thread we just switched from is in the dying state, then it also frees the page that contained the dying thread's @struct{thread} and stack. These couldn't be freed @@ -494,7 +503,7 @@ prior to the thread switch because the switch needed to use it. Running a thread for the first time is a special case. When @func{thread_create} creates a new thread, it goes through a fair -amount of trouble to get it started properly. In particular, a new +amount of trouble to get it started properly. In particular, the new thread hasn't started running yet, so there's no way for it to be running inside @func{switch_threads} as the scheduler expects. To solve the problem, @func{thread_create} creates some fake stack frames