static bool load (const char *cmdline, void (**eip) (void), void **esp);
/* Starts a new thread running a user program loaded from
- FILENAME. The new thread may be scheduled before
- process_execute() returns.*/
+ FILENAME. The new thread may be scheduled (and may even exit)
+ before process_execute() returns. Returns the new process's
+ thread id, or TID_ERROR if the thread cannot be created. */
tid_t
process_execute (const char *filename)
{
/* Initialize interrupt frame and load executable. */
memset (&if_, 0, sizeof if_);
- if_.es = SEL_UDSEG;
- if_.ds = SEL_UDSEG;
+ if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG;
if_.cs = SEL_UCSEG;
if_.eflags = FLAG_IF | FLAG_MBS;
- if_.ss = SEL_UDSEG;
success = load (filename, &if_.eip, &if_.esp);
/* If load failed, quit. */
if (!success)
thread_exit ();
- /* Switch page tables. */
- process_activate ();
-
/* Start the user process by simulating a return from an
interrupt, implemented by intr_exit (in
- threads/intr-stubs.pl). Because intr_exit takes all of its
+ threads/intr-stubs.S). Because intr_exit takes all of its
arguments on the stack in the form of a `struct intr_frame',
we just point the stack pointer (%esp) to our stack frame
and jump to it. */
NOT_REACHED ();
}
+/* Waits for thread TID to die and returns its exit status. If
+ it was terminated by the kernel (i.e. killed due to an
+ exception), returns -1. If TID is invalid or if it was not a
+ child of the calling process, or if process_wait() has already
+ been successfully called for the given TID, returns -1
+ immediately, without waiting.
+
+ This function will be implemented in problem 2-2. For now, it
+ does nothing. */
+int
+process_wait (tid_t child_tid UNUSED)
+{
+ return -1;
+}
+
/* Free the current process's resources. */
void
process_exit (void)
uint32_t *pd;
/* Destroy the current process's page directory and switch back
- to the kernel-only page directory. We have to set
- cur->pagedir to NULL before switching page directories, or a
- timer interrupt might switch back to the process page
- directory. */
+ to the kernel-only page directory. */
pd = cur->pagedir;
if (pd != NULL)
{
+ /* We must set cur->pagedir to NULL before switching page
+ directories, or a timer interrupt might switch back to
+ the process page directory. The asm statement prevents
+ GCC from reordering the assignment and the function
+ calls. */
cur->pagedir = NULL;
+ asm volatile ("");
+
pagedir_activate (NULL);
pagedir_destroy (pd);
}
static bool setup_stack (void **esp);
/* Aborts loading an executable, with an error message. */
-#define LOAD_ERROR(MSG) \
- do { \
- printf ("load: %s: ", filename); \
- printf MSG; \
- printf ("\n"); \
- goto done; \
+#define LOAD_ERROR(MSG) \
+ do { \
+ printf ("load: %s: ", filename); \
+ printf MSG; \
+ printf ("\n"); \
+ goto done; \
} while (0)
/* Loads an ELF executable from FILENAME into the current thread.
bool success = false;
int i;
- /* Allocate page directory. */
+ /* Allocate and activate page directory. */
t->pagedir = pagedir_create ();
if (t->pagedir == NULL)
LOAD_ERROR (("page directory allocation failed"));
+ process_activate ();
/* Open executable file. */
file = filesys_open (filename);