From 57c893ae56f151efc96fabebbb4c8ec039cb56ef Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 8 May 2012 02:35:22 +0200 Subject: * fixed sema_up which didn't yield the cpu * fixed wrong condition comperator * renamed the comperator functions to better explain their compare element * current status: 3 of 18 tests failed --- threads/synch.c | 51 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) (limited to 'threads/synch.c') 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 @@ #include "threads/interrupt.h" #include "threads/thread.h" -static bool lock_list_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b, +static bool lock_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b, void *AUX UNUSED); +static bool semaphore_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b, + void *aux UNUSED); /* Initializes semaphore SEMA to VALUE. A semaphore is a nonnegative integer along with two atomic operators for @@ -72,7 +74,8 @@ sema_down (struct semaphore *sema) while (sema->value == 0) { /* add thread to our ordered waiters list */ - list_insert_ordered (&sema->waiters, &thread_current ()->elem, &priority_list_cmp_greater, NULL); + list_insert_ordered (&sema->waiters, &thread_current ()->elem, + &thread_priority_cmp_greater, NULL); thread_block (); } sema->value--; @@ -113,15 +116,25 @@ void sema_up (struct semaphore *sema) { enum intr_level old_level; + bool yield = false; ASSERT (sema != NULL); old_level = intr_disable (); - if (!list_empty (&sema->waiters)) - thread_unblock (list_entry (list_pop_front (&sema->waiters), - struct thread, elem)); + if (!list_empty (&sema->waiters)) + { + struct thread *t = list_entry (list_pop_front (&sema->waiters), + struct thread, elem); + thread_unblock (t); + /* thread_unblock() doesn't yield so check if there's a need */ + if (t->priority > thread_current ()->priority) + yield = true; + } sema->value++; intr_set_level (old_level); + + if (yield) + thread_yield(); } static void sema_test_helper (void *sema_); @@ -187,11 +200,11 @@ lock_init (struct lock *lock) /* comparison function for our descending ordered lock list. */ static bool -lock_list_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b, +lock_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b, void *AUX UNUSED) { - struct lock *l1 = list_entry (a, struct lock, elem); - struct lock *l2 = list_entry (b, struct lock, elem); + const struct lock *l1 = list_entry (a, struct lock, elem); + const struct lock *l2 = list_entry (b, struct lock, elem); /* descending order - put newer in front */ return (l1->priority >= l2->priority); } @@ -226,7 +239,7 @@ lock_acquire (struct lock *lock) /* the lock priority changed so we need to sort the lock list of the lock holder */ list_remove (&lock->elem); list_insert_ordered (&lock->holder->locks, &lock->elem, - lock_list_priority_cmp_greater, NULL); + lock_priority_cmp_greater, NULL); /* finally donate our priority */ thread_donate_priority (cur, lock->holder); @@ -241,7 +254,7 @@ lock_acquire (struct lock *lock) /* save the locks we hold in descending order of their priority */ list_insert_ordered (&lock->holder->locks, &lock->elem, - lock_list_priority_cmp_greater, NULL); + lock_priority_cmp_greater, NULL); } /* Tries to acquires LOCK and returns true if successful or false @@ -315,6 +328,7 @@ struct semaphore_elem { struct list_elem elem; /* List element. */ struct semaphore semaphore; /* This semaphore. */ + int priority; /* the priority of the waiting thread */ }; /* Initializes condition variable COND. A condition variable @@ -328,6 +342,16 @@ cond_init (struct condition *cond) list_init (&cond->waiters); } +/* comparison function for our descending ordered condition waiters list. */ +static bool +semaphore_priority_cmp_greater(const struct list_elem *a, const struct list_elem *b, + void *aux UNUSED) +{ + const struct semaphore_elem *s1 = list_entry (a, struct semaphore_elem, elem); + const struct semaphore_elem *s2 = list_entry (b, struct semaphore_elem, elem); + return (s1->priority > s2->priority); +} + /* Atomically releases LOCK and waits for COND to be signaled by some other piece of code. After COND is signaled, LOCK is reacquired before returning. LOCK must be held before calling @@ -359,8 +383,11 @@ cond_wait (struct condition *cond, struct lock *lock) ASSERT (lock_held_by_current_thread (lock)); sema_init (&waiter.semaphore, 0); - /* add thread to our ordered waiters list */ - list_insert_ordered (&cond->waiters, &waiter.elem, &priority_list_cmp_greater, NULL); + /* set condition priority */ + waiter.priority = thread_current ()->priority; + /* and add condition to our ordered waiters list */ + list_insert_ordered (&cond->waiters, &waiter.elem, + &semaphore_priority_cmp_greater, NULL); lock_release (lock); sema_down (&waiter.semaphore); lock_acquire (lock); -- cgit v1.2.3