Add problem 1-1 solution.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 31 Dec 2004 07:16:11 +0000 (07:16 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 31 Dec 2004 07:16:11 +0000 (07:16 +0000)
solutions/README
solutions/p1-1.patch [new file with mode: 0644]

index f4d230910426889a52b80dcdaf5faf0809cfdd56..23bb6dd561167ebd68885a3a5c0bf59934a10d10 100644 (file)
@@ -1,6 +1,6 @@
 Sample solutions.
 
-* The solutions for p1-2 and p2 are okay.
+* The solutions for p1-1, p1-2, and p2 are okay.
 
 * The solution for p1-3 needs some work.
 
diff --git a/solutions/p1-1.patch b/solutions/p1-1.patch
new file mode 100644 (file)
index 0000000..b8090c8
--- /dev/null
@@ -0,0 +1,125 @@
+? solutions/p1-1.patch
+Index: src/devices/timer.c
+===================================================================
+RCS file: /afs/ir.stanford.edu/users/b/l/blp/private/cvs/pintos/src/devices/timer.c,v
+retrieving revision 1.16
+diff -u -p -u -r1.16 timer.c
+--- src/devices/timer.c        13 Dec 2004 22:42:01 -0000      1.16
++++ src/devices/timer.c        31 Dec 2004 07:12:25 -0000
+@@ -27,6 +27,9 @@ static volatile int64_t ticks;
+    Initialized by timer_calibrate(). */
+ static unsigned loops_per_tick;
++/* Threads waiting in timer_sleep(). */
++static struct list wait_list;
++
+ static intr_handler_func timer_interrupt;
+ static bool too_many_loops (unsigned loops);
+ static void busy_wait (int64_t loops);
+@@ -47,6 +50,8 @@ timer_init (void) 
+   outb (0x40, count >> 8);
+   intr_register (0x20, 0, INTR_OFF, timer_interrupt, "8254 Timer");
++
++  list_init (&wait_list);
+ }
+ /* Calibrates loops_per_tick, used to implement brief delays. */
+@@ -91,15 +96,35 @@ timer_elapsed (int64_t then) 
+   return timer_ticks () - then;
+ }
++/* Compares two threads based on their wake-up times. */
++static bool
++compare_threads_by_wakeup_time (const list_elem *a_, const list_elem *b_,
++                                void *aux UNUSED) 
++{
++  const struct thread *a = list_entry (a_, struct thread, timer_elem);
++  const struct thread *b = list_entry (b_, struct thread, timer_elem);
++
++  return a->wakeup_time < b->wakeup_time;
++}
++
+ /* Suspends execution for approximately TICKS timer ticks. */
+ void
+ timer_sleep (int64_t ticks) 
+ {
+-  int64_t start = timer_ticks ();
++  struct thread *t = thread_current ();
++
++  /* Schedule our wake-up time. */
++  t->wakeup_time = timer_ticks () + ticks;
++  /* Atomically insert the current thread into the wait list. */
+   ASSERT (intr_get_level () == INTR_ON);
+-  while (timer_elapsed (start) < ticks) 
+-    thread_yield ();
++  intr_disable ();
++  list_insert_ordered (&wait_list, &t->timer_elem,
++                       compare_threads_by_wakeup_time, NULL);
++  intr_enable ();
++
++  /* Wait. */
++  sema_down (&t->timer_sema);
+ }
+ /* Suspends execution for approximately MS milliseconds. */
+@@ -138,6 +163,16 @@ timer_interrupt (struct intr_frame *args
+   thread_tick ();
+   if (ticks % TIME_SLICE == 0)
+     intr_yield_on_return ();
++
++  while (!list_empty (&wait_list))
++    {
++      struct thread *t = list_entry (list_front (&wait_list),
++                                     struct thread, timer_elem);
++      if (ticks < t->wakeup_time) 
++        break;
++      sema_up (&t->timer_sema);
++      list_pop_front (&wait_list);
++    }
+ }
+ /* Returns true if LOOPS iterations waits for more than one timer
+Index: src/threads/thread.c
+===================================================================
+RCS file: /afs/ir.stanford.edu/users/b/l/blp/private/cvs/pintos/src/threads/thread.c,v
+retrieving revision 1.48
+diff -u -p -u -r1.48 thread.c
+--- src/threads/thread.c       9 Oct 2004 18:01:37 -0000       1.48
++++ src/threads/thread.c       31 Dec 2004 07:12:26 -0000
+@@ -337,6 +337,7 @@ init_thread (struct thread *t, const cha
+   t->stack = (uint8_t *) t + PGSIZE;
+   t->priority = priority;
+   t->magic = THREAD_MAGIC;
++  sema_init (&t->timer_sema, 0, "timer");
+ }
+ /* Allocates a SIZE-byte frame at the top of thread T's stack and
+Index: src/threads/thread.h
+===================================================================
+RCS file: /afs/ir.stanford.edu/users/b/l/blp/private/cvs/pintos/src/threads/thread.h,v
+retrieving revision 1.28
+diff -u -p -u -r1.28 thread.h
+--- src/threads/thread.h       29 Sep 2004 01:04:20 -0000      1.28
++++ src/threads/thread.h       31 Dec 2004 07:12:26 -0000
+@@ -4,6 +4,7 @@
+ #include <debug.h>
+ #include <list.h>
+ #include <stdint.h>
++#include "threads/synch.h"
+ /* States in a thread's life cycle. */
+ enum thread_status
+@@ -91,6 +92,11 @@ struct thread
+     /* Shared between thread.c and synch.c. */
+     list_elem elem;                     /* List element. */
++
++    /* Problem 1-1. */
++    int64_t wakeup_time;                /* Time to wake this thread up. */
++    list_elem timer_elem;               /* Element in timer_wait_list. */
++    struct semaphore timer_sema;        /* Semaphore. */
+ #ifdef USERPROG
+     /* Owned by userprog/process.c. */