Update.
[pintos-anon] / solutions / p1-2.patch
index 5e5ea21e5054f69b9511aacdd6d1614977e88665..7e3858281d98108f7386c4f916d5ede12826ec5b 100644 (file)
---- cs140/pintos/src/threads/thread.c  2004-09-17 23:16:15.000000000 -0700
-+++ cs140/ref/pintos/src/threads/thread.c      2004-09-17 23:19:03.000000000 -0700
-@@ -75,6 +75,7 @@
+diff -X pat -urpN threads/synch.c! src/threads/synch.c
+--- src/threads/synch.c~       2004-09-19 21:29:53.000000000 -0700
++++ src/threads/synch.c        2004-09-27 16:50:14.000000000 -0700
+@@ -330,3 +330,35 @@ cond_name (const struct condition *cond)
+   return cond->name;
+ }
++\f
++void
++latch_init (struct latch *latch, const char *name) 
++{
++  latch->released = false;
++  lock_init (&latch->monitor_lock, name);
++  cond_init (&latch->rel_cond, name);
++}
++
++void
++latch_acquire (struct latch *latch) 
++{
++  lock_acquire (&latch->monitor_lock);
++  if (!latch->released) 
++    {
++      cond_wait (&latch->rel_cond, &latch->monitor_lock);
++      ASSERT (latch->released); 
++    }
++  lock_release (&latch->monitor_lock);
++}
++
++void
++latch_release (struct latch *latch) 
++{
++  lock_acquire (&latch->monitor_lock);
++  if (!latch->released)
++    {
++      latch->released = true;
++      cond_signal (&latch->rel_cond, &latch->monitor_lock);
++    }
++  lock_release (&latch->monitor_lock);
++}
+diff -X pat -urpN src/threads/synch.h~ src/threads/synch.h
+--- src/threads/synch.h~       2004-09-19 21:29:53.000000000 -0700
++++ src/threads/synch.h        2004-09-27 16:50:14.000000000 -0700
+@@ -44,4 +44,16 @@ void cond_signal (struct condition *, st
+ void cond_broadcast (struct condition *, struct lock *);
+ const char *cond_name (const struct condition *);
++/* Latch. */
++struct latch 
++  {
++    bool released;              /* Released yet? */
++    struct lock monitor_lock;   /* Monitor lock. */
++    struct condition rel_cond;  /* Signaled when released. */
++  };
++
++void latch_init (struct latch *, const char *);
++void latch_acquire (struct latch *);
++void latch_release (struct latch *);
++
+ #endif /* threads/synch.h */
+diff -X pat -urpN src/threads/thread.c~ src/threads/thread.c
+--- src/threads/thread.c~      2004-09-26 14:15:17.000000000 -0700
++++ src/threads/thread.c       2004-09-27 16:51:03.000000000 -0700
+@@ -80,6 +80,7 @@ thread_init (void) 
    init_thread (initial_thread, "main", PRI_DEFAULT);
    initial_thread->status = THREAD_RUNNING;
    initial_thread->tid = allocate_tid ();
 +  sema_up (&initial_thread->can_die);
+ }
+ /* Starts preemptive thread scheduling by enabling interrupts.
+@@ -148,6 +149,7 @@ thread_create (const char *name, int pri
+   /* Initialize thread. */
+   init_thread (t, name, priority);
+   tid = t->tid = allocate_tid ();
++  list_push_back (&thread_current ()->children, &t->children_elem);
  
-   /* Initialize run queue. */
-   list_init (&ready_list);
-@@ -244,12 +245,29 @@
+   /* Stack frame for kernel_thread(). */
+   kf = alloc_frame (t, sizeof *kf);
+@@ -224,16 +226,34 @@ thread_tid (void) 
  void
  thread_exit (void) 
  {
 +  struct thread *t = thread_current ();
-+  list_elem *e;
++  list_elem *e, *next;
 +
    ASSERT (!intr_context ());
  
+ #ifdef USERPROG
+   process_exit ();
+ #endif
 +  /* Notify our parent that we're dying. */
-+  sema_up (&t->ready_to_die);
++  latch_release (&t->ready_to_die);
 +
 +  /* Notify our children that they can die. */
-+  for (e = list_begin (&t->children); e != list_end (&t->children);
-+       e = list_next (e)) 
++  for (e = list_begin (&t->children); e != list_end (&t->children); e = next)
 +    {
 +      struct thread *child = list_entry (e, struct thread, children_elem);
++      next = list_next (e);
++      list_remove (e);
 +      sema_up (&child->can_die); 
 +    }
 +
    schedule ();
    NOT_REACHED ();
  }
-@@ -286,6 +304,31 @@
+@@ -270,6 +290,22 @@ thread_block (void) 
    thread_current ()->status = THREAD_BLOCKED;
    schedule ();
  }
 +      struct thread *child = list_entry (e, struct thread, children_elem);
 +      e = list_next (e);
 +      if (child->tid == child_tid) 
-+        {
-+          /* Wait until child is ready to die. */
-+          sema_down (&child->ready_to_die);
-+
-+          /* Remove from list of children. */
-+          list_remove (&child->children_elem);
-+
-+          /* Notify child that it can finish dying. */
-+          sema_up (&child->can_die); 
-+        }
++        latch_acquire (&child->ready_to_die);
 +    }
 +}
  \f
  /* Idle thread.  Executes when no other thread is ready to run. */
  static void
-@@ -348,12 +391,13 @@
-     {
-       init_thread (t, name, priority);
-       t->tid = allocate_tid ();
-+      list_push_back (&thread_current ()->children, &t->children_elem);
-     }
-   return t;
- }
--/* Does basic initialization of T as a blocked thread named
-+/* Does basic initialization of T as a new, blocked thread named
-    NAME. */
- static void
- init_thread (struct thread *t, const char *name, int priority)
-@@ -367,6 +411,9 @@
+@@ -335,6 +371,9 @@ init_thread (struct thread *t, const cha
    strlcpy (t->name, name, sizeof t->name);
    t->stack = (uint8_t *) t + PGSIZE;
    t->priority = priority;
-+  sema_init (&t->ready_to_die, 0, "ready-to-die");
++  latch_init (&t->ready_to_die, "ready-to-die");
 +  sema_init (&t->can_die, 0, "can-die");
 +  list_init (&t->children);
    t->magic = THREAD_MAGIC;
  }
  
---- cs140/pintos/src/threads/thread.h  2004-09-16 21:42:35.000000000 -0700
-+++ cs140/ref/pintos/src/threads/thread.h      2004-09-17 23:21:14.000000000 -0700
+diff -X pat -urpN src/threads/thread.h~ src/threads/thread.h
+--- src/threads/thread.h~      2004-09-26 14:15:17.000000000 -0700
++++ src/threads/thread.h       2004-09-27 16:50:14.000000000 -0700
 @@ -4,6 +4,7 @@
  #include <debug.h>
  #include <list.h>
  #include <stdint.h>
 +#include "threads/synch.h"
  
- #ifdef USERPROG
- #include "userprog/addrspace.h"
-@@ -93,6 +94,12 @@
+ /* States in a thread's life cycle. */
+ enum thread_status
+@@ -89,6 +90,12 @@ struct thread
      uint8_t *stack;                     /* Saved stack pointer. */
      int priority;                       /* Priority. */
  
 +    /* Members for implementing thread_join(). */
-+    struct semaphore ready_to_die;      /* Up when thread about to die. */
++    struct latch ready_to_die;          /* Release when thread about to die. */
 +    struct semaphore can_die;           /* Up when thread allowed to die. */
 +    struct list children;               /* List of child threads. */
 +    list_elem children_elem;            /* Element of `children' list. */