Three Kinds of Errors Solution:
There are issues when you write worker threads:
cond_wait() might not return to the same threadmutex_lock(&m);
if (out_of_work) {
w = (item_t*) NULL;
} else {
if (!(w = (item_t*) dequeue(q))) {
cond_wait(cvar, &lock);
w = (item_t*) dequeue(q);
}
}
mutex_unlock(&m);
return w;
Above code is wrong. The following code is more correct, but still wrong:
mutex_lock(&m);
if (out_of_work) {
w = (item_t*) NULL;
} else {
// change 'if' to 'while'
while (!(w = (item_t*) dequeue(q))) {
cond_wait(cvar, &lock);
}
}
mutex_unlock(&m);
return w;
This is not a standard "time of check to time of use" (TOCTTOU) bug.
The below content assumes "user thread" (single process, no parallism)
To implement yield():
save general purpose registers, save %ebp, %esp, (we don't need to save %eip since it will be correct once we jump back)
restore to "switch to" thread's registers
Yield between process: INT 50 syscall
since they don't share memory, we need to make sure they don't see each other's secret
so kernel (instead of user code) is in charge of saving and restoring registers
%esp0%cs & %eip, %eflags, %ss & %esp, etc.)Process switch is more than conditional variable: it execute when
yield()
message passing from P1 to P2
P1 blocked by disk I/O
CPU preemption by clock interrupt
I/O Example:
P1: read() -> cond_wait() -> process_switch(P2)
P2: ... -> interrupt into kernel -> cond_signal()
(at least two things can be designed here)
cond_signal() mark P1 runnable, interrupt handler launched by P2 returns to P2 programcond_signal() calls process_switch(P1)... although this is morally correct, P2 interrupt handler WILL EXECUTE FOR A LONG TIME, WHICH IS BADTable of Content