From c357126cc15e329831624ab110f0bfce3eae9ec7 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 23 Oct 2024 17:51:48 +0100 Subject: [PATCH 1/4] fix missing curly brace --- src/threads/thread.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/threads/thread.c b/src/threads/thread.c index 70d5667..aa9761d 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -372,11 +372,15 @@ thread_yield (void) if (cur != idle_thread) { if (thread_mlfqs) + { list_insert_ordered (&ready_list, &cur->elem, thread_priority_less, NULL); + } else + { /* Insert the thread back into the ready list in priority order. */ list_insert_ordered(&ready_list, &cur->elem, priority_more, NULL); + } } cur->status = THREAD_READY; @@ -473,7 +477,7 @@ thread_update_recent_cpu (struct thread *t, void *aux UNUSED) = fp_add_int (fp_mul (recent_cpu_coeff, curr_recent_cpu), t->nice); // recent_cpu was updated, update priority. t->priority = calculate_bsd_priority (t->recent_cpu, t->nice); - +} /* Recalculates the effective priority of the current thread. */ void thread_recalculate_priority (void) From 1fb101c365bb886f86f80ef5738f86ff48a3256e Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 23 Oct 2024 18:56:48 +0100 Subject: [PATCH 2/4] remove repeated comparator and reorder thread_init operations --- src/threads/thread.c | 41 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/src/threads/thread.c b/src/threads/thread.c index aa9761d..c64bc87 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -73,8 +73,6 @@ static bool is_thread (struct thread *) UNUSED; static void *alloc_frame (struct thread *, size_t size); static int calculate_bsd_priority (fp32_t recent_cpu, int nice); static void thread_update_recent_cpu (struct thread *t, void *aux UNUSED); -static bool thread_priority_less (const struct list_elem *a, - const struct list_elem *b, void *aux UNUSED); static void schedule (void); void thread_schedule_tail (struct thread *prev); static tid_t allocate_tid (void); @@ -164,7 +162,7 @@ thread_tick (void) size_t ready = threads_ready (); if (t != idle_thread) ready++; - fp32_t old_coeff = fp_mul (fp_div_int (int_to_fp (59), 60), load_avg); + fp32_t old_coeff = fp_div_int (fp_mul_int(load_avg, 59), 60); fp32_t new_coeff = fp_div_int (int_to_fp (ready), 60); load_avg = fp_add (old_coeff, new_coeff); @@ -293,11 +291,9 @@ thread_unblock (struct thread *t) old_level = intr_disable (); ASSERT (t->status == THREAD_BLOCKED); - if (thread_mlfqs) - list_insert_ordered (&ready_list, &t->elem, thread_priority_less, NULL); - else - /* Insert the thread back into the ready list in priority order. */ - list_insert_ordered(&ready_list, &t->elem, priority_more, NULL); + + /* Insert the thread back into the ready list in priority order. */ + list_insert_ordered(&ready_list, &t->elem, priority_more, NULL); t->status = THREAD_READY; intr_set_level (old_level); @@ -371,16 +367,10 @@ thread_yield (void) if (cur != idle_thread) { - if (thread_mlfqs) - { - list_insert_ordered (&ready_list, &cur->elem, thread_priority_less, - NULL); - } - else - { - /* Insert the thread back into the ready list in priority order. */ - list_insert_ordered(&ready_list, &cur->elem, priority_more, NULL); - } + + /* Insert the thread back into the ready list in priority order. */ + list_insert_ordered(&ready_list, &cur->elem, priority_more, NULL); + } cur->status = THREAD_READY; @@ -643,8 +633,6 @@ init_thread (struct thread *t, const char *name, int nice, int priority, strlcpy (t->name, name, sizeof t->name); t->stack = (uint8_t *) t + PGSIZE; - t->priority - = thread_mlfqs ? calculate_bsd_priority (recent_cpu, nice) : priority; t->nice = nice; t->recent_cpu = recent_cpu; @@ -653,7 +641,7 @@ init_thread (struct thread *t, const char *name, int nice, int priority, t->magic = THREAD_MAGIC; list_init (&t->donors_list); - t->priority = t->base_priority; + t->priority = thread_mlfqs ? calculate_bsd_priority (recent_cpu, nice) : t->base_priority; t->waiting_lock = NULL; old_level = intr_disable (); @@ -746,17 +734,6 @@ calculate_bsd_priority (fp32_t recent_cpu, int nice) return priority; } -/* Returns true if thread a's priority is strictly greater than - thread b's priority. */ -static bool -thread_priority_less (const struct list_elem *a, const struct list_elem *b, - void *aux UNUSED) -{ - struct thread *ta = list_entry (a, struct thread, elem); - struct thread *tb = list_entry (b, struct thread, elem); - return ta->priority > tb->priority; -} - /* Schedules a new process. At entry, interrupts must be off and the running process's state must have been changed from running to some other state. This function finds another From d8c843f16a852bc5191b113eb5bb90b63a82f356 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 23 Oct 2024 19:37:27 +0100 Subject: [PATCH 3/4] add mlfqs condition checking in synchronisation primitives --- src/threads/synch.c | 101 ++++++++++++++++++++++++------------------- src/threads/thread.c | 6 +++ 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/src/threads/synch.c b/src/threads/synch.c index 05b7d93..0ceb746 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -251,19 +251,27 @@ lock_acquire (struct lock *lock) ASSERT (!lock_held_by_current_thread (lock)); struct thread *t = thread_current (); - enum intr_level old_level = intr_disable (); - if (lock->holder != NULL) - { - t->waiting_lock = lock; - donate_priority (lock->holder); - } + if(!thread_mlfqs) + { + + enum intr_level old_level = intr_disable (); + + if (lock->holder != NULL) + { + t->waiting_lock = lock; + donate_priority (lock->holder); + } + + intr_set_level (old_level); + } + - intr_set_level (old_level); sema_down (&lock->semaphore); lock->holder = thread_current (); - t->waiting_lock = NULL; + if (!thread_mlfqs) + t->waiting_lock = NULL; } /* Tries to acquires LOCK and returns true if successful or false @@ -297,50 +305,53 @@ lock_release (struct lock *lock) ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); - struct thread *current_thread = thread_current (); - struct thread *max_donor = NULL; + if (!thread_mlfqs) + { + struct thread *current_thread = thread_current (); + struct thread *max_donor = NULL; - struct list orphan_list; - list_init (&orphan_list); + struct list orphan_list; + list_init (&orphan_list); - enum intr_level old_level = intr_disable (); - /* Loop through current thread's donors, removing the ones waiting for the - lock being released and keeping track of them (within orphan_list). - Also identifies the highest priority donor thread among them. */ - struct list_elem *tail = list_tail (¤t_thread->donors_list); - struct list_elem *e = list_begin (¤t_thread->donors_list); - while (e != tail) - { - struct thread *donor = list_entry (e, struct thread, donor_elem); - struct list_elem *next = list_next (e); + enum intr_level old_level = intr_disable (); + /* Loop through current thread's donors, removing the ones waiting for the + lock being released and keeping track of them (within orphan_list). + Also identifies the highest priority donor thread among them. */ + struct list_elem *tail = list_tail (¤t_thread->donors_list); + struct list_elem *e = list_begin (¤t_thread->donors_list); + while (e != tail) + { + struct thread *donor = list_entry (e, struct thread, donor_elem); + struct list_elem *next = list_next (e); - /* Excludes donors that aren't waiting for the lock being released, - and tracks the rest. */ - if (donor->waiting_lock == lock) - { - list_remove (e); - list_push_back (&orphan_list, e); + /* Excludes donors that aren't waiting for the lock being released, + and tracks the rest. */ + if (donor->waiting_lock == lock) + { + list_remove (e); + list_push_back (&orphan_list, e); - /* Identify highest priority donor. */ - if (max_donor == NULL || donor->priority > max_donor->priority) - max_donor = donor; - } + /* Identify highest priority donor. */ + if (max_donor == NULL || donor->priority > max_donor->priority) + max_donor = donor; + } - e = next; - } + e = next; + } - /* If there exists a maximum donor thread waiting for this lock to be - released, transfer the remaining orphaned donors to its donor list. */ - if (max_donor != NULL) - { - while (!list_empty (&orphan_list)) - list_push_back (&max_donor->donors_list, list_pop_front (&orphan_list)); - } + /* If there exists a maximum donor thread waiting for this lock to be + released, transfer the remaining orphaned donors to its donor list. */ + if (max_donor != NULL) + { + while (!list_empty (&orphan_list)) + list_push_back (&max_donor->donors_list, list_pop_front (&orphan_list)); + } - intr_set_level (old_level); - /* Removal of donors to this thread may change its effective priority, - so recalculate. */ - thread_recalculate_priority (); + intr_set_level (old_level); + /* Removal of donors to this thread may change its effective priority, + so recalculate. */ + thread_recalculate_priority (); + } lock->holder = NULL; sema_up (&lock->semaphore); diff --git a/src/threads/thread.c b/src/threads/thread.c index c64bc87..1a7ab68 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -473,6 +473,12 @@ void thread_recalculate_priority (void) { struct thread *t = thread_current (); + + if (thread_mlfqs) + { + t->priority = calculate_bsd_priority (t->recent_cpu, t->nice); + return; + } enum intr_level old_level = intr_disable (); t->priority = t->base_priority; From 20be75748cbb06dc5b775f7626e62e08768bba8e Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 23 Oct 2024 19:57:17 +0100 Subject: [PATCH 4/4] replace thread_mlfqs checks in priority calculations with assertions --- src/threads/thread.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/threads/thread.c b/src/threads/thread.c index 1a7ab68..cb60d1b 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -474,12 +474,8 @@ thread_recalculate_priority (void) { struct thread *t = thread_current (); - if (thread_mlfqs) - { - t->priority = calculate_bsd_priority (t->recent_cpu, t->nice); - return; - } - + ASSERT(!thread_mlfqs) + enum intr_level old_level = intr_disable (); t->priority = t->base_priority; @@ -732,6 +728,9 @@ thread_schedule_tail (struct thread *prev) static int calculate_bsd_priority (fp32_t recent_cpu, int nice) { + + ASSERT(thread_mlfqs); + int priority = PRI_MAX - (fp_round (recent_cpu) / 4) - (nice * 2); if (priority < PRI_MIN) return PRI_MIN;