1 diff -X pat -urpN pintos.orig/src/threads/synch.c pintos/src/threads/synch.c
2 --- pintos.orig/src/threads/synch.c 2004-09-19 21:29:53.000000000 -0700
3 +++ pintos/src/threads/synch.c 2004-09-27 16:50:14.000000000 -0700
4 @@ -330,3 +330,35 @@ cond_name (const struct condition *cond)
10 +latch_init (struct latch *latch, const char *name)
12 + latch->released = false;
13 + lock_init (&latch->monitor_lock, name);
14 + cond_init (&latch->rel_cond, name);
18 +latch_acquire (struct latch *latch)
20 + lock_acquire (&latch->monitor_lock);
21 + if (!latch->released)
23 + cond_wait (&latch->rel_cond, &latch->monitor_lock);
24 + ASSERT (latch->released);
26 + lock_release (&latch->monitor_lock);
30 +latch_release (struct latch *latch)
32 + lock_acquire (&latch->monitor_lock);
33 + if (!latch->released)
35 + latch->released = true;
36 + cond_signal (&latch->rel_cond, &latch->monitor_lock);
38 + lock_release (&latch->monitor_lock);
40 diff -X pat -urpN pintos.orig/src/threads/synch.h pintos/src/threads/synch.h
41 --- pintos.orig/src/threads/synch.h 2004-09-19 21:29:53.000000000 -0700
42 +++ pintos/src/threads/synch.h 2004-09-27 16:50:14.000000000 -0700
43 @@ -44,4 +44,16 @@ void cond_signal (struct condition *, st
44 void cond_broadcast (struct condition *, struct lock *);
45 const char *cond_name (const struct condition *);
50 + bool released; /* Released yet? */
51 + struct lock monitor_lock; /* Monitor lock. */
52 + struct condition rel_cond; /* Signaled when released. */
55 +void latch_init (struct latch *, const char *);
56 +void latch_acquire (struct latch *);
57 +void latch_release (struct latch *);
59 #endif /* threads/synch.h */
60 diff -X pat -urpN pintos.orig/src/threads/thread.c pintos/src/threads/thread.c
61 --- pintos.orig/src/threads/thread.c 2004-09-26 14:15:17.000000000 -0700
62 +++ pintos/src/threads/thread.c 2004-09-27 16:51:03.000000000 -0700
63 @@ -80,6 +80,7 @@ thread_init (void)
64 init_thread (initial_thread, "main", PRI_DEFAULT);
65 initial_thread->status = THREAD_RUNNING;
66 initial_thread->tid = allocate_tid ();
67 + sema_up (&initial_thread->can_die);
70 /* Starts preemptive thread scheduling by enabling interrupts.
71 @@ -148,6 +149,7 @@ thread_create (const char *name, int pri
72 /* Initialize thread. */
73 init_thread (t, name, priority);
74 tid = t->tid = allocate_tid ();
75 + list_push_back (&thread_current ()->children, &t->children_elem);
77 /* Stack frame for kernel_thread(). */
78 kf = alloc_frame (t, sizeof *kf);
79 @@ -224,16 +226,34 @@ thread_tid (void)
83 + struct thread *t = thread_current ();
86 ASSERT (!intr_context ());
92 + /* Notify our parent that we're dying. */
93 + latch_release (&t->ready_to_die);
95 + /* Notify our children that they can die. */
96 + for (e = list_begin (&t->children); e != list_end (&t->children);
99 + struct thread *child = list_entry (e, struct thread, children_elem);
101 + sema_up (&child->can_die);
104 + /* Wait until our parent is ready for us to die. */
105 + sema_down (&t->can_die);
107 /* Just set our status to dying and schedule another process.
108 We will be destroyed during the call to schedule_tail(). */
110 - thread_current ()->status = THREAD_DYING;
111 + t->status = THREAD_DYING;
115 @@ -270,6 +290,22 @@ thread_block (void)
116 thread_current ()->status = THREAD_BLOCKED;
120 +/* Waits for thread with tid CHILD_TID to die. */
122 +thread_join (tid_t child_tid)
124 + struct thread *cur = thread_current ();
127 + for (e = list_begin (&cur->children); e != list_end (&cur->children); )
129 + struct thread *child = list_entry (e, struct thread, children_elem);
131 + if (child->tid == child_tid)
132 + latch_acquire (&child->ready_to_die);
136 /* Idle thread. Executes when no other thread is ready to run. */
138 @@ -335,6 +371,9 @@ init_thread (struct thread *t, const cha
139 strlcpy (t->name, name, sizeof t->name);
140 t->stack = (uint8_t *) t + PGSIZE;
141 t->priority = priority;
142 + latch_init (&t->ready_to_die, "ready-to-die");
143 + sema_init (&t->can_die, 0, "can-die");
144 + list_init (&t->children);
145 t->magic = THREAD_MAGIC;
148 diff -X pat -urpN pintos.orig/src/threads/thread.h pintos/src/threads/thread.h
149 --- pintos.orig/src/threads/thread.h 2004-09-26 14:15:17.000000000 -0700
150 +++ pintos/src/threads/thread.h 2004-09-27 16:50:14.000000000 -0700
155 +#include "threads/synch.h"
157 /* States in a thread's life cycle. */
159 @@ -89,6 +90,12 @@ struct thread
160 uint8_t *stack; /* Saved stack pointer. */
161 int priority; /* Priority. */
163 + /* Members for implementing thread_join(). */
164 + struct latch ready_to_die; /* Release when thread about to die. */
165 + struct semaphore can_die; /* Up when thread allowed to die. */
166 + struct list children; /* List of child threads. */
167 + list_elem children_elem; /* Element of `children' list. */
169 /* Shared between thread.c and synch.c. */
170 list_elem elem; /* List element. */