//获取信号量,成功后sem的计数器减1;不成功后进程将进入睡眠状态而一直等待下去
//注意区分down_interruptible(),down_killable()
//由于会使进程进入睡眠状态(不响应任何信号量,阻塞),所以不建议使用
void down(struct semaphore *sem)
{
unsigned long flags;
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;
}
//获取信号量,失败进入睡眠,但可被别的信号中断
//当有另外的内核控制路径给这个因为竞争不到信号量而睡眠的进程发送一个【致命信号】时,
//它就会立即返回而放弃继续竞争信号量
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;
}
//获取信号量,等待 timeout 时间,超时则返回
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;
}
//原子地获取信号量,成功与否都会立即返回
int down_trylock(struct semaphore *sem)
{
unsigned long flags;
int count;
raw_spin_lock_irqsave(&sem->lock, flags);
count = sem->count - 1;
if (likely(count >= 0))
sem->count = count;
raw_spin_unlock_irqrestore(&sem->lock, flags);
return (count < 0);
}
//读写信号量
struct rw_semaphore {
long count;
struct list_head wait_list; //等待队列
raw_spinlock_t wait_lock; //自旋锁
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
struct optimistic_spin_queue osq;
struct task_struct *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
};
//初始化信号量,将count设置为 val
struct semaphore {
raw_spinlock_t lock; //自旋锁
unsigned int count; //计数器
struct list_head wait_list; //等待队列
};
static inline void sema_init(struct semaphore *sem, int val)
{
static struct lock_class_key __key;
*sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0);
}
//释放信号量,sem->count加1
void up(struct semaphore *sem)
{
unsigned long flags;
raw_spin_lock_irqsave(&sem->lock, flags);
if (likely(list_empty(&sem->wait_list)))
sem->count++;
else
__up(sem);
raw_spin_unlock_irqrestore(&sem->lock, flags);
}
//注意区分down_interruptible(),down_killable()
//由于会使进程进入睡眠状态(不响应任何信号量,阻塞),所以不建议使用
void down(struct semaphore *sem)
{
unsigned long flags;
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;
}
//获取信号量,失败进入睡眠,但可被别的信号中断
//当有另外的内核控制路径给这个因为竞争不到信号量而睡眠的进程发送一个【致命信号】时,
//它就会立即返回而放弃继续竞争信号量
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;
}
//获取信号量,等待 timeout 时间,超时则返回
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;
}
//原子地获取信号量,成功与否都会立即返回
int down_trylock(struct semaphore *sem)
{
unsigned long flags;
int count;
raw_spin_lock_irqsave(&sem->lock, flags);
count = sem->count - 1;
if (likely(count >= 0))
sem->count = count;
raw_spin_unlock_irqrestore(&sem->lock, flags);
return (count < 0);
}
//读写信号量
struct rw_semaphore {
long count;
struct list_head wait_list; //等待队列
raw_spinlock_t wait_lock; //自旋锁
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
struct optimistic_spin_queue osq;
struct task_struct *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
};
//初始化信号量,将count设置为 val
struct semaphore {
raw_spinlock_t lock; //自旋锁
unsigned int count; //计数器
struct list_head wait_list; //等待队列
};
static inline void sema_init(struct semaphore *sem, int val)
{
static struct lock_class_key __key;
*sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0);
}
//释放信号量,sem->count加1
void up(struct semaphore *sem)
{
unsigned long flags;
raw_spin_lock_irqsave(&sem->lock, flags);
if (likely(list_empty(&sem->wait_list)))
sem->count++;
else
__up(sem);
raw_spin_unlock_irqrestore(&sem->lock, flags);
}