kernels/linux-2.4.0/include/asm-s390/semaphore-helper.h
/*
 * waking_non_zero_interruptible:
 *	1	got the lock
 *	0	go to sleep
 *	-EINTR	interrupted
 *
 * If we give up we must undo our count-decrease we previously did in down().
 * Subtle: up() can continue to happens and increase the semaphore count
 * even during our critical section protected by the spinlock. So
 * we must remeber to undo the sem->waking that will be run from
 * wake_one_more() some time soon, if the semaphore count become > 0.
 */
1       got the lock
0       go to sleep
-EINTR  interrupted

If we give up we must undo our count-decrease we previously did in down().
Subtle: up() can continue to happens and increase the semaphore count
even during our critical section protected by the spinlock. So
we must remeber to undo the sem->waking that will be run from
wake_one_more() some time soon, if the semaphore count become > 0.
1 got the lock 0 go to sleep - EINTR interrupted If we give up we must undo our count - decrease we previously did in down () . Subtle : up () can continue to happens and increase the semaphore count even during our critical section protected by the spinlock . So we must remeber to undo the sem - > waking that will be run from wake_one_more () some time soon if the semaphore count become > 0 .
static inline int waking_non_zero_interruptible(struct semaphore *sem,
						struct task_struct *tsk)
{
	unsigned long flags;
	int ret = 0;
	spin_lock_irqsave(&semaphore_wake_lock, flags);
	if (sem->waking > 0) {
		sem->waking--;
		ret = 1;
	} else if (signal_pending(tsk)) {
               if (atomic_inc_and_test_greater_zero(&sem->count))
                       sem->waking--;
		ret = -EINTR;
	}
	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
	return ret;
}
static inline int waking_non_zero_interruptible ( struct semaphore * sem , struct task_struct * tsk ) { unsigned long flags ; int ret = 0 ; spin_lock_irqsave ( & semaphore_wake_lock , flags ) ; if ( sem -> waking > 0 ) { sem -> waking -- ; ret = 1 ; } else if ( signal_pending ( tsk ) ) { if ( atomic_inc_and_test_greater_zero ( & sem -> count ) ) sem -> waking -- ; ret = - EINTR ; } spin_unlock_irqrestore ( & semaphore_wake_lock , flags ) ; return ret ; }
waking_non_zero_interruptible:
      1       got the lock
      0       go to sleep
      -EINTR  interrupted
waking_non_zero_interruptible : 1 got the lock 0 go to sleep - EINTR interrupted