diff --git a/src/devices/timer.c b/src/devices/timer.c index e4abd1dd07eb96e01101e1e3e4988119c61f6bb2..fdfd567dcb6c88dbedebdd4cdf94102ccf541895 100644 --- a/src/devices/timer.c +++ b/src/devices/timer.c @@ -106,7 +106,7 @@ timer_sleep (int64_t ticks) // check_front struct thread* t = thread_current (); - // t->status = THREAD_ASLEEP; // TODO gets overwritten by thread_yield + t->status = THREAD_ASLEEP; // TODO gets overwritten by thread_yield t->sleep_until = start + ticks; thread_yield (); diff --git a/src/devices/timer.h b/src/devices/timer.h index 45a3f72e1127cd02f97b79d995277bec67a0812f..eed59838c2d9c6e2ea706c5ebcd997d735fb2c17 100644 --- a/src/devices/timer.h +++ b/src/devices/timer.h @@ -7,6 +7,8 @@ /* Number of timer interrupts per second. */ #define TIMER_FREQ 100 +#define max(a, b) ((a) > (b) ? (a) : (b)) + void timer_init (void); void timer_calibrate (void); diff --git a/src/threads/thread.c b/src/threads/thread.c index 9da537fe89bfb3cfe64ae577a3bb520d31bb20da..c2bda5383bec9040f549a935377506acd952eb13 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -258,7 +258,7 @@ thread_current (void) of stack, so a few big automatic arrays or moderate recursion can cause stack overflow. */ ASSERT (is_thread (t)); - ASSERT (t->status == THREAD_RUNNING); + // ASSERT (t->status == THREAD_RUNNING); return t; } @@ -302,7 +302,10 @@ thread_yield (void) old_level = intr_disable (); if (cur != idle_thread) list_push_back (&ready_list, &cur->elem); - cur->status = THREAD_READY; + + if (cur->status != THREAD_ASLEEP) { + cur->status = THREAD_READY; + } schedule (); intr_set_level (old_level); } @@ -523,30 +526,43 @@ static void schedule (void) { struct thread *cur = running_thread (); - struct thread *next = next_thread_to_run (); + struct thread *next ;//= next_thread_to_run (); struct thread *prev = NULL; - struct thread* init_next = next; ASSERT (intr_get_level () == INTR_OFF); /* set to THREAD_READY in thread_yield() */ ASSERT (cur->status != THREAD_RUNNING); - ASSERT (is_thread (next)); //#ifdef USERPROG - - while (next->status == THREAD_ASLEEP - && next->sleep_until < timer_ticks ()) - { - list_push_back (&ready_list, &next->elem); - next = list_entry (list_pop_front (&ready_list), struct thread, elem); - - if (next == init_next) { - next = idle_thread; - break; + for (struct list_elem* e = list_begin(&ready_list); + e != list_end (&ready_list); + e = list_next (e)) { + next = list_entry (e, struct thread, elem); + switch (next->status) { + case THREAD_ASLEEP: + if (next->sleep_until <= timer_ticks()) { + next->status = THREAD_READY; + list_remove (e); + } + break; + case THREAD_READY: + list_remove (e); + goto swap_in; + break; + default: + continue; } } + next = idle_thread; + +swap_in: + +// we never pop + + ASSERT (is_thread (next)); + // if all sleeping, busy wait with interrupt on //#endif