Fix bugs.
[pintos-anon] / solutions / p1-2.patch
1 Only in pintos/src/threads: .#init.c
2 Only in pintos/src/threads: build
3 Only in pintos/src/threads: init.c~
4 diff -urp pintos.orig/src/threads/synch.c pintos/src/threads/synch.c
5 --- pintos.orig/src/threads/synch.c     2004-09-19 21:29:53.000000000 -0700
6 +++ pintos/src/threads/synch.c  2004-09-20 22:38:56.000000000 -0700
7 @@ -330,3 +330,35 @@ cond_name (const struct condition *cond)
8  
9    return cond->name;
10  }
11 +\f
12 +void
13 +latch_init (struct latch *latch, const char *name) 
14 +{
15 +  latch->released = false;
16 +  lock_init (&latch->monitor_lock, name);
17 +  cond_init (&latch->rel_cond, name);
18 +}
19 +
20 +void
21 +latch_acquire (struct latch *latch) 
22 +{
23 +  lock_acquire (&latch->monitor_lock);
24 +  if (!latch->released) 
25 +    {
26 +      cond_wait (&latch->rel_cond, &latch->monitor_lock);
27 +      ASSERT (latch->released); 
28 +    }
29 +  lock_release (&latch->monitor_lock);
30 +}
31 +
32 +void
33 +latch_release (struct latch *latch) 
34 +{
35 +  lock_acquire (&latch->monitor_lock);
36 +  if (!latch->released)
37 +    {
38 +      latch->released = true;
39 +      cond_signal (&latch->rel_cond, &latch->monitor_lock);
40 +    }
41 +  lock_release (&latch->monitor_lock);
42 +}
43 Only in pintos/src/threads: synch.c.orig
44 diff -urp pintos.orig/src/threads/synch.h pintos/src/threads/synch.h
45 --- pintos.orig/src/threads/synch.h     2004-09-19 21:29:53.000000000 -0700
46 +++ pintos/src/threads/synch.h  2004-09-20 22:38:56.000000000 -0700
47 @@ -44,4 +44,16 @@ void cond_signal (struct condition *, st
48  void cond_broadcast (struct condition *, struct lock *);
49  const char *cond_name (const struct condition *);
50  
51 +/* Latch. */
52 +struct latch 
53 +  {
54 +    bool released;              /* Released yet? */
55 +    struct lock monitor_lock;   /* Monitor lock. */
56 +    struct condition rel_cond;  /* Signaled when released. */
57 +  };
58 +
59 +void latch_init (struct latch *, const char *);
60 +void latch_acquire (struct latch *);
61 +void latch_release (struct latch *);
62 +
63  #endif /* threads/synch.h */
64 Only in pintos/src/threads: synch.h.orig
65 diff -urp pintos.orig/src/threads/thread.c pintos/src/threads/thread.c
66 --- pintos.orig/src/threads/thread.c    2004-09-20 19:32:31.000000000 -0700
67 +++ pintos/src/threads/thread.c 2004-09-20 22:52:43.000000000 -0700
68 @@ -76,6 +76,7 @@ thread_init (void) 
69    init_thread (initial_thread, "main", PRI_DEFAULT);
70    initial_thread->status = THREAD_RUNNING;
71    initial_thread->tid = allocate_tid ();
72 +  sema_up (&initial_thread->can_die);
73  }
74  
75  /* Starts preemptive thread scheduling by enabling interrupts.
76 @@ -120,6 +121,7 @@ thread_create (const char *name, int pri
77    /* Initialize thread. */
78    init_thread (t, name, priority);
79    tid = t->tid = allocate_tid ();
80 +  list_push_back (&thread_current ()->children, &t->children_elem);
81  
82    /* Stack frame for kernel_thread(). */
83    kf = alloc_frame (t, sizeof *kf);
84 @@ -196,12 +198,30 @@ thread_tid (void) 
85  void
86  thread_exit (void) 
87  {
88 +  struct thread *t = thread_current ();
89 +  list_elem *e;
90 +
91    ASSERT (!intr_context ());
92  
93 +  /* Notify our parent that we're dying. */
94 +  latch_release (&t->ready_to_die);
95 +
96 +  /* Notify our children that they can die. */
97 +  for (e = list_begin (&t->children); e != list_end (&t->children);
98 +       e = list_next (e)) 
99 +    {
100 +      struct thread *child = list_entry (e, struct thread, children_elem);
101 +      list_remove (e);
102 +      sema_up (&child->can_die); 
103 +    }
104 +
105 +  /* Wait until our parent is ready for us to die. */
106 +  sema_down (&t->can_die);
107 +
108    /* Just set our status to dying and schedule another process.
109       We will be destroyed during the call to schedule_tail(). */
110    intr_disable ();
111 -  thread_current ()->status = THREAD_DYING;
112 +  t->status = THREAD_DYING;
113    schedule ();
114    NOT_REACHED ();
115  }
116 @@ -238,6 +258,22 @@ thread_block (void) 
117    thread_current ()->status = THREAD_BLOCKED;
118    schedule ();
119  }
120 +
121 +/* Waits for thread with tid CHILD_TID to die. */
122 +void
123 +thread_join (tid_t child_tid) 
124 +{
125 +  struct thread *cur = thread_current ();
126 +  list_elem *e;
127 +
128 +  for (e = list_begin (&cur->children); e != list_end (&cur->children); ) 
129 +    {
130 +      struct thread *child = list_entry (e, struct thread, children_elem);
131 +      e = list_next (e);
132 +      if (child->tid == child_tid) 
133 +        latch_acquire (&child->ready_to_die);
134 +    }
135 +}
136  \f
137  /* Idle thread.  Executes when no other thread is ready to run. */
138  static void
139 @@ -303,6 +339,9 @@ init_thread (struct thread *t, const cha
140    strlcpy (t->name, name, sizeof t->name);
141    t->stack = (uint8_t *) t + PGSIZE;
142    t->priority = priority;
143 +  latch_init (&t->ready_to_die, "ready-to-die");
144 +  sema_init (&t->can_die, 0, "can-die");
145 +  list_init (&t->children);
146    t->magic = THREAD_MAGIC;
147  }
148  
149 Only in pintos/src/threads: thread.c.orig
150 Only in pintos/src/threads: thread.c.rej
151 Only in pintos/src/threads: thread.c.rej~
152 Only in pintos/src/threads: thread.c~
153 diff -urp pintos.orig/src/threads/thread.h pintos/src/threads/thread.h
154 --- pintos.orig/src/threads/thread.h    2004-09-20 15:29:18.000000000 -0700
155 +++ pintos/src/threads/thread.h 2004-09-20 22:36:55.000000000 -0700
156 @@ -4,6 +4,7 @@
157  #include <debug.h>
158  #include <list.h>
159  #include <stdint.h>
160 +#include "threads/synch.h"
161  
162  /* States in a thread's life cycle. */
163  enum thread_status
164 @@ -89,6 +90,12 @@ struct thread
165      uint8_t *stack;                     /* Saved stack pointer. */
166      int priority;                       /* Priority. */
167  
168 +    /* Members for implementing thread_join(). */
169 +    struct latch ready_to_die;          /* Release when thread about to die. */
170 +    struct semaphore can_die;           /* Up when thread allowed to die. */
171 +    struct list children;               /* List of child threads. */
172 +    list_elem children_elem;            /* Element of `children' list. */
173 +
174      /* Shared between thread.c and synch.c. */
175      list_elem elem;                     /* List element. */
176  
177 Only in pintos/src/threads: thread.h.orig
178 Only in pintos/src/threads: thread.h~