summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2012-03-26 20:18:23 +0200
committermanuel <manuel@mausz.at>2012-03-26 20:18:23 +0200
commit11c1519a12cdae1ce05d31a6e389a103259c6c93 (patch)
treede8b4a9c5ae617098c274733d1b3562f1a89d680
parentb5f0874cd96ee2a62aabc645b9626c2749cb6a01 (diff)
downloadprogos-11c1519a12cdae1ce05d31a6e389a103259c6c93.tar.gz
progos-11c1519a12cdae1ce05d31a6e389a103259c6c93.tar.bz2
progos-11c1519a12cdae1ce05d31a6e389a103259c6c93.zip
first timer alarm implementation
-rw-r--r--pintos-progos/.gitignore6
-rw-r--r--pintos-progos/devices/timer.c45
-rw-r--r--pintos-progos/threads/thread.h16
-rw-r--r--proj0.txt23
4 files changed, 76 insertions, 14 deletions
diff --git a/pintos-progos/.gitignore b/pintos-progos/.gitignore
new file mode 100644
index 0000000..e87c613
--- /dev/null
+++ b/pintos-progos/.gitignore
@@ -0,0 +1,6 @@
1intro/bochsout.txt
2intro/bochsrc.txt
3intro/build
4threads/bochsout.txt
5threads/bochsrc.txt
6threads/build
diff --git a/pintos-progos/devices/timer.c b/pintos-progos/devices/timer.c
index befaaae..bf78351 100644
--- a/pintos-progos/devices/timer.c
+++ b/pintos-progos/devices/timer.c
@@ -30,11 +30,16 @@ static void busy_wait (int64_t loops);
30static void real_time_sleep (int64_t num, int32_t denom); 30static void real_time_sleep (int64_t num, int32_t denom);
31static void real_time_delay (int64_t num, int32_t denom); 31static void real_time_delay (int64_t num, int32_t denom);
32 32
33/* list of processes waiting for an alarm event
34 * and currently put to sleep */
35static struct list alarm_list;
36
33/* Sets up the timer to interrupt TIMER_FREQ times per second, 37/* Sets up the timer to interrupt TIMER_FREQ times per second,
34 and registers the corresponding interrupt. */ 38 and registers the corresponding interrupt. */
35void 39void
36timer_init (void) 40timer_init (void)
37{ 41{
42 list_init (&alarm_list);
38 pit_configure_channel (0, 2, TIMER_FREQ); 43 pit_configure_channel (0, 2, TIMER_FREQ);
39 intr_register_ext (0x20, timer_interrupt, "8254 Timer"); 44 intr_register_ext (0x20, timer_interrupt, "8254 Timer");
40} 45}
@@ -89,11 +94,26 @@ timer_elapsed (int64_t then)
89void 94void
90timer_sleep (int64_t ticks) 95timer_sleep (int64_t ticks)
91{ 96{
92 int64_t start = timer_ticks (); 97 struct thread *t = thread_current ();
98 enum intr_level old_level;
93 99
94 ASSERT (intr_get_level () == INTR_ON); 100 /* nothing to sleep here */
95 while (timer_elapsed (start) < ticks) 101 if (ticks <= 0)
96 thread_yield (); 102 return;
103
104 t->alarm_tick = timer_ticks () + ticks;
105
106 /* add thread to alarm list
107 * disable interrupts as this is critical */
108 old_level = intr_disable ();
109 ASSERT (t->status == THREAD_RUNNING);
110 list_push_back (&alarm_list, &t->elem);
111
112 /* block the thread */
113 thread_block();
114
115 /* restore interrupt */
116 intr_set_level (old_level);
97} 117}
98 118
99/* Sleeps for approximately MS milliseconds. Interrupts must be 119/* Sleeps for approximately MS milliseconds. Interrupts must be
@@ -170,8 +190,25 @@ timer_print_stats (void)
170static void 190static void
171timer_interrupt (struct intr_frame *args UNUSED) 191timer_interrupt (struct intr_frame *args UNUSED)
172{ 192{
193 struct list_elem *el, *next;
194
173 ticks++; 195 ticks++;
174 thread_tick (); 196 thread_tick ();
197
198 /* check for threads waiting for an alarm event */
199 for (el = list_begin (&alarm_list); el != list_end (&alarm_list); el = next)
200 {
201 struct thread *t = list_entry (el, struct thread, elem);
202 if (t->alarm_tick == timer_ticks ())
203 {
204 next = list_remove (el);
205 /* unblock must be called AFTER removing,
206 * as thread_unblock() will reuse thread.elem */
207 thread_unblock (t);
208 }
209 else
210 next = list_next (el);
211 }
175} 212}
176 213
177/* Returns true if LOOPS iterations waits for more than one timer 214/* Returns true if LOOPS iterations waits for more than one timer
diff --git a/pintos-progos/threads/thread.h b/pintos-progos/threads/thread.h
index eebf42c..9cc5ef7 100644
--- a/pintos-progos/threads/thread.h
+++ b/pintos-progos/threads/thread.h
@@ -76,11 +76,13 @@ typedef int tid_t;
76 set to THREAD_MAGIC. Stack overflow will normally change this 76 set to THREAD_MAGIC. Stack overflow will normally change this
77 value, triggering the assertion. */ 77 value, triggering the assertion. */
78/* The `elem' member has a dual purpose. It can be an element in 78/* The `elem' member has a dual purpose. It can be an element in
79 the run queue (thread.c), or it can be an element in a 79 the run queue (thread.c), it can be an element in a semaphore
80 semaphore wait list (synch.c). It can be used these two ways 80 wait list (synch.c), or it can be an element in the alarm sleep
81 only because they are mutually exclusive: only a thread in the 81 list (timer.c). It can be used these two ways only because they
82 ready state is on the run queue, whereas only a thread in the 82 are mutually exclusive: only a thread in the ready state is on
83 blocked state is on a semaphore wait list. */ 83 the run queue, only a thread in the blocked state is on a semaphore
84 wait list, whereas only a thread waiting for an alarm event is on
85 the alarm sleep list. */
84struct thread 86struct thread
85 { 87 {
86 /* Owned by thread.c. */ 88 /* Owned by thread.c. */
@@ -91,7 +93,7 @@ struct thread
91 int priority; /* Priority. */ 93 int priority; /* Priority. */
92 struct list_elem allelem; /* List element for all threads list. */ 94 struct list_elem allelem; /* List element for all threads list. */
93 95
94 /* Shared between thread.c and synch.c. */ 96 /* Shared between thread.c, synch.c and timer.c. */
95 struct list_elem elem; /* List element. */ 97 struct list_elem elem; /* List element. */
96 98
97#ifdef USERPROG 99#ifdef USERPROG
@@ -103,6 +105,8 @@ struct thread
103 105
104 /* Owned by thread.c. */ 106 /* Owned by thread.c. */
105 unsigned magic; /* Detects stack overflow. */ 107 unsigned magic; /* Detects stack overflow. */
108
109 int64_t alarm_tick; /* absolute tick when to trigger an alarm event */
106 }; 110 };
107 111
108/* If false (default), use round-robin scheduler. 112/* If false (default), use round-robin scheduler.
diff --git a/proj0.txt b/proj0.txt
index d77cdb9..8cdfb49 100644
--- a/proj0.txt
+++ b/proj0.txt
@@ -3,14 +3,14 @@
3 | PROJECT 0: INTRO | 3 | PROJECT 0: INTRO |
4 | DESIGN DOCUMENT | 4 | DESIGN DOCUMENT |
5 +--------------------+ 5 +--------------------+
6 6
7---- GROUP ---- 7---- GROUP ----
8 8
9>> Fill in the names and email addresses of your group members. 9>> Fill in the names and email addresses of your group members.
10 10
11FirstName LastName <email@domain.example> 11Peter Ketscher <e9651415@mail.student.tuwien.ac.at>
12FirstName LastName <email@domain.example> 12Karoline Koth <e0326266@student.tuwien.ac.at>
13FirstName LastName <email@domain.example> 13Manuel Mausz <manuel-uni@mausz.at>
14 14
15---- PRELIMINARIES ---- 15---- PRELIMINARIES ----
16 16
@@ -21,6 +21,7 @@ FirstName LastName <email@domain.example>
21>> preparing your submission, other than the Pintos documentation, course 21>> preparing your submission, other than the Pintos documentation, course
22>> text, lecture notes, and course staff. 22>> text, lecture notes, and course staff.
23 23
24TODO
24 ALARM CLOCK 25 ALARM CLOCK
25 =========== 26 ===========
26 27
@@ -30,27 +31,41 @@ FirstName LastName <email@domain.example>
30>> `struct' member, global or static variable, `typedef', or 31>> `struct' member, global or static variable, `typedef', or
31>> enumeration. Identify the purpose of each in 25 words or less. 32>> enumeration. Identify the purpose of each in 25 words or less.
32 33
34struct thread:
35int64_t alarm_tick ...absolute tick when to trigger an alarm event
36
33---- ALGORITHMS ---- 37---- ALGORITHMS ----
34 38
35>> A2: Briefly describe what happens in a call to timer_sleep(), 39>> A2: Briefly describe what happens in a call to timer_sleep(),
36>> including the effects of the timer interrupt handler. 40>> including the effects of the timer interrupt handler.
37 41
42TODO
43
38>> A3: What steps are taken to minimize the amount of time spent in 44>> A3: What steps are taken to minimize the amount of time spent in
39>> the timer interrupt handler? 45>> the timer interrupt handler?
40 46
47TODO
48
41---- SYNCHRONIZATION ---- 49---- SYNCHRONIZATION ----
42 50
43>> A4: How are race conditions avoided when multiple threads call 51>> A4: How are race conditions avoided when multiple threads call
44>> timer_sleep() simultaneously? 52>> timer_sleep() simultaneously?
45 53
54TODO
55
46>> A5: How are race conditions avoided when a timer interrupt occurs 56>> A5: How are race conditions avoided when a timer interrupt occurs
47>> during a call to timer_sleep()? 57>> during a call to timer_sleep()?
48 58
59We've disabled the interrupts during list operations.
60
49---- RATIONALE ---- 61---- RATIONALE ----
50 62
51>> A6: Why did you choose this design? In what ways is it superior to 63>> A6: Why did you choose this design? In what ways is it superior to
52>> another design you considered? 64>> another design you considered?
53 65
66It's very simple, doesn't require any complex structures and memory allocations
67and fulfills the needs of project0.
68
54 ARGUMENT PASSING 69 ARGUMENT PASSING
55 ================ 70 ================
56 71