summaryrefslogtreecommitdiffstats
path: root/threads
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2012-05-11 03:02:38 +0200
committermanuel <manuel@mausz.at>2012-05-11 03:02:38 +0200
commit04bb67f0e37a9144c4656d21f9f876f256de13e5 (patch)
tree9a81ebbfb4653258c5fa97cfe527dd7628f348b2 /threads
parent2ea82ff0203b1cc22b55900752d44514506eb01e (diff)
downloadprogos-04bb67f0e37a9144c4656d21f9f876f256de13e5.tar.gz
progos-04bb67f0e37a9144c4656d21f9f876f256de13e5.tar.bz2
progos-04bb67f0e37a9144c4656d21f9f876f256de13e5.zip
major: added support for nested priority donation
minor: replaced priority with a pointer to the waiting thread in condition handling status: 0/18 failed!
Diffstat (limited to 'threads')
-rw-r--r--threads/synch.c31
-rw-r--r--threads/thread.c1
-rw-r--r--threads/thread.h1
3 files changed, 24 insertions, 9 deletions
diff --git a/threads/synch.c b/threads/synch.c
index 6ffe1de..364b769 100644
--- a/threads/synch.c
+++ b/threads/synch.c
@@ -223,32 +223,45 @@ void
223lock_acquire (struct lock *lock) 223lock_acquire (struct lock *lock)
224{ 224{
225 struct thread *cur = thread_current (); 225 struct thread *cur = thread_current ();
226 struct lock *blocked_lock;
226 227
227 ASSERT (lock != NULL); 228 ASSERT (lock != NULL);
228 ASSERT (!intr_context ()); 229 ASSERT (!intr_context ());
229 ASSERT (!lock_held_by_current_thread (lock)); 230 ASSERT (!lock_held_by_current_thread (lock));
230 231
232 /* nested priority donation: save currently blocked lock */
231 if (lock->holder != NULL) 233 if (lock->holder != NULL)
234 cur->blocked_lock = lock;
235
236 /* nested priority donation: we loop backwards: lock -> holder -> blocked_lock
237 and donate our priority */
238 blocked_lock = lock;
239 while (blocked_lock != NULL && blocked_lock->holder != NULL)
232 { 240 {
233 /* check for a possible priority donation */ 241 /* check for a possible priority donation */
234 if (cur->priority > lock->priority) 242 if (cur->priority > blocked_lock->priority)
235 { 243 {
236 /* the new priority of this lock is our own priority */ 244 /* the new priority of this lock is our own priority */
237 lock->priority = cur->priority; 245 blocked_lock->priority = cur->priority;
238 246
239 /* the lock priority changed so we need to sort the lock list of the lock holder */ 247 /* the lock priority changed so we need to sort the lock list of the lock holder */
240 list_remove (&lock->elem); 248 list_remove (&blocked_lock->elem);
241 list_insert_ordered (&lock->holder->locks, &lock->elem, 249 list_insert_ordered (&blocked_lock->holder->locks, &blocked_lock->elem,
242 lock_priority_cmp_greater, NULL); 250 lock_priority_cmp_greater, NULL);
243 251
244 /* finally donate our priority */ 252 /* finally donate our priority */
245 thread_donate_priority (cur, lock->holder); 253 thread_donate_priority (cur, blocked_lock->holder);
246 } 254 }
255
256 blocked_lock = blocked_lock->holder->blocked_lock;
247 } 257 }
248 258
249 sema_down (&lock->semaphore); 259 sema_down (&lock->semaphore);
250 lock->holder = cur; 260 lock->holder = cur;
251 261
262 /* nested priority donation: we got the lock, reset blocked_lock */
263 cur->blocked_lock = NULL;
264
252 /* the priority of this lock is our own priority */ 265 /* the priority of this lock is our own priority */
253 lock->priority = cur->priority; 266 lock->priority = cur->priority;
254 267
@@ -325,7 +338,7 @@ struct semaphore_elem
325 { 338 {
326 struct list_elem elem; /* List element. */ 339 struct list_elem elem; /* List element. */
327 struct semaphore semaphore; /* This semaphore. */ 340 struct semaphore semaphore; /* This semaphore. */
328 int priority; /* the priority of the waiting thread */ 341 struct thread *thread; /* the current waiting thread */
329 }; 342 };
330 343
331/* Initializes condition variable COND. A condition variable 344/* Initializes condition variable COND. A condition variable
@@ -346,7 +359,7 @@ semaphore_priority_cmp_greater(const struct list_elem *a, const struct list_elem
346{ 359{
347 const struct semaphore_elem *s1 = list_entry (a, struct semaphore_elem, elem); 360 const struct semaphore_elem *s1 = list_entry (a, struct semaphore_elem, elem);
348 const struct semaphore_elem *s2 = list_entry (b, struct semaphore_elem, elem); 361 const struct semaphore_elem *s2 = list_entry (b, struct semaphore_elem, elem);
349 return (s1->priority > s2->priority); 362 return (s1->thread->priority > s2->thread->priority);
350} 363}
351 364
352/* Atomically releases LOCK and waits for COND to be signaled by 365/* Atomically releases LOCK and waits for COND to be signaled by
@@ -380,8 +393,8 @@ cond_wait (struct condition *cond, struct lock *lock)
380 ASSERT (lock_held_by_current_thread (lock)); 393 ASSERT (lock_held_by_current_thread (lock));
381 394
382 sema_init (&waiter.semaphore, 0); 395 sema_init (&waiter.semaphore, 0);
383 /* set condition priority */ 396 /* set thread of waiter */
384 waiter.priority = thread_current ()->priority; 397 waiter.thread = thread_current ();
385 /* and add condition to our ordered waiters list */ 398 /* and add condition to our ordered waiters list */
386 list_insert_ordered (&cond->waiters, &waiter.elem, 399 list_insert_ordered (&cond->waiters, &waiter.elem,
387 &semaphore_priority_cmp_greater, NULL); 400 &semaphore_priority_cmp_greater, NULL);
diff --git a/threads/thread.c b/threads/thread.c
index 358d3a1..61ab5d9 100644
--- a/threads/thread.c
+++ b/threads/thread.c
@@ -380,6 +380,7 @@ void
380thread_other_set_priority (struct thread *t, int new_priority) 380thread_other_set_priority (struct thread *t, int new_priority)
381{ 381{
382 ASSERT (is_thread (t)); 382 ASSERT (is_thread (t));
383 ASSERT (new_priority >= PRI_MIN && new_priority <= PRI_MAX);
383 384
384 if (t->priority == new_priority) 385 if (t->priority == new_priority)
385 return; 386 return;
diff --git a/threads/thread.h b/threads/thread.h
index 8cfafe6..fd4f8a6 100644
--- a/threads/thread.h
+++ b/threads/thread.h
@@ -111,6 +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 }; 115 };
115 116
116/* If false (default), use round-robin scheduler. 117/* If false (default), use round-robin scheduler.