X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=blobdiff_plain;f=src%2Fthreads%2Fthread.c;h=87f22b80607b4faba8ae2b1e9f93dc5d6659d8cc;hp=92d1aa899efe1d8bf84c6c7056ae7d45215c687b;hb=8b801a69f8e0c2c4ef7e32a2476786f80f433b8e;hpb=b0c619871eee10551a0d510b67ee3a2493088341 diff --git a/src/threads/thread.c b/src/threads/thread.c index 92d1aa8..87f22b8 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -24,6 +24,10 @@ that are ready to run but not actually running. */ static struct list ready_list; +/* List of all processes. Processes are added to this list + when they are first scheduled and removed when they exit. */ +static struct list all_list; + /* Idle thread. */ static struct thread *idle_thread; @@ -64,7 +68,7 @@ static void init_thread (struct thread *, const char *name, int priority); static bool is_thread (struct thread *) UNUSED; static void *alloc_frame (struct thread *, size_t size); static void schedule (void); -void schedule_tail (struct thread *prev); +void thread_schedule_tail (struct thread *prev); static tid_t allocate_tid (void); /* Initializes the threading system by transforming the code @@ -87,6 +91,7 @@ thread_init (void) lock_init (&tid_lock); list_init (&ready_list); + list_init (&all_list); /* Set up a thread structure for the running thread. */ initial_thread = running_thread (); @@ -191,6 +196,7 @@ thread_create (const char *name, int priority, /* Stack frame for switch_threads(). */ sf = alloc_frame (t, sizeof *sf); sf->eip = switch_entry; + sf->ebp = 0; /* Add to run queue. */ thread_unblock (t); @@ -280,9 +286,11 @@ thread_exit (void) process_exit (); #endif - /* Just set our status to dying and schedule another process. - We will be destroyed during the call to schedule_tail(). */ + /* Remove thread from all threads list, set our status to dying, + and schedule another process. That process will destroy us + when it calls thread_schedule_tail(). */ intr_disable (); + list_remove (&thread_current()->allelem); thread_current ()->status = THREAD_DYING; schedule (); NOT_REACHED (); @@ -306,6 +314,23 @@ thread_yield (void) intr_set_level (old_level); } +/* Invoke function 'func' on all threads, passing along 'aux'. + This function must be called with interrupts off. */ +void +thread_foreach (thread_action_func *func, void *aux) +{ + struct list_elem *e; + + ASSERT (intr_get_level () == INTR_OFF); + + for (e = list_begin (&all_list); e != list_end (&all_list); + e = list_next (e)) + { + struct thread *t = list_entry (e, struct thread, allelem); + func (t, aux); + } +} + /* Sets the current thread's priority to NEW_PRIORITY. */ void thread_set_priority (int new_priority) @@ -426,6 +451,8 @@ is_thread (struct thread *t) static void init_thread (struct thread *t, const char *name, int priority) { + enum intr_level old_level; + ASSERT (t != NULL); ASSERT (PRI_MIN <= priority && priority <= PRI_MAX); ASSERT (name != NULL); @@ -436,6 +463,10 @@ init_thread (struct thread *t, const char *name, int priority) t->stack = (uint8_t *) t + PGSIZE; t->priority = priority; t->magic = THREAD_MAGIC; + + old_level = intr_disable (); + list_push_back (&all_list, &t->allelem); + intr_set_level (old_level); } /* Allocates a SIZE-byte frame at the top of thread T's stack and @@ -482,7 +513,7 @@ next_thread_to_run (void) After this function and its caller returns, the thread switch is complete. */ void -schedule_tail (struct thread *prev) +thread_schedule_tail (struct thread *prev) { struct thread *cur = running_thread (); @@ -516,8 +547,8 @@ schedule_tail (struct thread *prev) running to some other state. This function finds another thread to run and switches to it. - It's not safe to call printf() until schedule_tail() has - completed. */ + It's not safe to call printf() until thread_schedule_tail() + has completed. */ static void schedule (void) { @@ -531,7 +562,7 @@ schedule (void) if (cur != next) prev = switch_threads (cur, next); - schedule_tail (prev); + thread_schedule_tail (prev); } /* Returns a tid to use for a new thread. */