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 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_); diff --git a/src/threads/thread.c b/src/threads/thread.c index 30ca2bd..3a428f1 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; } @@ -256,7 +257,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 +328,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); @@ -354,7 +356,12 @@ thread_foreach (thread_action_func *func, void *aux) 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; + if (new_priority < old_priority) + thread_yield (); } /* Returns the current thread's priority. */ @@ -598,6 +605,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 UNUSED) +{ + 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 */