[PATCH] sigtimedwait with zero timeout should not block

From: Henrik Nordstrom (hno@actionbase.se)
Date: Fri Sep 22 2000 - 11:09:50 EST


As I mentioned earlier sigtimedwait with a zero timeout (0,0) should not
block, but it currently does for 10msec (one jiffie). This is a
performance problem for applications using polled signal queues. SUSV2
says specifically for this case "returns immediately with an error".

Attached is a new version of my patch. The previous version messed up
the signal mask if the signal queue was empty and a zero timeout was
selected.

It is still waiting one more jiffie than what is indicated by the
timeout value if other than zero, caused by the following code fragment:

                        timeout = (timespec_to_jiffies(&ts)
                                   + (ts.tv_sec || ts.tv_nsec));

Does anyone have any clue on why this +1 is there? I think this should
also go away to only read

                        timeout = timespec_to_jiffies(&ts);

--
Henrik Nordstrom

--- linux-2.4.0-test8/kernel/signal.c Fri Sep 22 11:11:05 2000 +++ linux-2.4.0-test8-reiserfs-3.6.15-raw-20000915-hno/kernel/signal.c Fri Sep 22 11:08:29 2000 @@ -939,25 +939,28 @@ spin_lock_irq(&current->sigmask_lock); sig = dequeue_signal(&these, &info); if (!sig) { - /* None ready -- temporarily unblock those we're interested - in so that we'll be awakened when they arrive. */ - sigset_t oldblocked = current->blocked; - sigandsets(&current->blocked, &current->blocked, &these); - recalc_sigpending(current); - spin_unlock_irq(&current->sigmask_lock); - timeout = MAX_SCHEDULE_TIMEOUT; if (uts) timeout = (timespec_to_jiffies(&ts) + (ts.tv_sec || ts.tv_nsec)); - current->state = TASK_INTERRUPTIBLE; - timeout = schedule_timeout(timeout); + if (timeout) { + /* None ready -- temporarily unblock those we're + * interested while we are sleeping in so that we'll + * be awakened when they arrive. */ + sigset_t oldblocked = current->blocked; + sigandsets(&current->blocked, &current->blocked, &these); + recalc_sigpending(current); + spin_unlock_irq(&current->sigmask_lock); + + current->state = TASK_INTERRUPTIBLE; + timeout = schedule_timeout(timeout); - spin_lock_irq(&current->sigmask_lock); - sig = dequeue_signal(&these, &info); - current->blocked = oldblocked; - recalc_sigpending(current); + spin_lock_irq(&current->sigmask_lock); + sig = dequeue_signal(&these, &info); + current->blocked = oldblocked; + recalc_sigpending(current); + } } spin_unlock_irq(&current->sigmask_lock);

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Sep 23 2000 - 21:00:27 EST