Add comments.
[pintos-anon] / src / threads / thread.h
index e8927def25ebc99594a541425096ddc6eff8c4e4..a70b48b50cb0305f2147089a0b4db17948e8de46 100644 (file)
@@ -9,15 +9,66 @@
 #include "addrspace.h"
 #endif
 
-enum thread_status 
+/* States in a thread's life cycle. */
+enum thread_status
   {
-    THREAD_RUNNING,
-    THREAD_READY,
-    THREAD_BLOCKED,
-    THREAD_DYING
+    THREAD_RUNNING,     /* Running thread. */
+    THREAD_READY,       /* Not running but ready to run. */
+    THREAD_BLOCKED,     /* Waiting for an event to trigger. */
+    THREAD_DYING        /* About to be destroyed. */
   };
 
-struct thread 
+/* A kernel thread or user process.
+
+   Each thread structure is stored in its own 4 kB page.  The
+   thread structure itself sits at the very bottom of the page
+   (at offset 0).  The rest of the page is reserved for the
+   thread's kernel stack, which grows downward from the top of
+   the page (at offset 4 kB).  Here's an illustration:
+
+        4 kB +---------------------------------+
+             |          kernel stack           |
+             |                |                |
+             |                |                |
+             |                V                |
+             |         grows downward          |
+             |                                 |
+             |                                 |
+             |                                 |
+             |                                 |
+             |                                 |
+             |                                 |
+             |                                 |
+             |                                 |
+             +---------------------------------+
+             |             magic               |
+             |               :                 |
+             |               :                 |
+             |              name               |
+             |             status              |
+        0 kB +---------------------------------+
+
+   The upshot of this is twofold:
+
+      1. First, `struct thread' must not be allowed to grow too
+         big.  If it does, then there will not be enough room for
+         the kernel stack.  Our base `struct thread' is only a
+         few bytes in size.  It probably should stay well under 1
+         kB.
+
+      2. Second, kernel stacks must not be allowed to grow too
+         large.  If a stack overflows, it will corrupt the thread
+         state.  Thus, kernel functions should not allocate large
+         structures or arrays as non-static local variables.  Use
+         dynamic allocation with malloc() or palloc_get()
+         instead.
+
+   The first symptom of either of these problems will probably be
+   an assertion failure in thread_current(), which checks that
+   the `magic' member of the running thread's `struct thread' is
+   set to THREAD_MAGIC.  Stack overflow will normally change this
+   value, triggering the assertion. */
+struct thread
   {
     /* These members are owned by the thread_*() functions. */
     enum thread_status status;          /* Thread state. */
@@ -29,7 +80,7 @@ struct thread
     /* These members are owned by the addrspace_*() functions. */
     uint32_t *pagedir;                  /* Page directory. */
 #endif
-    
+
     /* Marker to detect stack overflow. */
     unsigned magic;                     /* Always set to THREAD_MAGIC. */
   };