Merge branch 'merged-complete' into 'master'

Merge complete code base into master

See merge request lab2425_autumn/pintos_22!15
This commit is contained in:
Dias Alberto, Ethan
2024-10-23 19:05:45 +00:00
2 changed files with 72 additions and 75 deletions

View File

@@ -251,19 +251,27 @@ lock_acquire (struct lock *lock)
ASSERT (!lock_held_by_current_thread (lock)); ASSERT (!lock_held_by_current_thread (lock));
struct thread *t = thread_current (); struct thread *t = thread_current ();
enum intr_level old_level = intr_disable ();
if (lock->holder != NULL) if(!thread_mlfqs)
{ {
t->waiting_lock = lock;
donate_priority (lock->holder); 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); sema_down (&lock->semaphore);
lock->holder = thread_current (); 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 /* 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 != NULL);
ASSERT (lock_held_by_current_thread (lock)); ASSERT (lock_held_by_current_thread (lock));
struct thread *current_thread = thread_current (); if (!thread_mlfqs)
struct thread *max_donor = NULL; {
struct thread *current_thread = thread_current ();
struct thread *max_donor = NULL;
struct list orphan_list; struct list orphan_list;
list_init (&orphan_list); list_init (&orphan_list);
enum intr_level old_level = intr_disable (); enum intr_level old_level = intr_disable ();
/* Loop through current thread's donors, removing the ones waiting for the /* Loop through current thread's donors, removing the ones waiting for the
lock being released and keeping track of them (within orphan_list). lock being released and keeping track of them (within orphan_list).
Also identifies the highest priority donor thread among them. */ Also identifies the highest priority donor thread among them. */
struct list_elem *tail = list_tail (&current_thread->donors_list); struct list_elem *tail = list_tail (&current_thread->donors_list);
struct list_elem *e = list_begin (&current_thread->donors_list); struct list_elem *e = list_begin (&current_thread->donors_list);
while (e != tail) while (e != tail)
{ {
struct thread *donor = list_entry (e, struct thread, donor_elem); struct thread *donor = list_entry (e, struct thread, donor_elem);
struct list_elem *next = list_next (e); struct list_elem *next = list_next (e);
/* Excludes donors that aren't waiting for the lock being released, /* Excludes donors that aren't waiting for the lock being released,
and tracks the rest. */ and tracks the rest. */
if (donor->waiting_lock == lock) if (donor->waiting_lock == lock)
{ {
list_remove (e); list_remove (e);
list_push_back (&orphan_list, e); list_push_back (&orphan_list, e);
/* Identify highest priority donor. */ /* Identify highest priority donor. */
if (max_donor == NULL || donor->priority > max_donor->priority) if (max_donor == NULL || donor->priority > max_donor->priority)
max_donor = donor; max_donor = donor;
} }
e = next; e = next;
} }
/* If there exists a maximum donor thread waiting for this lock to be /* If there exists a maximum donor thread waiting for this lock to be
released, transfer the remaining orphaned donors to its donor list. */ released, transfer the remaining orphaned donors to its donor list. */
if (max_donor != NULL) if (max_donor != NULL)
{ {
while (!list_empty (&orphan_list)) while (!list_empty (&orphan_list))
list_push_back (&max_donor->donors_list, list_pop_front (&orphan_list)); list_push_back (&max_donor->donors_list, list_pop_front (&orphan_list));
} }
intr_set_level (old_level); intr_set_level (old_level);
/* Removal of donors to this thread may change its effective priority, /* Removal of donors to this thread may change its effective priority,
so recalculate. */ so recalculate. */
thread_recalculate_priority (); thread_recalculate_priority ();
}
lock->holder = NULL; lock->holder = NULL;
sema_up (&lock->semaphore); sema_up (&lock->semaphore);

View File

@@ -73,8 +73,6 @@ static bool is_thread (struct thread *) UNUSED;
static void *alloc_frame (struct thread *, size_t size); static void *alloc_frame (struct thread *, size_t size);
static int calculate_bsd_priority (fp32_t recent_cpu, int nice); static int calculate_bsd_priority (fp32_t recent_cpu, int nice);
static void thread_update_recent_cpu (struct thread *t, void *aux UNUSED); 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); static void schedule (void);
void thread_schedule_tail (struct thread *prev); void thread_schedule_tail (struct thread *prev);
static tid_t allocate_tid (void); static tid_t allocate_tid (void);
@@ -164,7 +162,7 @@ thread_tick (void)
size_t ready = threads_ready (); size_t ready = threads_ready ();
if (t != idle_thread) if (t != idle_thread)
ready++; 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); fp32_t new_coeff = fp_div_int (int_to_fp (ready), 60);
load_avg = fp_add (old_coeff, new_coeff); load_avg = fp_add (old_coeff, new_coeff);
@@ -293,11 +291,9 @@ thread_unblock (struct thread *t)
old_level = intr_disable (); old_level = intr_disable ();
ASSERT (t->status == THREAD_BLOCKED); ASSERT (t->status == THREAD_BLOCKED);
if (thread_mlfqs)
list_insert_ordered (&ready_list, &t->elem, thread_priority_less, NULL); /* Insert the thread back into the ready list in priority order. */
else 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; t->status = THREAD_READY;
intr_set_level (old_level); intr_set_level (old_level);
@@ -371,12 +367,10 @@ thread_yield (void)
if (cur != idle_thread) if (cur != idle_thread)
{ {
if (thread_mlfqs)
list_insert_ordered (&ready_list, &cur->elem, thread_priority_less, /* Insert the thread back into the ready list in priority order. */
NULL); list_insert_ordered(&ready_list, &cur->elem, priority_more, 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; cur->status = THREAD_READY;
@@ -473,13 +467,15 @@ thread_update_recent_cpu (struct thread *t, void *aux UNUSED)
= fp_add_int (fp_mul (recent_cpu_coeff, curr_recent_cpu), t->nice); = fp_add_int (fp_mul (recent_cpu_coeff, curr_recent_cpu), t->nice);
// recent_cpu was updated, update priority. // recent_cpu was updated, update priority.
t->priority = calculate_bsd_priority (t->recent_cpu, t->nice); t->priority = calculate_bsd_priority (t->recent_cpu, t->nice);
}
/* Recalculates the effective priority of the current thread. */ /* Recalculates the effective priority of the current thread. */
void void
thread_recalculate_priority (void) thread_recalculate_priority (void)
{ {
struct thread *t = thread_current (); struct thread *t = thread_current ();
ASSERT(!thread_mlfqs)
enum intr_level old_level = intr_disable (); enum intr_level old_level = intr_disable ();
t->priority = t->base_priority; t->priority = t->base_priority;
@@ -639,8 +635,6 @@ init_thread (struct thread *t, const char *name, int nice, int priority,
strlcpy (t->name, name, sizeof t->name); strlcpy (t->name, name, sizeof t->name);
t->stack = (uint8_t *) t + PGSIZE; t->stack = (uint8_t *) t + PGSIZE;
t->priority
= thread_mlfqs ? calculate_bsd_priority (recent_cpu, nice) : priority;
t->nice = nice; t->nice = nice;
t->recent_cpu = recent_cpu; t->recent_cpu = recent_cpu;
@@ -649,7 +643,7 @@ init_thread (struct thread *t, const char *name, int nice, int priority,
t->magic = THREAD_MAGIC; t->magic = THREAD_MAGIC;
list_init (&t->donors_list); 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; t->waiting_lock = NULL;
old_level = intr_disable (); old_level = intr_disable ();
@@ -734,6 +728,9 @@ thread_schedule_tail (struct thread *prev)
static int static int
calculate_bsd_priority (fp32_t recent_cpu, int nice) calculate_bsd_priority (fp32_t recent_cpu, int nice)
{ {
ASSERT(thread_mlfqs);
int priority = PRI_MAX - (fp_round (recent_cpu) / 4) - (nice * 2); int priority = PRI_MAX - (fp_round (recent_cpu) / 4) - (nice * 2);
if (priority < PRI_MIN) if (priority < PRI_MIN)
return PRI_MIN; return PRI_MIN;
@@ -742,17 +739,6 @@ calculate_bsd_priority (fp32_t recent_cpu, int nice)
return priority; 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 /* Schedules a new process. At entry, interrupts must be off and
the running process's state must have been changed from the running process's state must have been changed from
running to some other state. This function finds another running to some other state. This function finds another