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)
13 +latch_init (struct latch *latch, const char *name)
15 + latch->released = false;
16 + lock_init (&latch->monitor_lock, name);
17 + cond_init (&latch->rel_cond, name);
21 +latch_acquire (struct latch *latch)
23 + lock_acquire (&latch->monitor_lock);
24 + if (!latch->released)
26 + cond_wait (&latch->rel_cond, &latch->monitor_lock);
27 + ASSERT (latch->released);
29 + lock_release (&latch->monitor_lock);
33 +latch_release (struct latch *latch)
35 + lock_acquire (&latch->monitor_lock);
36 + if (!latch->released)
38 + latch->released = true;
39 + cond_signal (&latch->rel_cond, &latch->monitor_lock);
41 + lock_release (&latch->monitor_lock);
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 *);
54 + bool released; /* Released yet? */
55 + struct lock monitor_lock; /* Monitor lock. */
56 + struct condition rel_cond; /* Signaled when released. */
59 +void latch_init (struct latch *, const char *);
60 +void latch_acquire (struct latch *);
61 +void latch_release (struct latch *);
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);
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);
82 /* Stack frame for kernel_thread(). */
83 kf = alloc_frame (t, sizeof *kf);
84 @@ -196,12 +198,30 @@ thread_tid (void)
88 + struct thread *t = thread_current ();
91 ASSERT (!intr_context ());
93 + /* Notify our parent that we're dying. */
94 + latch_release (&t->ready_to_die);
96 + /* Notify our children that they can die. */
97 + for (e = list_begin (&t->children); e != list_end (&t->children);
100 + struct thread *child = list_entry (e, struct thread, children_elem);
102 + sema_up (&child->can_die);
105 + /* Wait until our parent is ready for us to die. */
106 + sema_down (&t->can_die);
108 /* Just set our status to dying and schedule another process.
109 We will be destroyed during the call to schedule_tail(). */
111 - thread_current ()->status = THREAD_DYING;
112 + t->status = THREAD_DYING;
116 @@ -238,6 +258,22 @@ thread_block (void)
117 thread_current ()->status = THREAD_BLOCKED;
121 +/* Waits for thread with tid CHILD_TID to die. */
123 +thread_join (tid_t child_tid)
125 + struct thread *cur = thread_current ();
128 + for (e = list_begin (&cur->children); e != list_end (&cur->children); )
130 + struct thread *child = list_entry (e, struct thread, children_elem);
132 + if (child->tid == child_tid)
133 + latch_acquire (&child->ready_to_die);
137 /* Idle thread. Executes when no other thread is ready to run. */
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;
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
160 +#include "threads/synch.h"
162 /* States in a thread's life cycle. */
164 @@ -89,6 +90,12 @@ struct thread
165 uint8_t *stack; /* Saved stack pointer. */
166 int priority; /* Priority. */
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. */
174 /* Shared between thread.c and synch.c. */
175 list_elem elem; /* List element. */
177 Only in pintos/src/threads: thread.h.orig
178 Only in pintos/src/threads: thread.h~