summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proj1.txt13
-rw-r--r--threads/synch.c30
-rw-r--r--threads/thread.h2
3 files changed, 26 insertions, 19 deletions
diff --git a/proj1.txt b/proj1.txt
index 274ef34..27b0d17 100644
--- a/proj1.txt
+++ b/proj1.txt
@@ -34,6 +34,19 @@ http://hynek.me/studies/sched_ausarbeitung.pdf
34>> `struct' member, global or static variable, `typedef', or 34>> `struct' member, global or static variable, `typedef', or
35>> enumeration. Identify the purpose of each in 25 words or less. 35>> enumeration. Identify the purpose of each in 25 words or less.
36 36
37struct thread:
38 int is_donated ...flag if threads priority has been donated by another thread
39 int saved_priority ...saved base priority in case of priority dontation
40 struct list locks ...list of locks the thread currently holds
41 struct lock *blocked_lock ...the lock the thread currently tries to acquire (but hasn't yet)
42
43struct lock:
44 int priority ...the priority of the thread with the highest priority currently acquiring the lock
45 struct list_elem elem ...list element for (struct thread)->locks
46
47struct semaphore_elem:
48 struct thread *thread ...the current waiting thread
49
37>> B2: Explain the data structure used to track priority donation. 50>> B2: Explain the data structure used to track priority donation.
38>> Use ASCII art to diagram a nested donation. (Alternately, submit a 51>> Use ASCII art to diagram a nested donation. (Alternately, submit a
39>> .png file.) 52>> .png file.)
diff --git a/threads/synch.c b/threads/synch.c
index db204f5..d7e5e39 100644
--- a/threads/synch.c
+++ b/threads/synch.c
@@ -34,8 +34,6 @@
34 34
35static bool lock_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b, 35static bool lock_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b,
36 void *AUX UNUSED); 36 void *AUX UNUSED);
37static bool semaphore_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b,
38 void *aux UNUSED);
39 37
40/* Initializes semaphore SEMA to VALUE. A semaphore is a 38/* Initializes semaphore SEMA to VALUE. A semaphore is a
41 nonnegative integer along with two atomic operators for 39 nonnegative integer along with two atomic operators for
@@ -353,16 +351,6 @@ cond_init (struct condition *cond)
353 list_init (&cond->waiters); 351 list_init (&cond->waiters);
354} 352}
355 353
356/* comparison function for our descending ordered condition waiters list. */
357static bool
358semaphore_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b,
359 void *aux UNUSED)
360{
361 const struct semaphore_elem *s1 = list_entry (a, struct semaphore_elem, elem);
362 const struct semaphore_elem *s2 = list_entry (b, struct semaphore_elem, elem);
363 return (s1->thread->priority > s2->thread->priority);
364}
365
366/* Atomically releases LOCK and waits for COND to be signaled by 354/* Atomically releases LOCK and waits for COND to be signaled by
367 some other piece of code. After COND is signaled, LOCK is 355 some other piece of code. After COND is signaled, LOCK is
368 reacquired before returning. LOCK must be held before calling 356 reacquired before returning. LOCK must be held before calling
@@ -396,9 +384,9 @@ cond_wait (struct condition *cond, struct lock *lock)
396 sema_init (&waiter.semaphore, 0); 384 sema_init (&waiter.semaphore, 0);
397 /* set thread of waiter */ 385 /* set thread of waiter */
398 waiter.thread = thread_current (); 386 waiter.thread = thread_current ();
399 /* and add condition to our ordered waiters list */ 387 /* and add condition to our waiters list. sorting isn't useful here either.
400 list_insert_ordered (&cond->waiters, &waiter.elem, 388 see sema_up()/cond_signal() for more details */
401 &semaphore_priority_cmp_greater, NULL); 389 list_push_back (&cond->waiters, &waiter->elem);
402 lock_release (lock); 390 lock_release (lock);
403 sema_down (&waiter.semaphore); 391 sema_down (&waiter.semaphore);
404 lock_acquire (lock); 392 lock_acquire (lock);
@@ -419,9 +407,15 @@ cond_signal (struct condition *cond, struct lock *lock UNUSED)
419 ASSERT (!intr_context ()); 407 ASSERT (!intr_context ());
420 ASSERT (lock_held_by_current_thread (lock)); 408 ASSERT (lock_held_by_current_thread (lock));
421 409
422 if (!list_empty (&cond->waiters)) 410 /* we can't sort the list during insertion that easily as the priority of
423 sema_up (&list_entry (list_pop_front (&cond->waiters), 411 blocked/waiting threads may change due to priority donation.
424 struct semaphore_elem, elem)->semaphore); 412 this is the same as with sema_down()/sema_up() */
413 if (!list_empty (&cond->waiters))
414 {
415 list_sort (&cond->waiters, &semaphore_priority_cmp_greater, NULL);
416 sema_up (&list_entry (list_pop_front (&cond->waiters),
417 struct semaphore_elem, elem)->semaphore);
418 }
425} 419}
426 420
427/* Wakes up all threads, if any, waiting on COND (protected by 421/* Wakes up all threads, if any, waiting on COND (protected by
diff --git a/threads/thread.h b/threads/thread.h
index fd4f8a6..9125937 100644
--- a/threads/thread.h
+++ b/threads/thread.h
@@ -111,7 +111,7 @@ struct thread
111 int is_donated; /* flag if threads priority has been donated by another thread */ 111 int is_donated; /* flag if threads priority has been donated by another thread */
112 int saved_priority; /* saved base priority in case of priority dontation */ 112 int saved_priority; /* saved base priority in case of priority dontation */
113 struct list locks; /* list of locks the thread currently holds */ 113 struct list locks; /* list of locks the thread currently holds */
114 struct lock *blocked_lock; /* lock the thread currently trys to accquire (but hasn't yet) */ 114 struct lock *blocked_lock; /* the lock the thread currently tries to acquire (but hasn't yet) */
115 }; 115 };
116 116
117/* If false (default), use round-robin scheduler. 117/* If false (default), use round-robin scheduler.