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