summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--threads/synch.c51
-rw-r--r--threads/thread.c12
-rw-r--r--threads/thread.h2
3 files changed, 46 insertions, 19 deletions
diff --git a/threads/synch.c b/threads/synch.c
index 1f15bb9..92008ef 100644
--- a/threads/synch.c
+++ b/threads/synch.c
@@ -32,8 +32,10 @@
32#include "threads/interrupt.h" 32#include "threads/interrupt.h"
33#include "threads/thread.h" 33#include "threads/thread.h"
34 34
35static bool lock_list_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);
37 39
38/* Initializes semaphore SEMA to VALUE. A semaphore is a 40/* Initializes semaphore SEMA to VALUE. A semaphore is a
39 nonnegative integer along with two atomic operators for 41 nonnegative integer along with two atomic operators for
@@ -72,7 +74,8 @@ sema_down (struct semaphore *sema)
72 while (sema->value == 0) 74 while (sema->value == 0)
73 { 75 {
74 /* add thread to our ordered waiters list */ 76 /* add thread to our ordered waiters list */
75 list_insert_ordered (&sema->waiters, &thread_current ()->elem, &priority_list_cmp_greater, NULL); 77 list_insert_ordered (&sema->waiters, &thread_current ()->elem,
78 &thread_priority_cmp_greater, NULL);
76 thread_block (); 79 thread_block ();
77 } 80 }
78 sema->value--; 81 sema->value--;
@@ -113,15 +116,25 @@ void
113sema_up (struct semaphore *sema) 116sema_up (struct semaphore *sema)
114{ 117{
115 enum intr_level old_level; 118 enum intr_level old_level;
119 bool yield = false;
116 120
117 ASSERT (sema != NULL); 121 ASSERT (sema != NULL);
118 122
119 old_level = intr_disable (); 123 old_level = intr_disable ();
120 if (!list_empty (&sema->waiters)) 124 if (!list_empty (&sema->waiters))
121 thread_unblock (list_entry (list_pop_front (&sema->waiters), 125 {
122 struct thread, elem)); 126 struct thread *t = list_entry (list_pop_front (&sema->waiters),
127 struct thread, elem);
128 thread_unblock (t);
129 /* thread_unblock() doesn't yield so check if there's a need */
130 if (t->priority > thread_current ()->priority)
131 yield = true;
132 }
123 sema->value++; 133 sema->value++;
124 intr_set_level (old_level); 134 intr_set_level (old_level);
135
136 if (yield)
137 thread_yield();
125} 138}
126 139
127static void sema_test_helper (void *sema_); 140static void sema_test_helper (void *sema_);
@@ -187,11 +200,11 @@ lock_init (struct lock *lock)
187 200
188/* comparison function for our descending ordered lock list. */ 201/* comparison function for our descending ordered lock list. */
189static bool 202static bool
190lock_list_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b, 203lock_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b,
191 void *AUX UNUSED) 204 void *AUX UNUSED)
192{ 205{
193 struct lock *l1 = list_entry (a, struct lock, elem); 206 const struct lock *l1 = list_entry (a, struct lock, elem);
194 struct lock *l2 = list_entry (b, struct lock, elem); 207 const struct lock *l2 = list_entry (b, struct lock, elem);
195 /* descending order - put newer in front */ 208 /* descending order - put newer in front */
196 return (l1->priority >= l2->priority); 209 return (l1->priority >= l2->priority);
197} 210}
@@ -226,7 +239,7 @@ lock_acquire (struct lock *lock)
226 /* the lock priority changed so we need to sort the lock list of the lock holder */ 239 /* the lock priority changed so we need to sort the lock list of the lock holder */
227 list_remove (&lock->elem); 240 list_remove (&lock->elem);
228 list_insert_ordered (&lock->holder->locks, &lock->elem, 241 list_insert_ordered (&lock->holder->locks, &lock->elem,
229 lock_list_priority_cmp_greater, NULL); 242 lock_priority_cmp_greater, NULL);
230 243
231 /* finally donate our priority */ 244 /* finally donate our priority */
232 thread_donate_priority (cur, lock->holder); 245 thread_donate_priority (cur, lock->holder);
@@ -241,7 +254,7 @@ lock_acquire (struct lock *lock)
241 254
242 /* save the locks we hold in descending order of their priority */ 255 /* save the locks we hold in descending order of their priority */
243 list_insert_ordered (&lock->holder->locks, &lock->elem, 256 list_insert_ordered (&lock->holder->locks, &lock->elem,
244 lock_list_priority_cmp_greater, NULL); 257 lock_priority_cmp_greater, NULL);
245} 258}
246 259
247/* Tries to acquires LOCK and returns true if successful or false 260/* Tries to acquires LOCK and returns true if successful or false
@@ -315,6 +328,7 @@ struct semaphore_elem
315 { 328 {
316 struct list_elem elem; /* List element. */ 329 struct list_elem elem; /* List element. */
317 struct semaphore semaphore; /* This semaphore. */ 330 struct semaphore semaphore; /* This semaphore. */
331 int priority; /* the priority of the waiting thread */
318 }; 332 };
319 333
320/* Initializes condition variable COND. A condition variable 334/* Initializes condition variable COND. A condition variable
@@ -328,6 +342,16 @@ cond_init (struct condition *cond)
328 list_init (&cond->waiters); 342 list_init (&cond->waiters);
329} 343}
330 344
345/* comparison function for our descending ordered condition waiters list. */
346static bool
347semaphore_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b,
348 void *aux UNUSED)
349{
350 const struct semaphore_elem *s1 = list_entry (a, struct semaphore_elem, elem);
351 const struct semaphore_elem *s2 = list_entry (b, struct semaphore_elem, elem);
352 return (s1->priority > s2->priority);
353}
354
331/* Atomically releases LOCK and waits for COND to be signaled by 355/* Atomically releases LOCK and waits for COND to be signaled by
332 some other piece of code. After COND is signaled, LOCK is 356 some other piece of code. After COND is signaled, LOCK is
333 reacquired before returning. LOCK must be held before calling 357 reacquired before returning. LOCK must be held before calling
@@ -359,8 +383,11 @@ cond_wait (struct condition *cond, struct lock *lock)
359 ASSERT (lock_held_by_current_thread (lock)); 383 ASSERT (lock_held_by_current_thread (lock));
360 384
361 sema_init (&waiter.semaphore, 0); 385 sema_init (&waiter.semaphore, 0);
362 /* add thread to our ordered waiters list */ 386 /* set condition priority */
363 list_insert_ordered (&cond->waiters, &waiter.elem, &priority_list_cmp_greater, NULL); 387 waiter.priority = thread_current ()->priority;
388 /* and add condition to our ordered waiters list */
389 list_insert_ordered (&cond->waiters, &waiter.elem,
390 &semaphore_priority_cmp_greater, NULL);
364 lock_release (lock); 391 lock_release (lock);
365 sema_down (&waiter.semaphore); 392 sema_down (&waiter.semaphore);
366 lock_acquire (lock); 393 lock_acquire (lock);
diff --git a/threads/thread.c b/threads/thread.c
index 17d21bd..a7db106 100644
--- a/threads/thread.c
+++ b/threads/thread.c
@@ -73,11 +73,11 @@ static tid_t allocate_tid (void);
73 73
74/* comparison function for our descending ordered ready list. */ 74/* comparison function for our descending ordered ready list. */
75bool 75bool
76priority_list_cmp_greater(const struct list_elem *a, const struct list_elem *b, 76thread_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b,
77 void *AUX UNUSED) 77 void *AUX UNUSED)
78{ 78{
79 struct thread *t1 = list_entry (a, struct thread, elem); 79 const struct thread *t1 = list_entry (a, struct thread, elem);
80 struct thread *t2 = list_entry (b, struct thread, elem); 80 const struct thread *t2 = list_entry (b, struct thread, elem);
81 return (t1->priority > t2->priority); 81 return (t1->priority > t2->priority);
82} 82}
83 83
@@ -264,7 +264,7 @@ thread_unblock (struct thread *t)
264 old_level = intr_disable (); 264 old_level = intr_disable ();
265 ASSERT (t->status == THREAD_BLOCKED); 265 ASSERT (t->status == THREAD_BLOCKED);
266 /* add thread to our ordered ready_list */ 266 /* add thread to our ordered ready_list */
267 list_insert_ordered (&ready_list, &t->elem, &priority_list_cmp_greater, NULL); 267 list_insert_ordered (&ready_list, &t->elem, &thread_priority_cmp_greater, NULL);
268 t->status = THREAD_READY; 268 t->status = THREAD_READY;
269 intr_set_level (old_level); 269 intr_set_level (old_level);
270} 270}
@@ -335,7 +335,7 @@ thread_yield (void)
335 335
336 old_level = intr_disable (); 336 old_level = intr_disable ();
337 if (cur != idle_thread) 337 if (cur != idle_thread)
338 list_insert_ordered (&ready_list, &cur->elem, &priority_list_cmp_greater, NULL); 338 list_insert_ordered (&ready_list, &cur->elem, &thread_priority_cmp_greater, NULL);
339 cur->status = THREAD_READY; 339 cur->status = THREAD_READY;
340 schedule (); 340 schedule ();
341 intr_set_level (old_level); 341 intr_set_level (old_level);
@@ -390,7 +390,7 @@ thread_other_set_priority (struct thread *t, int new_priority)
390 { 390 {
391 /* sort our ordered list */ 391 /* sort our ordered list */
392 list_remove (&t->elem); 392 list_remove (&t->elem);
393 list_insert_ordered (&ready_list, &t->elem, &priority_list_cmp_greater, NULL); 393 list_insert_ordered (&ready_list, &t->elem, &thread_priority_cmp_greater, NULL);
394 } 394 }
395 else if (t->status == THREAD_RUNNING && !list_empty (&ready_list)) 395 else if (t->status == THREAD_RUNNING && !list_empty (&ready_list))
396 { 396 {
diff --git a/threads/thread.h b/threads/thread.h
index a6ef25d..8bc6512 100644
--- a/threads/thread.h
+++ b/threads/thread.h
@@ -118,7 +118,7 @@ struct thread
118 Controlled by kernel command-line option "-o mlfqs". */ 118 Controlled by kernel command-line option "-o mlfqs". */
119extern bool thread_mlfqs; 119extern bool thread_mlfqs;
120 120
121bool priority_list_cmp_greater (const struct list_elem *a, const struct list_elem *b, 121bool thread_priority_cmp_greater (const struct list_elem *a, const struct list_elem *b,
122 void *aux); 122 void *aux);
123 123
124void thread_init (void); 124void thread_init (void);