Linux内核中的P,V操作之V

2008年11月29日 | 由 helight | 400字 | 阅读大约需要1分钟 | 归档于 programming | 标签 #linux #开源 #kernel

V操作:也在文件:kernel/semaphore.c中。

void up(struct semaphore *sem) { 
    unsigned long flags; 
    spin_lock_irqsave(&sem->lock, flags); 
    if (likely(list_empty(&sem->wait_list))) //在这里用list_empty判断sem的等待队列是否为空。 
        sem->count++; //如果为空则只是信号量的计数加1 
    else 
        __up(sem); //否则在这里去唤醒信号量的等待队列上的进程。 
    spin_unlock_irqrestore(&sem->lock, flags); 
} 

下面来看看__up(sem)这个函数:

static noinline void __sched __up(struct semaphore *sem) {
    //下面一句是在上面确定有等待进程了之后,来取第一个等待进程(当然这里取的一个信号量结构体)。应为第一个进程是等待最久的。 
    struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list, struct semaphore_waiter, list); 
    list_del(&waiter->list); //然后在这个等待队列上将其删除 
    waiter->up = 1; //标识允许唤醒 
    wake_up_process(waiter->task); //这里正真去唤醒进程。 
} 

wake_up_process(waiter->task);再调用函数try_to_wake_up(p, TASK_ALL, 0);进行了进程的唤醒。