发布于 

MIT 6.828 HW7 xv6 locking

Notes of MIT 6.828 HW6

Don’t do this

If we execute the following code, we will meet dead lock because the lock is already held by the process and will never be released, and the second acquire(&lk) will never be satisfied.

1
2
3
4
struct spinlock lk;
initlock(&lk, "test lock");
acquire(&lk);
acquire(&lk);

Interrupts in ide.c

An acquire ensures that interrupts are off on the local processor using the cli instruction (via pushcli()), and that interrupts remain off until the release of the last lock held by that processor (at which point they are enabled using sti).

If we turn on interrupts while holding the ide lock in iderw in ide.c, kernel will run into dead lock. This is because it tries to handle the disk interrupt while holding the ide lock, but the handler ideintr() also acquires the lock.

1
2
3
4
5
6
7
8
9
10
// Interrupt handler.
void
ideintr(void)
{
struct buf *b;

// First queued buffer is the active request.
acquire(&idelock);
/* ... */
}

Interrupt in file.c

If we turn on interrupts while holding the file_table_lock, dead lock won’t happen. Because there isn’t a interrupt handler that acquires the file_table_lock.

xv6 lock implementation

release() must clear lk->pcs[0] and lk->cpu before clearing lk->locked, because otherwise the lock might be acquired by another thread before the clear is completed. If so, another acquire() would need to set these fields while release() tries to clear the same fields at the same time. This could lead to error.