当前位置: 首页 > 工具软件 > Count_Down > 使用案例 >

内核同步机制API之down_xx

江敏学
2023-12-01
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小于零的处理情况有所不同.

 类似资料: