一些内核同步API (2)

//获取信号量,成功后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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值