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