2 Index: src/devices/timer.c
3 ===================================================================
4 RCS file: /afs/ir.stanford.edu/users/b/l/blp/private/cvs/pintos/src/devices/timer.c,v
5 retrieving revision 1.16
6 diff -u -p -u -r1.16 timer.c
7 --- src/devices/timer.c 13 Dec 2004 22:42:01 -0000 1.16
8 +++ src/devices/timer.c 31 Dec 2004 07:12:25 -0000
9 @@ -27,6 +27,9 @@ static volatile int64_t ticks;
10 Initialized by timer_calibrate(). */
11 static unsigned loops_per_tick;
13 +/* Threads waiting in timer_sleep(). */
14 +static struct list wait_list;
16 static intr_handler_func timer_interrupt;
17 static bool too_many_loops (unsigned loops);
18 static void busy_wait (int64_t loops);
19 @@ -47,6 +50,8 @@ timer_init (void)
20 outb (0x40, count >> 8);
22 intr_register (0x20, 0, INTR_OFF, timer_interrupt, "8254 Timer");
24 + list_init (&wait_list);
27 /* Calibrates loops_per_tick, used to implement brief delays. */
28 @@ -91,15 +96,35 @@ timer_elapsed (int64_t then)
29 return timer_ticks () - then;
32 +/* Compares two threads based on their wake-up times. */
34 +compare_threads_by_wakeup_time (const list_elem *a_, const list_elem *b_,
37 + const struct thread *a = list_entry (a_, struct thread, timer_elem);
38 + const struct thread *b = list_entry (b_, struct thread, timer_elem);
40 + return a->wakeup_time < b->wakeup_time;
43 /* Suspends execution for approximately TICKS timer ticks. */
45 timer_sleep (int64_t ticks)
47 - int64_t start = timer_ticks ();
48 + struct thread *t = thread_current ();
50 + /* Schedule our wake-up time. */
51 + t->wakeup_time = timer_ticks () + ticks;
53 + /* Atomically insert the current thread into the wait list. */
54 ASSERT (intr_get_level () == INTR_ON);
55 - while (timer_elapsed (start) < ticks)
58 + list_insert_ordered (&wait_list, &t->timer_elem,
59 + compare_threads_by_wakeup_time, NULL);
63 + sema_down (&t->timer_sema);
66 /* Suspends execution for approximately MS milliseconds. */
67 @@ -138,6 +163,16 @@ timer_interrupt (struct intr_frame *args
69 if (ticks % TIME_SLICE == 0)
70 intr_yield_on_return ();
72 + while (!list_empty (&wait_list))
74 + struct thread *t = list_entry (list_front (&wait_list),
75 + struct thread, timer_elem);
76 + if (ticks < t->wakeup_time)
78 + sema_up (&t->timer_sema);
79 + list_pop_front (&wait_list);
83 /* Returns true if LOOPS iterations waits for more than one timer
84 Index: src/threads/thread.c
85 ===================================================================
86 RCS file: /afs/ir.stanford.edu/users/b/l/blp/private/cvs/pintos/src/threads/thread.c,v
87 retrieving revision 1.48
88 diff -u -p -u -r1.48 thread.c
89 --- src/threads/thread.c 9 Oct 2004 18:01:37 -0000 1.48
90 +++ src/threads/thread.c 31 Dec 2004 07:12:26 -0000
91 @@ -337,6 +337,7 @@ init_thread (struct thread *t, const cha
92 t->stack = (uint8_t *) t + PGSIZE;
93 t->priority = priority;
94 t->magic = THREAD_MAGIC;
95 + sema_init (&t->timer_sema, 0, "timer");
98 /* Allocates a SIZE-byte frame at the top of thread T's stack and
99 Index: src/threads/thread.h
100 ===================================================================
101 RCS file: /afs/ir.stanford.edu/users/b/l/blp/private/cvs/pintos/src/threads/thread.h,v
102 retrieving revision 1.28
103 diff -u -p -u -r1.28 thread.h
104 --- src/threads/thread.h 29 Sep 2004 01:04:20 -0000 1.28
105 +++ src/threads/thread.h 31 Dec 2004 07:12:26 -0000
110 +#include "threads/synch.h"
112 /* States in a thread's life cycle. */
114 @@ -91,6 +92,11 @@ struct thread
116 /* Shared between thread.c and synch.c. */
117 list_elem elem; /* List element. */
120 + int64_t wakeup_time; /* Time to wake this thread up. */
121 + list_elem timer_elem; /* Element in timer_wait_list. */
122 + struct semaphore timer_sema; /* Semaphore. */
125 /* Owned by userprog/process.c. */