Search code examples
operating-systemosdevxv6

How does wakeup(void *chan) works in xv6?


I'm learning about osdev and looking up xv6 code, currently - the console code in particular. Basically, I don't get how the console launches a process.

in console.c there is a function:

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);
       }
    }
}

So I get it, when the line ends (or the length of the buffer exceeds maximum), it launches wakeup(&input.r)

Then there is this in 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);
}

What is happening here? Why is it comparing address of a console buffer and proc's chan? What is this chan?


Solution

  • It is for processes who waiting (sleeps) for console input. See here:

    235 int                                                                             
    236 consoleread(struct inode *ip, char *dst, int n)                                 
    ...                                                        
    251     sleep(&input.r, &cons.lock);
    

    The code you have mentioned wakeups this sleeping processes, because data have came from console and is available now for processing. chan - is a channel. You can wait (sleep) for different things. This channel is for console input data.