From 4ed64cf173966d447b9851717a0013bd122d242c Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 10:47:38 +0100 Subject: [PATCH 01/13] Add guard in thread_set_priority ensuring priority values are within correct range --- src/threads/thread.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/threads/thread.c b/src/threads/thread.c index 30ca2bd..ed305ad 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -354,6 +354,7 @@ thread_foreach (thread_action_func *func, void *aux) void thread_set_priority (int new_priority) { + ASSERT (PRI_MIN <= new_priority && new_priority <= PRI_MAX); thread_current ()->priority = new_priority; } -- 2.49.1 From 1821d73b09616e61e5d8344db49ad42b7492723d Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 11:50:04 +0100 Subject: [PATCH 02/13] Add comparison function for thread list elements based on thread priority --- src/threads/thread.c | 11 +++++++++++ src/threads/thread.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/src/threads/thread.c b/src/threads/thread.c index ed305ad..8e18ca9 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -599,6 +599,17 @@ allocate_tid (void) return tid; } +/* Returns true iff the priority of the first list element's thread is greater + than that of the second list element's thread. */ +bool +thread_priority_greater (const struct list_elem *a, const struct list_elem *b, + void *aux) +{ + struct thread *ta = list_entry (a, struct thread, elem); + struct thread *tb = list_entry (b, struct thread, elem); + return ta->priority > tb->priority; +} + /* Offset of `stack' member within `struct thread'. Used by switch.S, which can't figure it out on its own. */ uint32_t thread_stack_ofs = offsetof (struct thread, stack); diff --git a/src/threads/thread.h b/src/threads/thread.h index f36d7ac..0503af9 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -139,4 +139,7 @@ void thread_set_nice (int); int thread_get_recent_cpu (void); int thread_get_load_avg (void); +/* Returns true iff the priority of the first list element's thread is greater + than that of the second list element's thread. */ +list_less_func thread_priority_greater; #endif /* threads/thread.h */ -- 2.49.1 From f1fa7d2ffbfba3a562f60542171bed75d85fc2a0 Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 11:51:40 +0100 Subject: [PATCH 03/13] Reformat thread_priority_greater to fit code style --- src/threads/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads/thread.c b/src/threads/thread.c index 8e18ca9..dfc70df 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -603,7 +603,7 @@ allocate_tid (void) than that of the second list element's thread. */ bool thread_priority_greater (const struct list_elem *a, const struct list_elem *b, - void *aux) + void *aux) { struct thread *ta = list_entry (a, struct thread, elem); struct thread *tb = list_entry (b, struct thread, elem); -- 2.49.1 From d4d5a7a937ecefa53915e6c82538d73fa015123f Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 12:01:03 +0100 Subject: [PATCH 04/13] Update thread_priority_greater function signature to explicitly signal unused parameter --- src/threads/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads/thread.c b/src/threads/thread.c index dfc70df..146a430 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -603,7 +603,7 @@ allocate_tid (void) than that of the second list element's thread. */ bool thread_priority_greater (const struct list_elem *a, const struct list_elem *b, - void *aux) + void *aux UNUSED) { struct thread *ta = list_entry (a, struct thread, elem); struct thread *tb = list_entry (b, struct thread, elem); -- 2.49.1 From 79061fcb9b45219af33d2439fc91af9a5a10d463 Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 13:51:41 +0100 Subject: [PATCH 05/13] Update thread module to maintain list of ready threads in descending order of priority --- src/threads/thread.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/threads/thread.c b/src/threads/thread.c index 146a430..709fcef 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -256,7 +256,7 @@ thread_unblock (struct thread *t) old_level = intr_disable (); ASSERT (t->status == THREAD_BLOCKED); - list_push_back (&ready_list, &t->elem); + list_insert_ordered (&ready_list, &t->elem, &thread_priority_greater, NULL); t->status = THREAD_READY; intr_set_level (old_level); } @@ -327,7 +327,8 @@ thread_yield (void) old_level = intr_disable (); if (cur != idle_thread) - list_push_back (&ready_list, &cur->elem); + list_insert_ordered (&ready_list, &cur->elem, thread_priority_greater, + NULL); cur->status = THREAD_READY; schedule (); intr_set_level (old_level); -- 2.49.1 From 6855a48603ac6a53b4b55d390f49b396f6623013 Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 13:53:48 +0100 Subject: [PATCH 06/13] Update semaphore code to wake highest priority thread, and run if required --- src/threads/synch.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/threads/synch.c b/src/threads/synch.c index 7776cb0..e1bcf9f 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -68,7 +68,8 @@ sema_down (struct semaphore *sema) old_level = intr_disable (); while (sema->value == 0) { - list_push_back (&sema->waiters, &thread_current ()->elem); + list_insert_ordered (&sema->waiters, &thread_current ()->elem, + &thread_priority_greater, NULL); thread_block (); } sema->value--; @@ -118,6 +119,7 @@ sema_up (struct semaphore *sema) struct thread, elem)); sema->value++; intr_set_level (old_level); + thread_yield (); } static void sema_test_helper (void *sema_); -- 2.49.1 From 54b46806babf9412e8c5b22d9fb28cd7ccc868ca Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 15:12:01 +0100 Subject: [PATCH 07/13] Update thread creation to yield thread in case it's no longer the highest priority --- src/threads/thread.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/threads/thread.c b/src/threads/thread.c index 709fcef..6b48788 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -219,6 +219,7 @@ thread_create (const char *name, int priority, /* Add to run queue. */ thread_unblock (t); + thread_yield (); return tid; } -- 2.49.1 From 3c1a26b668c38b8a205194f2c52d47b57e7d9f5a Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 15:14:05 +0100 Subject: [PATCH 08/13] Update setting of thread priorities to yield in case a higher priority thread requires control --- src/threads/thread.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/threads/thread.c b/src/threads/thread.c index 6b48788..6c1dcca 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -358,6 +358,7 @@ thread_set_priority (int new_priority) { ASSERT (PRI_MIN <= new_priority && new_priority <= PRI_MAX); thread_current ()->priority = new_priority; + thread_yield (); } /* Returns the current thread's priority. */ -- 2.49.1 From 163b7f9016162f976090c172f9dba655b0f54aaa Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 15:38:31 +0100 Subject: [PATCH 09/13] Update setting of priority of threads to only yield when current thread's priority has been lowered --- src/threads/thread.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/threads/thread.c b/src/threads/thread.c index 6c1dcca..3a428f1 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -357,8 +357,11 @@ void thread_set_priority (int new_priority) { ASSERT (PRI_MIN <= new_priority && new_priority <= PRI_MAX); + int old_priority = thread_get_priority (); + thread_current ()->priority = new_priority; - thread_yield (); + if (new_priority < old_priority) + thread_yield (); } /* Returns the current thread's priority. */ -- 2.49.1 From c32a69a368e6539c5791d3d69e0bb088ff41d237 Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Tue, 15 Oct 2024 17:00:02 +0100 Subject: [PATCH 10/13] Update repository settings to ignore shell scripts --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5d8d05c..9546b0d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ #ignore pdf files (just keep source files) *.pdf +#ignore shell scripts (only used for testing) +*.sh + #ignore junk files from latex output *.out *.log -- 2.49.1 From 88967acdaa49de4b71294cce988687f06c192e19 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Thu, 17 Oct 2024 08:53:53 +0100 Subject: [PATCH 11/13] Update cond_wait to insert into waiters list in sorted order of priority --- src/threads/synch.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/threads/synch.c b/src/threads/synch.c index b588656..2431494 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -355,7 +355,14 @@ cond_wait (struct condition *cond, struct lock *lock) ASSERT (lock_held_by_current_thread (lock)); sema_init (&waiter.semaphore, 0); - list_push_back (&cond->waiters, &waiter.elem); + + /* Insert the semaphore_elem into the waiters list in order of priority. + We pass the priority of the current thread as aux to sema_priority_more + because the thread has not been sema'd down yet (See sema_priority_more) */ + int priority = thread_current ()->priority; + list_insert_ordered (&cond->waiters, &waiter.elem, sema_priority_more, + &priority); + lock_release (lock); sema_down (&waiter.semaphore); lock_acquire (lock); -- 2.49.1 From 810a5376b93ae1f4a0104708332e42383b3996b6 Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Thu, 17 Oct 2024 08:55:29 +0100 Subject: [PATCH 12/13] Implement priority scheduling for condition variables --- src/threads/synch.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/threads/synch.c b/src/threads/synch.c index e1bcf9f..0cb9989 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -266,6 +266,35 @@ cond_init (struct condition *cond) list_init (&cond->waiters); } +/* Returns true iff the priority of the only thread in the first singleton + semaphore is greater than the priority of the only thread in the second + singleton semaphore. + + If used for insertion, the third argument must be a pointer to struct + list_elem for the thread being inserted, otherwise must be NULL. */ +static bool +singleton_sema_priority_greater (const struct list_elem *a, + const struct list_elem *b, + void *insertingThread) +{ + struct list_elem *te_a, *te_b; + + te_b = list_front ( + &list_entry (b, struct semaphore_elem, elem)->semaphore.waiters); + + if (insertingThread == NULL) + { + te_a = list_front ( + &list_entry (a, struct semaphore_elem, elem)->semaphore.waiters); + } + else + { + te_a = insertingThread; + } + + return thread_priority_greater (te_a, te_b, NULL); +} + /* 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 @@ -297,7 +326,9 @@ cond_wait (struct condition *cond, struct lock *lock) ASSERT (lock_held_by_current_thread (lock)); sema_init (&waiter.semaphore, 0); - list_push_back (&cond->waiters, &waiter.elem); + list_insert_ordered (&cond->waiters, &waiter.elem, + singleton_sema_priority_greater, + &thread_current ()->elem); lock_release (lock); sema_down (&waiter.semaphore); lock_acquire (lock); -- 2.49.1 From e38e1400a2cbd12227a6edd36a8b98592ccce4e6 Mon Sep 17 00:00:00 2001 From: Themis Demetriades Date: Thu, 17 Oct 2024 09:19:09 +0100 Subject: [PATCH 13/13] Update singleton_sema_priority_greater function description for clarity --- src/threads/synch.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/threads/synch.c b/src/threads/synch.c index 0cb9989..12fdf11 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -270,8 +270,11 @@ cond_init (struct condition *cond) semaphore is greater than the priority of the only thread in the second singleton semaphore. - If used for insertion, the third argument must be a pointer to struct - list_elem for the thread being inserted, otherwise must be NULL. */ + Where this function is used for insertion in a singleton semaphore list, the + third argument may specify a list_elem * to assume corresponds to the thread + waiting for the inserting semaphore. For correctness, ensure this thread + calls sema_down () for this semaphore before future list accesses. */ + static bool singleton_sema_priority_greater (const struct list_elem *a, const struct list_elem *b, -- 2.49.1