X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=solutions%2Fp1-2.patch;h=7e3858281d98108f7386c4f916d5ede12826ec5b;hb=969638e43328cce935d0fd486f9966bc369a2a6d;hp=5e5ea21e5054f69b9511aacdd6d1614977e88665;hpb=31ea3e0d81304ca46d13e200dd998ea04a194e19;p=pintos-anon diff --git a/solutions/p1-2.patch b/solutions/p1-2.patch index 5e5ea21..7e38582 100644 --- a/solutions/p1-2.patch +++ b/solutions/p1-2.patch @@ -1,30 +1,103 @@ ---- 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; + } ++ ++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); + } + @@ -39,7 +112,7 @@ schedule (); NOT_REACHED (); } -@@ -286,6 +304,31 @@ +@@ -270,6 +290,22 @@ thread_block (void) thread_current ()->status = THREAD_BLOCKED; schedule (); } @@ -56,62 +129,39 @@ + 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); + } +} /* 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 #include #include +#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. */