From 349cc721b17effa62c8b18a7dccc5defc44472d3 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 2 Sep 2004 21:03:03 +0000 Subject: [PATCH] Don't destroy current thread's pagedir before activating a different one (!). thread_wake() needs to run with interrupts off. --- src/threads/synch.c | 6 +++--- src/threads/thread.c | 29 +++++++++++++++++------------ src/threads/thread.h | 4 ++-- src/userprog/addrspace.c | 3 +-- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/threads/synch.c b/src/threads/synch.c index ea38068..08ba8f4 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -51,7 +51,7 @@ sema_down (struct semaphore *sema) struct thread_elem te; te.thread = thread_current (); list_push_back (&sema->waiters, &te.elem); - thread_sleep (); + thread_block (); } sema->value--; intr_set_level (old_level); @@ -70,8 +70,8 @@ sema_up (struct semaphore *sema) old_level = intr_disable (); if (!list_empty (&sema->waiters)) - thread_wake (list_entry (list_pop_front (&sema->waiters), - struct thread_elem, elem)->thread); + thread_unblock (list_entry (list_pop_front (&sema->waiters), + struct thread_elem, elem)->thread); sema->value++; intr_set_level (old_level); } diff --git a/src/threads/thread.c b/src/threads/thread.c index 7b34722..2694a10 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -113,7 +113,7 @@ thread_create (const char *name, thread_func *function, void *aux) sf->eip = switch_entry; /* Add to run queue. */ - thread_wake (t); + thread_unblock (t); return t; } @@ -160,25 +160,29 @@ thread_execute (const char *filename) sf->eip = switch_entry; /* Add to run queue. */ - thread_wake (t); + thread_unblock (t); return true; } #endif -/* Transitions T from its current state to THREAD_READY, the - ready-to-run state. On entry, T must be ready or blocked. +/* Transitions a blocked thread T from its current state to the + ready-to-run state. If T is not blocked, there is no effect. (Use thread_yield() to make the running thread ready.) */ void -thread_wake (struct thread *t) +thread_unblock (struct thread *t) { + enum intr_level old_level; + ASSERT (is_thread (t)); - ASSERT (t->status == THREAD_READY || t->status == THREAD_BLOCKED); - if (t->status != THREAD_READY) + + old_level = intr_disable (); + if (t->status == THREAD_BLOCKED) { list_push_back (&run_queue, &t->rq_elem); t->status = THREAD_READY; } + intr_set_level (old_level); } /* Returns the name of thread T. */ @@ -238,9 +242,9 @@ thread_yield (void) } /* Puts the current thread to sleep. It will not be scheduled - again until awoken by thread_wake(). */ + again until awoken by thread_unblock(). */ void -thread_sleep (void) +thread_block (void) { ASSERT (!intr_context ()); ASSERT (intr_get_level () == INTR_OFF); @@ -261,7 +265,7 @@ idle (void *aux UNUSED) /* Let someone else run. */ intr_disable (); - thread_sleep (); + thread_block (); intr_enable (); } } @@ -388,12 +392,13 @@ schedule_tail (struct thread *prev) ASSERT (intr_get_level () == INTR_OFF); cur->status = THREAD_RUNNING; - if (prev != NULL && prev->status == THREAD_DYING) - destroy_thread (prev); #ifdef USERPROG addrspace_activate (cur); #endif + + if (prev != NULL && prev->status == THREAD_DYING) + destroy_thread (prev); } /* Schedules a new process. At entry, interrupts must be off and diff --git a/src/threads/thread.h b/src/threads/thread.h index aab1a73..e8927de 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -43,12 +43,12 @@ struct thread *thread_create (const char *name, thread_func *, void *); bool thread_execute (const char *filename); #endif -void thread_wake (struct thread *); +void thread_unblock (struct thread *); const char *thread_name (struct thread *); struct thread *thread_current (void); void thread_exit (void) NO_RETURN; void thread_yield (void); -void thread_sleep (void); +void thread_block (void); #endif /* thread.h */ diff --git a/src/userprog/addrspace.c b/src/userprog/addrspace.c index 1170f16..e8d8305 100644 --- a/src/userprog/addrspace.c +++ b/src/userprog/addrspace.c @@ -273,7 +273,6 @@ addrspace_activate (struct thread *t) { ASSERT (t != NULL); - if (t->pagedir != NULL) - pagedir_activate (t->pagedir); + pagedir_activate (t->pagedir); tss_set_esp0 ((uint8_t *) t + PGSIZE); } -- 2.30.2