More from Godmar.
[pintos-anon] / TODO
1 -*- text -*-
2
3 From: "Godmar Back" <godmar@gmail.com>
4 Subject: priority donation tests
5 To: "Ben Pfaff" <blp@cs.stanford.edu>
6 Date: Fri, 3 Mar 2006 11:02:08 -0500
7
8 Ben,
9
10 it seems the priority donation tests are somewhat incomplete and allow
11 incorrect implementations to pass with a perfect score.
12
13 We are seeing the following wrong implementations pass all tests:
14
15 - Implementations that assume locks are released in the opposite order
16 in which they're acquired. The students implement this by
17 popping/pushing on the donation list.
18
19 - Implementations that assume that the priority of a thread waiting on
20 a semaphore or condition variable cannot change between when the
21 thread was blocked and when it is unblocked. The students implement
22 this by doing an insert into an ordered list on block, rather than
23 picking the maximum thread on unblock.
24
25 Neither of these two cases is detected; do you currently check for
26 these mistakes manually?
27
28 I wrote a test that checks for the first case; it is here:
29 http://people.cs.vt.edu/~gback/pintos/priority-donate-multiple-2.patch
30
31 [...]
32
33 I also wrote a test case for the second scenario:
34 http://people.cs.vt.edu/~gback/pintos/priority-donate-sema.c
35 http://people.cs.vt.edu/~gback/pintos/priority-donate-sema.ck
36
37 I put the other tests up here:
38 http://people.cs.vt.edu/~gback/pintos/priority-donate-multiple2.c
39 http://people.cs.vt.edu/~gback/pintos/priority-donate-multiple2.ck
40
41 From: "Godmar Back" <godmar@gmail.com>
42 Subject: multiple threads waking up at same clock tick
43 To: "Ben Pfaff" <blp@cs.stanford.edu>
44 Date: Wed, 1 Mar 2006 08:14:47 -0500
45
46 Greg Benson points out another potential TODO item for P1.
47
48 ----
49 One thing I recall:
50
51 The alarm tests do not test to see if multiple threads are woken up if
52 their timers have expired.  That is, students can write a solution
53 that just wakes up the first thread on the sleep queue rather than
54 check for additional threads.  Of course, the next thread will be
55 woken up on the next tick.  Also, this might be hard to test.
56
57 ---
58 Way to test this: (from Godmar Back)
59
60 Thread A with high priority spins until 'ticks' changes, then calls to
61 timer_sleep(X), Thread B with lower priority is then resumed, calls
62 set_priority to make its priority equal to that of thread A, then
63 calls timer_sleep(X), all of that before the next clock interrupt
64 arrives.
65
66 On wakeup, each thread records wake-up time and calls yield
67 immediately, forcing the scheduler to switch to the other
68 equal-priority thread. Both wake-up times must be the same (and match
69 the planned wake-up time.)
70
71 From: "Waqar Mohsin" <wmohsin@gmail.com>
72 Subject: 3 questions about switch_threads() in switch.S
73 To: blp@cs.stanford.edu, joshwise@stanford.edu
74 Date: Fri, 3 Mar 2006 17:09:21 -0800
75
76 QUESTION 1
77  
78 In the section
79  
80   # Save current stack pointer to old thread's stack, if any.
81   movl SWITCH_CUR(%esp), %eax
82   test %eax, %eax
83   jz 1f
84   movl %esp, (%eax,%edx,1)
85 1:
86
87   # Restore stack pointer from new thread's stack.
88   movl SWITCH_NEXT(%esp), %ecx
89   movl (%ecx,%edx,1), %esp
90
91 why are we saving the current stack pointer only if the "cur" thread pointer
92 is non-NULL ? Isn't it gauranteed to be non-NULL because switch_threads() is
93 only called form schedule(), where we have
94
95   struct thread *cur = running_thread ();
96
97 which should always be non-NULL (given the way kernel pool is laid out).
98
99 QUESTION 2
100
101   # This stack frame must match the one set up by thread_create().
102   pushl %ebx
103   pushl %ebp
104   pushl %esi
105   pushl %edi
106
107 I find the comment confusing. thread_create() is a special case: the set of
108 registers popped from switch_threads stack frame for a newly created thread
109 are all zero, so their order shouldn't dictate the order above.
110
111 I think all that matters is that the order of pops at the end of
112 switch_threads() is the opposite of the pushes at the beginning (as shown
113 above).
114
115 QUESTION 3
116
117 Is it true that struct switch_threads_frame does NOT strictly require
118
119     struct thread *cur;         /* 20: switch_threads()'s CUR argument. */
120     struct thread *next;        /* 24: switch_threads()'s NEXT argument. */
121 at the end ?
122
123 When a newly created thread's stack pointer is installed in switch_threads(),
124 all we do is pop the saved registers and return to switch_entry() which pops
125 off and discards the above two simulated (and not used) arguments to
126 switch_threads().
127
128 If we remove these two from struct switch_threads_frame and don't do a
129
130   # Discard switch_threads() arguments.
131   addl $8, %esp
132 in switch_entry(), things should still work. Am I right ?
133
134 Thanks
135 Waqar
136
137 From: "Godmar Back" <godmar@gmail.com>
138 Subject: thread_yield in irq handler
139 To: "Ben Pfaff" <blp@cs.stanford.edu>
140 Date: Wed, 22 Feb 2006 22:18:50 -0500
141
142 Ben,
143
144 you write in your Tour of Pintos:
145
146 "Second, an interrupt handler must not call any function that can
147 sleep, which rules out thread_yield(), lock_acquire(), and many
148 others. This is because external interrupts use space on the stack of
149 the kernel thread that was running at the time the interrupt occurred.
150 If the interrupt handler tried to sleep and that thread resumed, then
151 the two uses of the single stack would interfere, which cannot be
152 allowed."
153
154 Is the last sentence really true?
155
156 I thought the reason that you couldn't sleep is that you would put
157 effectively a random thread/process to sleep, but I don't think it
158 would cause problems with the kernel stack.  After all, it doesn't
159 cause this problem if you call thread_yield at the end of
160 intr_handler(), so why would it cause this problem earlier.
161
162 As for thread_yield(), my understanding is that the reason it's called
163 at the end is to ensure it's done after the interrupt is acknowledged,
164 which you can't do until the end because Pintos doesn't handle nested
165 interrupts.
166
167  - Godmar
168
169 From: "Godmar Back" <godmar@gmail.com>
170
171 For reasons I don't currently understand, some of our students seem
172 hesitant to include each thread in a second "all-threads" list and are
173 looking for ways to implement the advanced scheduler without one.
174
175 Currently, I believe, all tests for the mlfqs are such that all
176 threads are either ready or sleeping in timer_sleep(). This allows for
177 an incorrect implementation in which recent-cpu and priorities are
178 updated only for those threads that are on the alarm list or the ready
179 list.
180
181 The todo item would be a test where a thread is blocked on a
182 semaphore, lock or condition variable and have its recent_cpu decay to
183 zero, and check that it's scheduled right after the unlock/up/signal.
184
185 From: "Godmar Back" <godmar@gmail.com>
186 Subject: set_priority & donation - a TODO item
187 To: "Ben Pfaff" <blp@cs.stanford.edu>
188 Date: Mon, 20 Feb 2006 22:20:26 -0500
189
190 Ben,
191
192 it seems that there are currently no tests that check the proper
193 behavior of thread_set_priority() when called by a thread that is
194 running under priority donation.  The proper behavior, I assume, is to
195 temporarily drop the donation if the set priority is higher, and to
196 reassume the donation should the thread subsequently set its own
197 priority again to a level that's lower than a still active donation.
198
199  - Godmar
200
201 From: Godmar Back <godmar@gmail.com>
202 Subject: project 4 question/comment regarding caching inode data
203 To: Ben Pfaff <blp@cs.stanford.edu>
204 Date: Sat, 14 Jan 2006 15:59:33 -0500
205
206 Ben,
207
208 in section 6.3.3 in the P4 FAQ, you write:
209
210 "You can store a pointer to inode data in struct inode, if you want,"
211
212 Should you point out that if they indeed do that, they likely wouldn't
213 be able to support more than 64 open inodes systemwide at any given
214 point in time.
215
216 (This seems like a rather strong limitation; do your current tests
217 open more than 64 files?
218 It would also point to an obvious way to make the projects harder by
219 specifically disallowing that inode data be locked in memory during
220 the entire time an inode is kept open.)
221
222  - Godmar
223
224 From: Godmar Back <godmar@gmail.com>
225 Subject: on caching in project 4
226 To: Ben Pfaff <blp@cs.stanford.edu>
227 Date: Mon, 9 Jan 2006 20:58:01 -0500
228
229 here's an idea for future semesters.
230
231 I'm in the middle of project 4, I've started by implementing a buffer
232 cache and plugging it into the existing filesystem.  Along the way I
233 was wondering how we could test the cache.
234
235 Maybe one could adopt a similar testing strategy as in project 1 for
236 the MLQFS scheduler: add a function that reads "get_cache_accesses()"
237 and a function "get_cache_hits()".  Then create a version of pintos
238 that creates access traces for a to-be-determined workload.  Run an
239 off-line analysis that would determine how many hits a perfect cache
240 would have (MAX), and how much say an LRU strategy would give (MIN).
241 Then add a fudge factor to account for different index strategies and
242 test that the reported number of cache hits/accesses is within (MIN,
243 MAX) +/- fudge factor.
244
245 (As an aside - I am curious why you chose to use a clock-style
246 algorithm rather than the more straightforward LRU for your buffer
247 cache implementation in your sample solution. Is there a reason for
248 that?  I was curious to see if it made a difference, so I implemented
249 LRU for your cache implementation and ran the test workload of project
250 4 and printed cache hits/accesses.
251 I found that for that workload, the clock-based algorithm performs
252 almost identical to LRU (within about 1%, but I ran nondeterministally
253 with QEMU). I then reduced the cache size to 32 blocks and found again
254 the same performance, which raises the suspicion that the test
255 workload might not force any cache replacement, so the eviction
256 strategy doesn't matter.)
257
258 Godmar Back <godmar@gmail.com> writes:
259
260 > in your sample solution to P4, dir_reopen does not take any locks when
261 > changing a directory's open_cnt. This looks like a race condition to
262 > me, considering that dir_reopen is called from execute_process without
263 > any filesystem locks held.
264
265 * Get rid of rox--causes more trouble than it's worth
266
267 * Reconsider command line arg style--confuses everyone.
268
269 * Finish writing tour.
270
271 * Introduce a "yield" system call to speed up the syn-* tests.
272
273 via Godmar Back:
274
275 * Project 3 solution needs FS lock.
276
277 * Get rid of mmap syscall, add sbrk.
278
279 * Make backtrace program accept multiple object file arguments,
280   e.g. add -u option to allow backtracing user program also.
281
282 * page-linear, page-shuffle VM tests do not use enough memory to force
283   eviction.  Should increase memory consumption.
284
285 * Add FS persistence test(s).
286
287 * lock_acquire(), lock_release() don't need additional intr_dis/enable
288   calls, because the semaphore protects lock->holder.
289
290
291
292 * process_death test needs improvement
293
294 * Internal tests.
295
296 * Improve automatic interpretation of exception messages.
297
298 * Userprog project:
299
300   - Mark read-only pages as actually read-only in the page table.  Or,
301     since this was consistently rated as the easiest project by the
302     students, require them to do it.
303
304   - Don't provide per-process pagedir implementation but only
305     single-process implementation and require students to implement
306     the separation?  This project was rated as the easiest after all.
307     Alternately we could just remove the synchronization on pid
308     selection and check that students fix it.
309
310 * Filesys project:
311
312   - Need a better way to measure performance improvement of buffer
313     cache.  Some students reported that their system was slower with
314     cache--likely, Bochs doesn't simulate a disk with a realistic
315     speed.
316
317 * Documentation:
318
319   - Add "Digging Deeper" sections that describe the nitty-gritty x86
320     details for the benefit of those interested.
321
322   - Add explanations of what "real" OSes do to give students some
323     perspective.
324
325 * Assignments:
326
327   - Add extra credit:
328
329     . Low-level x86 stuff, like paged page tables.
330
331     . Specifics on how to implement sbrk, malloc.
332
333     . Other good ideas.
334
335     . opendir/readdir/closedir
336
337     . everything needed for getcwd()