提交 f06d9686 编写于 作者: M Matthew Wilcox 提交者: Matthew Wilcox

Introduce down_killable()

down_killable() is the functional counterpart of mutex_lock_killable.
Signed-off-by: NMatthew Wilcox <willy@linux.intel.com>
上级 64ac24e7
...@@ -61,6 +61,12 @@ extern void down(struct semaphore *sem); ...@@ -61,6 +61,12 @@ extern void down(struct semaphore *sem);
*/ */
extern int __must_check down_interruptible(struct semaphore *sem); extern int __must_check down_interruptible(struct semaphore *sem);
/*
* As down_interruptible(), except the sleep may only be interrupted by
* signals which are fatal to this process.
*/
extern int __must_check down_killable(struct semaphore *sem);
/* /*
* As down(), except this function will not sleep. It will return 0 if it * As down(), except this function will not sleep. It will return 0 if it
* acquired the semaphore and 1 if the semaphore was contended. This * acquired the semaphore and 1 if the semaphore was contended. This
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
static noinline void __down(struct semaphore *sem); static noinline void __down(struct semaphore *sem);
static noinline int __down_interruptible(struct semaphore *sem); static noinline int __down_interruptible(struct semaphore *sem);
static noinline int __down_killable(struct semaphore *sem);
static noinline void __up(struct semaphore *sem); static noinline void __up(struct semaphore *sem);
void down(struct semaphore *sem) void down(struct semaphore *sem)
...@@ -61,6 +62,20 @@ int down_interruptible(struct semaphore *sem) ...@@ -61,6 +62,20 @@ int down_interruptible(struct semaphore *sem)
} }
EXPORT_SYMBOL(down_interruptible); EXPORT_SYMBOL(down_interruptible);
int down_killable(struct semaphore *sem)
{
unsigned long flags;
int result = 0;
spin_lock_irqsave(&sem->lock, flags);
if (unlikely(sem->count-- <= 0))
result = __down_killable(sem);
spin_unlock_irqrestore(&sem->lock, flags);
return result;
}
EXPORT_SYMBOL(down_killable);
/** /**
* down_trylock - try to acquire the semaphore, without waiting * down_trylock - try to acquire the semaphore, without waiting
* @sem: the semaphore to be acquired * @sem: the semaphore to be acquired
...@@ -143,6 +158,8 @@ static inline int __sched __down_common(struct semaphore *sem, long state) ...@@ -143,6 +158,8 @@ static inline int __sched __down_common(struct semaphore *sem, long state)
for (;;) { for (;;) {
if (state == TASK_INTERRUPTIBLE && signal_pending(task)) if (state == TASK_INTERRUPTIBLE && signal_pending(task))
goto interrupted; goto interrupted;
if (state == TASK_KILLABLE && fatal_signal_pending(task))
goto interrupted;
__set_task_state(task, state); __set_task_state(task, state);
spin_unlock_irq(&sem->lock); spin_unlock_irq(&sem->lock);
schedule(); schedule();
...@@ -178,6 +195,11 @@ static noinline int __sched __down_interruptible(struct semaphore *sem) ...@@ -178,6 +195,11 @@ static noinline int __sched __down_interruptible(struct semaphore *sem)
return __down_common(sem, TASK_INTERRUPTIBLE); return __down_common(sem, TASK_INTERRUPTIBLE);
} }
static noinline int __sched __down_killable(struct semaphore *sem)
{
return __down_common(sem, TASK_KILLABLE);
}
static noinline void __sched __up(struct semaphore *sem) static noinline void __sched __up(struct semaphore *sem)
{ {
if (unlikely(list_empty(&sem->wait_list))) if (unlikely(list_empty(&sem->wait_list)))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册