void down(struct semaphore *sem)函数的功能是获取信号量,获取成功后会将信号量减一,获取不到时会一直等待.
其源码分析如下:
void down(struct semaphore *sem)
{
unsigned long flags;
#可以看到在对信号量count减一操作时用spin lock 锁保护起来。
#这里用likely修饰说明sem->count 大部分情况下都大于零,因此down 就在spinlock的保护下对sem->count减一。
raw_spin_lock_irqsave(&sem->lock, flags);
if (likely(sem->count > 0))
sem->count--;
else
__down(sem);
raw_spin_unlock_irqrestore(&sem->lock, flags);
}
与之相类似的还有
int down_interruptible(struct semaphore *sem)
{
unsigned long flags;
int result = 0;
raw_spin_lock_irqsave(&sem->lock, flags);
if (likely(sem->count > 0))
sem->count--;
else
result = __down_interruptible(sem);
raw_spin_unlock_irqrestore(&sem->lock, flags);
return result;
}
可以看到down_interruptible 和down 函数在sem->count 大于零的情况下处理的过程一直,都是在spinlock 的保护下
对sem->count减一
与之相类似的还有
int down_killable(struct semaphore *sem)
{
unsigned long flags;
int result = 0;
raw_spin_lock_irqsave(&sem->lock, flags);
if (likely(sem->count > 0))
sem->count--;
else
result = __down_killable(sem);
raw_spin_unlock_irqrestore(&sem->lock, flags);
return result;
}
可以看到down_killable和down_interruptible 以及down 函数在sem->count 大于零的情况下处理的过程一直,都是在spinlock 的保护下
对sem->count减一,不同点在于对sem->count小于零的处理情况有所不同.
与之相同的还有
int down_timeout(struct semaphore *sem, long timeout)
{
unsigned long flags;
int result = 0;
raw_spin_lock_irqsave(&sem->lock, flags);
if (likely(sem->count > 0))
sem->count--;
else
result = __down_timeout(sem, timeout);
raw_spin_unlock_irqrestore(&sem->lock, flags);
return result;
}
可以看到down_timeout 和down_killable和down_interruptible 以及down 函数在sem->count 大于零的情况下处理的过程一直,都是在spinlock 的保护下
对sem->count减一,不同点在于对sem->count小于零的处理情况有所不同.