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);
 

Reply via email to