Hi.
While playing with signal queues it was discovered that sigtimedwait
with a zero timeout apparently does block somewhat even if it should
not.
Why:
It forces a schedule()
Also the actual delay seems to be at least 10msec more than requested,
but I guess that is an effect of the schedule()?
Attached is a small patch to optimize this case. (the .patchw version is
with -w to more clearly indicate the minimal changes made)
Some timings to prove the point: (Intel)
Linux-2.4.0-test7 without the patch:
timeout = 0 nsec: blocks for 10msec
timeout = 10 nsec: blocks for 20msec
Linux-2.4.0-test8 with the patch:
timeout = 0 nsec: does not block. ~0.1200 msec on my laptop.
timeout = 10 nsec: blocks for 20msec
Due to laziness I have not timed 2.4.0-test8 without the patch.
-- Henrik Nordstrom
--- linux-2.4.0-test7-reiserfs-3.6.14-raw-hno/kernel/signal.c.orig Sat Sep 16 11:47:04 2000 +++ linux-2.4.0-test7-reiserfs-3.6.14-raw-hno/kernel/signal.c Sat Sep 16 11:52:18 2000 @@ -848,15 +848,18 @@ timeout = (timespec_to_jiffies(&ts) + (ts.tv_sec || ts.tv_nsec)); - current->state = TASK_INTERRUPTIBLE; - timeout = schedule_timeout(timeout); + if (timeout) { + 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_unlock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sigmask_lock); + sig = dequeue_signal(&these, &info); + current->blocked = oldblocked; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + } + } else + spin_unlock_irq(¤t->sigmask_lock); if (sig) { ret = sig;
--- linux-2.4.0-test7-reiserfs-3.6.14-raw-hno/kernel/signal.c.orig Sat Sep 16 11:47:04 2000 +++ linux-2.4.0-test7-reiserfs-3.6.14-raw-hno/kernel/signal.c Sat Sep 16 11:52:18 2000 @@ -848,6 +848,7 @@ timeout = (timespec_to_jiffies(&ts) + (ts.tv_sec || ts.tv_nsec)); + if (timeout) { current->state = TASK_INTERRUPTIBLE; timeout = schedule_timeout(timeout); @@ -855,7 +856,9 @@ sig = dequeue_signal(&these, &info); current->blocked = oldblocked; recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); } + } else spin_unlock_irq(¤t->sigmask_lock); if (sig) {
- 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:24 EST