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(¤t->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(¤t->blocked, ¤t->blocked, &these); - recalc_sigpending(current); - spin_unlock_irq(¤t->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(¤t->blocked, ¤t->blocked, &these); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + current->state = TASK_INTERRUPTIBLE; + timeout = schedule_timeout(timeout); - spin_lock_irq(¤t->sigmask_lock); - sig = dequeue_signal(&these, &info); - current->blocked = oldblocked; - recalc_sigpending(current); + spin_lock_irq(¤t->sigmask_lock); + sig = dequeue_signal(&these, &info); + current->blocked = oldblocked; + recalc_sigpending(current); + } } spin_unlock_irq(¤t->sigmask_lock);