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:
@@ -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 (¤t_thread->donors_list);
|
struct list_elem *tail = list_tail (¤t_thread->donors_list);
|
||||||
struct list_elem *e = list_begin (¤t_thread->donors_list);
|
struct list_elem *e = list_begin (¤t_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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user