X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fthreads%2Fthread.c;h=82858dfca059874717e0f01c77db979634f9000e;hb=b9d1a06a2bcc6de5251e12be91ad687d3b291244;hp=04b446f9f475d0225b45b4f6e6d797a12defbd87;hpb=1824e4d39b4f042474d29ac91ee59b326ab00da1;p=pintos-anon diff --git a/src/threads/thread.c b/src/threads/thread.c index 04b446f..82858df 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -2,6 +2,7 @@ #include #include "debug.h" #include "interrupt.h" +#include "intr-stubs.h" #include "lib.h" #include "mmu.h" #include "palloc.h" @@ -105,13 +106,42 @@ thread_current (void) bool thread_execute (const char *filename) { - struct thread *t = new_thread (filename); + struct thread *t; + struct intr_frame *if_; + struct switch_thunk_frame *tf; + struct switch_frame *sf; + void (*start) (void); + + ASSERT (filename != NULL); + + t = new_thread (filename); if (t == NULL) return false; - if (!addrspace_load (&t->addrspace, filename)) + if (!addrspace_load (&t->addrspace, filename, &start)) panic ("%s: program load failed", filename); - printk ("%s: loaded\n", filename); + + /* Interrupt frame. */ + if_ = alloc_frame (t, sizeof *if_); + if_->es = SEL_UDSEG; + if_->ds = SEL_UDSEG; + if_->eip = start; + if_->cs = SEL_UCSEG; + if_->eflags = FLAG_IF | 2; + if_->esp = PHYS_BASE; + if_->ss = SEL_UDSEG; + + /* Stack frame for switch_thunk(). */ + tf = alloc_frame (t, sizeof *tf); + tf->eip = (void (*) (void)) intr_exit; + + /* Stack frame for thread_switch(). */ + sf = alloc_frame (t, sizeof *sf); + sf->eip = (void (*) (void)) switch_thunk; + + /* Add to run queue. */ + thread_ready (t); + return true; } #endif