Change assembly from AT&T to Intel syntax.
[pintos-anon] / src / threads / thread.c
index afb2006bc1aa8a51ebffc002f80d29e766470e96..01ce7d33227a19196762199f3c349bab4890b688 100644 (file)
@@ -59,10 +59,11 @@ void schedule_tail (struct thread *prev);
 static tid_t allocate_tid (void);
 
 /* Initializes the threading system by transforming the code
 static tid_t allocate_tid (void);
 
 /* Initializes the threading system by transforming the code
-   that's currently running into a thread.  Note that this is
-   possible only because the loader was careful to put the bottom
-   of the stack at a page boundary; it won't work in general.
-   Also initializes the run queue.
+   that's currently running into a thread.  This can't work in
+   general and it is possible in this case only because loader.S
+   was careful to put the bottom of the stack at a page boundary.
+
+   Also initializes the run queue and the tid lock.
 
    After calling this function, be sure to initialize the page
    allocator before trying to create any threads with
 
    After calling this function, be sure to initialize the page
    allocator before trying to create any threads with
@@ -169,9 +170,25 @@ thread_create (const char *name, int priority,
   return tid;
 }
 
   return tid;
 }
 
-/* Transitions a blocked thread T from its current state to the
-   ready-to-run state.  This is an error if T is not blocked.
-   (Use thread_yield() to make the running thread ready.) */
+/* Puts the current thread to sleep.  It will not be scheduled
+   again until awoken by thread_unblock().
+
+   This function must be called with interrupts turned off.  It
+   is usually a better idea to use one of the synchronization
+   primitives in synch.h. */
+void
+thread_block (void) 
+{
+  ASSERT (!intr_context ());
+  ASSERT (intr_get_level () == INTR_OFF);
+
+  thread_current ()->status = THREAD_BLOCKED;
+  schedule ();
+}
+
+/* Transitions a blocked thread T to the ready-to-run state.
+   This is an error if T is not blocked.  (Use thread_yield() to
+   make the running thread ready.) */
 void
 thread_unblock (struct thread *t) 
 {
 void
 thread_unblock (struct thread *t) 
 {
@@ -254,22 +271,6 @@ thread_yield (void)
   schedule ();
   intr_set_level (old_level);
 }
   schedule ();
   intr_set_level (old_level);
 }
-
-/* Puts the current thread to sleep.  It will not be scheduled
-   again until awoken by thread_unblock().
-
-   This function must be called with interrupts turned off.  It
-   is usually a better idea to use one of the synchronization
-   primitives in synch.h. */
-void
-thread_block (void) 
-{
-  ASSERT (!intr_context ());
-  ASSERT (intr_get_level () == INTR_OFF);
-
-  thread_current ()->status = THREAD_BLOCKED;
-  schedule ();
-}
 \f
 /* Idle thread.  Executes when no other thread is ready to run. */
 static void
 \f
 /* Idle thread.  Executes when no other thread is ready to run. */
 static void
@@ -284,7 +285,8 @@ idle (void *aux UNUSED)
       thread_block ();
       intr_enable ();
 
       thread_block ();
       intr_enable ();
 
-      /* Use CPU `hlt' instruction to wait for interrupt. */
+      /* Use CPU `hlt' instruction to wait for interrupt.
+         See [IA32-v2a] "HLT" and [IA32-v3] 7.7. */
       asm ("hlt");
     }
 }
       asm ("hlt");
     }
 }
@@ -310,7 +312,7 @@ running_thread (void)
      down to the start of a page.  Because `struct thread' is
      always at the beginning of a page and the stack pointer is
      somewhere in the middle, this locates the curent thread. */
      down to the start of a page.  Because `struct thread' is
      always at the beginning of a page and the stack pointer is
      somewhere in the middle, this locates the curent thread. */
-  asm ("movl %%esp, %0\n" : "=g" (esp));
+  asm ("mov %0, %%esp" : "=g" (esp));
   return pg_round_down (esp);
 }
 
   return pg_round_down (esp);
 }
 
@@ -375,6 +377,10 @@ next_thread_to_run (void)
    the first time a thread is scheduled it is called by
    switch_entry() (see switch.S).
 
    the first time a thread is scheduled it is called by
    switch_entry() (see switch.S).
 
+   It's not safe to call printf() until the thread switch is
+   complete.  In practice that means that printf()s should be
+   added at the end of the function.
+
    After this function and its caller returns, the thread switch
    is complete. */
 void
    After this function and its caller returns, the thread switch
    is complete. */
 void
@@ -406,7 +412,10 @@ schedule_tail (struct thread *prev)
 /* Schedules a new process.  At entry, interrupts must be off and
    the running process's state must have been changed from
    running to some other state.  This function finds another
 /* Schedules a new process.  At entry, interrupts must be off and
    the running process's state must have been changed from
    running to some other state.  This function finds another
-   thread to run and switches to it. */
+   thread to run and switches to it.
+
+   It's not safe to call printf() until schedule_tail() has
+   completed. */
 static void
 schedule (void) 
 {
 static void
 schedule (void) 
 {