wakeup(void *chan) 在 xv6 中如何工作?
How does wakeup(void *chan) works in xv6?
我正在学习 osdev 并查找 xv6 代码,目前 - 特别是控制台代码。基本上,我不明白控制台是如何启动一个进程的。
在console.c中有一个函数:
void consoleintr(int (*getc)(void)) {
....
while((c = getc()) >= 0) {
switch(c) {
....
default:
....
if(c == '\n' || c == C('D') || input.rightmost == input.r + INPUT_BUF) {
wakeup(&input.r);
}
}
}
所以我明白了,当行结束时(或缓冲区的长度超过最大值),它会启动 wakeup(&input.r)
然后proc.c中有这个:
// Wake up all processes sleeping on chan.
// The ptable lock must be held.
static void wakeup1(void *chan)
{
struct proc *p;
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
if(p->state == SLEEPING && p->chan == chan)
p->state = RUNNABLE;
}
// Wake up all processes sleeping on chan.
void wakeup(void *chan)
{
acquire(&ptable.lock);
wakeup1(chan);
release(&ptable.lock);
}
这里发生了什么?为什么要比较控制台缓冲区的地址和 proc 的 chan?这是什么chan?
它用于等待(休眠)控制台输入的进程。看这里:
235 int
236 consoleread(struct inode *ip, char *dst, int n)
...
251 sleep(&input.r, &cons.lock);
您提到的代码唤醒了这个休眠进程,因为数据来自控制台,现在可以进行处理。
chan
- 是一个频道。您可以等待(睡眠)不同的事情。此通道用于控制台输入数据。
我正在学习 osdev 并查找 xv6 代码,目前 - 特别是控制台代码。基本上,我不明白控制台是如何启动一个进程的。
在console.c中有一个函数:
void consoleintr(int (*getc)(void)) {
....
while((c = getc()) >= 0) {
switch(c) {
....
default:
....
if(c == '\n' || c == C('D') || input.rightmost == input.r + INPUT_BUF) {
wakeup(&input.r);
}
}
}
所以我明白了,当行结束时(或缓冲区的长度超过最大值),它会启动 wakeup(&input.r)
然后proc.c中有这个:
// Wake up all processes sleeping on chan.
// The ptable lock must be held.
static void wakeup1(void *chan)
{
struct proc *p;
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
if(p->state == SLEEPING && p->chan == chan)
p->state = RUNNABLE;
}
// Wake up all processes sleeping on chan.
void wakeup(void *chan)
{
acquire(&ptable.lock);
wakeup1(chan);
release(&ptable.lock);
}
这里发生了什么?为什么要比较控制台缓冲区的地址和 proc 的 chan?这是什么chan?
它用于等待(休眠)控制台输入的进程。看这里:
235 int
236 consoleread(struct inode *ip, char *dst, int n)
...
251 sleep(&input.r, &cons.lock);
您提到的代码唤醒了这个休眠进程,因为数据来自控制台,现在可以进行处理。
chan
- 是一个频道。您可以等待(睡眠)不同的事情。此通道用于控制台输入数据。