Merge 'task1/priority-donation' into 'master' #14
@@ -270,15 +270,53 @@ lock_release (struct lock *lock)
|
|||||||
ASSERT (lock_held_by_current_thread (lock));
|
ASSERT (lock_held_by_current_thread (lock));
|
||||||
|
|
||||||
struct thread *current_thread = thread_current ();
|
struct thread *current_thread = thread_current ();
|
||||||
|
struct thread *max_donor = NULL;
|
||||||
|
|
||||||
|
struct list orphan_list;
|
||||||
|
list_init (&orphan_list);
|
||||||
|
|
||||||
|
/* 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 *tail = list_tail (¤t_thread->donors_list);
|
||||||
for (struct list_elem *e = list_begin (¤t_thread->donors_list);
|
struct list_elem *e = list_begin (¤t_thread->donors_list);
|
||||||
e != tail; e = e->next)
|
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);
|
||||||
|
|
||||||
|
/* Excludes donors that aren't waiting for the lock being released,
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Identify highest priority donor. */
|
||||||
|
if (max_donor == NULL || donor->priority > max_donor->priority)
|
||||||
|
max_donor = donor;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
tail = list_tail (&orphan_list);
|
||||||
|
e = list_begin (&orphan_list);
|
||||||
|
while (e != tail)
|
||||||
|
{
|
||||||
|
struct list_elem *next = list_next (e);
|
||||||
|
list_push_back (&max_donor->donors_list, e);
|
||||||
|
|
||||||
|
e = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Removal of donors to this thread may change its effective priority,
|
||||||
|
so recalculate. */
|
||||||
thread_recalculate_priority ();
|
thread_recalculate_priority ();
|
||||||
|
|
||||||
lock->holder = NULL;
|
lock->holder = NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user