*/
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
* acquired the semaphore and 1 if the semaphore was contended. This
static noinline void __down(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);
void down(struct semaphore *sem)
}
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
* @sem: the semaphore to be acquired
for (;;) {
if (state == TASK_INTERRUPTIBLE && signal_pending(task))
goto interrupted;
+ if (state == TASK_KILLABLE && fatal_signal_pending(task))
+ goto interrupted;
__set_task_state(task, state);
spin_unlock_irq(&sem->lock);
schedule();
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)
{
if (unlikely(list_empty(&sem->wait_list)))